1#!/usr/bin/env bash 2 3get_devtype() { 4 local typ 5 typ=$(udevadm info --query=property --name="$1" | grep "^ID_FS_TYPE=" | sed 's|^ID_FS_TYPE=||') 6 if [ "$typ" = "" ] ; then 7 typ=$(blkid -c /dev/null "$1" -o value -s TYPE) 8 fi 9 echo "$typ" 10} 11 12get_pool_devices() { 13 # also present in 99zfssystemd 14 local poolconfigtemp 15 local poolconfigoutput 16 local pooldev 17 local prefix 18 local resolved 19 poolconfigtemp=`mktemp` 20 @sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1 21 if [ "$?" != "0" ] ; then 22 poolconfigoutput=$(cat "$poolconfigtemp") 23 dinfo "zfsexpandknowledge: pool $1 cannot be listed: $poolconfigoutput" 24 else 25 cat "$poolconfigtemp" | awk -F '\t' '/\t\/dev/ { print $2 }' | \ 26 while read pooldev ; do 27 if [ -n "$pooldev" -a -e "$pooldev" ] ; then 28 if [ -h "$pooldev" ] ; then 29 resolved=`readlink -f "$pooldev"` 30 else 31 resolved="$pooldev" 32 fi 33 dinfo "zfsexpandknowledge: pool $1 has device $pooldev (which resolves to $resolved)" 34 echo "$resolved" 35 fi 36 done 37 fi 38 rm -f "$poolconfigtemp" 39} 40 41find_zfs_block_devices() { 42 local dev 43 local blockdev 44 local mp 45 local fstype 46 local pool 47 local key 48 local n 49 local poolconfigoutput 50 numfields=`head -1 /proc/self/mountinfo | awk '{print NF}'` 51 if [ "$numfields" == "10" ] ; then 52 fields="n n n n mp n n fstype dev n" 53 else 54 fields="n n n n mp n n n fstype dev n" 55 fi 56 while read $fields ; do 57 if [ "$fstype" != "zfs" ]; then continue ; fi 58 if [ "$mp" == "$1" ]; then 59 pool=$(echo "$dev" | cut -d / -f 1) 60 get_pool_devices "$pool" 61 fi 62 done < /proc/self/mountinfo 63} 64 65array_contains () { 66 local e 67 for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done 68 return 1 69} 70 71check() { 72 local mp 73 local dev 74 local blockdevs 75 local fstype 76 local majmin 77 local _depdev 78 local _depdevname 79 local _depdevtype 80 local _depmajmin 81 local _dev 82 83if [[ $hostonly ]]; then 84 85 for mp in \ 86 "/" \ 87 "/etc" \ 88 "/bin" \ 89 "/sbin" \ 90 "/lib" \ 91 "/lib64" \ 92 "/usr" \ 93 "/usr/bin" \ 94 "/usr/sbin" \ 95 "/usr/lib" \ 96 "/usr/lib64" \ 97 "/boot"; 98 do 99 mp=$(readlink -f "$mp") 100 mountpoint "$mp" >/dev/null 2>&1 || continue 101 blockdevs=$(find_zfs_block_devices "$mp") 102 if [ -z "$blockdevs" ] ; then continue ; fi 103 dinfo "zfsexpandknowledge: block devices backing ZFS dataset $mp: $blockdevs" 104 for dev in $blockdevs 105 do 106 array_contains "$dev" "${host_devs[@]}" || host_devs+=("$dev") 107 fstype=$(get_devtype "$dev") 108 host_fs_types["$dev"]="$fstype" 109 majmin=$(get_maj_min "$dev") 110 if [[ -d /sys/dev/block/$majmin/slaves ]] ; then 111 for _depdev in /sys/dev/block/$majmin/slaves/*; do 112 [[ -f $_depdev/dev ]] || continue 113 _depdev=/dev/$(basename "$_depdev") 114 _depdevname=$(udevadm info --query=property --name="$_depdev" | grep "^DEVNAME=" | sed 's|^DEVNAME=||') 115 _depdevtype=$(get_devtype "$_depdevname") 116 _depmajmin=$(get_maj_min "$_depdevname") 117 dinfo "zfsexpandknowledge: underlying block device backing ZFS dataset $mp: $_depdevname" 118 array_contains "$_depdevname" "${host_devs[@]}" || host_devs+=("$_depdevname") 119 host_fs_types["$_depdevname"]="$_depdevtype" 120 done 121 fi 122 done 123 done 124 for a in "${host_devs[@]}" 125 do 126 dinfo "zfsexpandknowledge: host device $a" 127 done 128 for a in "${!host_fs_types[@]}" 129 do 130 dinfo "zfsexpandknowledge: device $a of type ${host_fs_types[$a]}" 131 done 132 133fi 134 135return 1 136} 137