mirror_zfs/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in
Savyasachee Jha b3ab290855
dracut: skip zfsexpandknoweldge when zfs_devs is present in dracut
PR 1711 (https://github.com/dracutdevs/dracut/pull/1711) adds a zfs_devs
function to dracut to detect the physical devices backing zfs pools. If
this function exists in the version of dracut this module is being
called from, then it does not need to run.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Savyasachee Jha <hi@savyasacheejha.com>
Closes #13121
2022-02-28 14:35:25 -08:00

129 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
get_devtype() {
local typ
typ=$(udevadm info --query=property --name="$1" | sed -n 's|^ID_FS_TYPE=||p')
if [ -z "$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 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
awk -F '\t' '/\t\/dev/ { print $2 }' "$poolconfigtemp" | \
while read -r pooldev ; do
if [ -e "$pooldev" ] ; then
resolved="$(readlink -f "$pooldev")"
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 mp
local fstype
local _
numfields="$(awk '{print NF; exit}' /proc/self/mountinfo)"
if [ "$numfields" = "10" ] ; then
fields="_ _ _ _ mp _ _ fstype dev _"
else
fields="_ _ _ _ mp _ _ _ fstype dev _"
fi
# shellcheck disable=SC2086
while read -r ${fields?} ; do
[ "$fstype" = "zfs" ] || continue
[ "$mp" = "$1" ] && get_pool_devices "${dev%%/*}"
done < /proc/self/mountinfo
}
array_contains () {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
check() {
# https://github.com/dracutdevs/dracut/pull/1711 provides a zfs_devs
# function to detect the physical devices backing zfs pools. If this
# function exists in the version of dracut this module is being called
# from, then it does not need to run.
type zfs_devs >/dev/null 2>&1 && return 1
local mp
local dev
local blockdevs
local fstype
local majmin
local _depdev
local _depdevname
local _depdevtype
# shellcheck disable=SC2154
if [ -n "$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/${_depdev##*/}"
_depdevname=$(udevadm info --query=property --name="$_depdev" | sed -n 's|^DEVNAME=||p')
_depdevtype=$(get_devtype "$_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
}