aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in
blob: f4b7b8cdcce323e6f48cc1af2f47f1f0b3e4a658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env bash

get_devtype() {
  local typ
  typ=$(udevadm info --query=property --name="$1" | grep "^ID_FS_TYPE=" | sed 's|^ID_FS_TYPE=||')
  if [ "$typ" = "" ] ; then
     typ=$(blkid -c /dev/null "$1" -o value -s TYPE)
  fi
  echo "$typ"
}

get_pool_devices() {
  # also present in 99zfssystemd
  local poolconfigtemp
  local poolconfigoutput
  local pooldev
  local prefix
  local resolved
  poolconfigtemp=`mktemp`
  @sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1
  if [ "$?" != "0" ] ; then
    poolconfigoutput=$(cat "$poolconfigtemp")
    dinfo "zfsexpandknowledge: pool $1 cannot be listed: $poolconfigoutput"
  else
    cat "$poolconfigtemp" |  awk -F '\t' '/\t\/dev/ { print $2 }' | \
    while read pooldev ; do
        if [ -n "$pooldev" -a -e "$pooldev" ] ; then
          if [ -h "$pooldev" ] ; then
              resolved=`readlink -f "$pooldev"`
          else
              resolved="$pooldev"
          fi
          dinfo "zfsexpandknowledge: pool $1 has device $pooldev (which resolves to $resolved)"
          echo "$resolved"
        fi
    done
  fi
  rm -f "$poolconfigtemp"
}

find_zfs_block_devices() {
    local dev
    local blockdev
    local mp
    local fstype
    local pool
    local key
    local n
    local poolconfigoutput
    numfields=`head -1 /proc/self/mountinfo | awk '{print NF}'`
    if [ "$numfields" == "10" ] ; then
        fields="n n n n mp n n fstype dev n"
    else
        fields="n n n n mp n n n fstype dev n"
    fi
    while read $fields ; do
       if [ "$fstype" != "zfs" ]; then continue ; fi
       if [ "$mp" == "$1" ]; then
           pool=$(echo "$dev" | cut -d / -f 1)
           get_pool_devices "$pool"
       fi
    done < /proc/self/mountinfo
}

array_contains () {
  local e
  for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
  return 1
}

check() {
    local mp
    local dev
    local blockdevs
    local fstype
    local majmin
    local _depdev
    local _depdevname
    local _depdevtype
    local _depmajmin
    local _dev

if [[ $hostonly ]]; then

    for mp in \
        "/" \
        "/etc" \
        "/bin" \
        "/sbin" \
        "/lib" \
        "/lib64" \
        "/usr" \
        "/usr/bin" \
        "/usr/sbin" \
        "/usr/lib" \
        "/usr/lib64" \
        "/boot";
    do
        mp=$(readlink -f "$mp")
        mountpoint "$mp" >/dev/null 2>&1 || continue
        blockdevs=$(find_zfs_block_devices "$mp")
        if [ -z "$blockdevs" ] ; then continue ; fi
        dinfo "zfsexpandknowledge: block devices backing ZFS dataset $mp: ${blockdevs//$'\n'/ }"
        for dev in $blockdevs
        do
            array_contains "$dev" "${host_devs[@]}" || host_devs+=("$dev")
            fstype=$(get_devtype "$dev")
            host_fs_types["$dev"]="$fstype"
            majmin=$(get_maj_min "$dev")
            if [[ -d /sys/dev/block/$majmin/slaves ]] ; then
                for _depdev in /sys/dev/block/$majmin/slaves/*; do
                    [[ -f $_depdev/dev ]] || continue
                    _depdev=/dev/$(basename "$_depdev")
                    _depdevname=$(udevadm info --query=property --name="$_depdev" | grep "^DEVNAME=" | sed 's|^DEVNAME=||')
                    _depdevtype=$(get_devtype "$_depdevname")
                    _depmajmin=$(get_maj_min "$_depdevname")
                    dinfo "zfsexpandknowledge: underlying block device backing ZFS dataset $mp: ${_depdevname//$'\n'/ }"
                    array_contains "$_depdevname" "${host_devs[@]}" || host_devs+=("$_depdevname")
                    host_fs_types["$_depdevname"]="$_depdevtype"
                done
            fi
        done
    done
    for a in "${host_devs[@]}"
        do
        dinfo "zfsexpandknowledge: host device $a"
    done
    for a in "${!host_fs_types[@]}"
        do
        dinfo "zfsexpandknowledge: device $a of type ${host_fs_types[$a]}"
    done

fi

return 1
}