#!/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` if ! @sbindir@/zpool list -v -H -P "$1" > "$poolconfigtemp" 2>&1 ; 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 }