Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dracut fixes for a fragmented essential hierarchy, mostly #11898

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contrib/dracut/02zfsexpandknowledge/module-setup.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ if [[ $hostonly ]]; then
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"
dinfo "zfsexpandknowledge: block devices backing ZFS dataset $mp: ${blockdevs//$'\n'/ }"
for dev in $blockdevs
do
array_contains "$dev" "${host_devs[@]}" || host_devs+=("$dev")
Expand All @@ -114,7 +114,7 @@ if [[ $hostonly ]]; then
_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"
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
Expand Down
78 changes: 63 additions & 15 deletions contrib/dracut/90zfs/zfs-generator.sh.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/sh

echo "zfs-generator: starting" >> /dev/kmsg
grep -wq debug /proc/cmdline && debug=1
[ -n "$debug" ] && echo "zfs-generator: starting" >> /dev/kmsg

GENERATOR_DIR="$1"
[ -n "$GENERATOR_DIR" ] || {
Expand All @@ -10,12 +11,13 @@ GENERATOR_DIR="$1"

[ -f /lib/dracut-lib.sh ] && dracutlib=/lib/dracut-lib.sh
[ -f /usr/lib/dracut/modules.d/99base/dracut-lib.sh ] && dracutlib=/usr/lib/dracut/modules.d/99base/dracut-lib.sh

command -v getarg >/dev/null 2>&1 || {
echo "zfs-generator: loading Dracut library from $dracutlib" >> /dev/kmsg
[ -n "$debug" ] && echo "zfs-generator: loading Dracut library from $dracutlib" >> /dev/kmsg
. "$dracutlib"
}

. /lib/dracut-zfs-lib.sh

[ -z "$root" ] && root=$(getarg root=)
[ -z "$rootfstype" ] && rootfstype=$(getarg rootfstype=)
[ -z "$rootflags" ] && rootflags=$(getarg rootflags=)
Expand All @@ -27,44 +29,90 @@ command -v getarg >/dev/null 2>&1 || {
[ "$rootfstype" != "zfs" ] &&
exit 0

rootfstype=zfs
case ",${rootflags}," in
*,zfsutil,*) ;;
,,) rootflags=zfsutil ;;
*) rootflags="zfsutil,${rootflags}" ;;
esac

echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf >> /dev/kmsg
if [ "${root}" != "zfs:AUTO" ]; then
root="${root##zfs:}"
root="${root##ZFS=}"
fi

[ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR"
[ -d "$GENERATOR_DIR"/sysroot.mount.d ] || mkdir "$GENERATOR_DIR"/sysroot.mount.d
[ -n "$debug" ] && echo "zfs-generator: writing extension for sysroot.mount to $GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf" >> /dev/kmsg


mkdir -p "$GENERATOR_DIR"/sysroot.mount.d "$GENERATOR_DIR"/initrd-root-fs.target.requires "$GENERATOR_DIR"/dracut-pre-mount.service.d
{
echo "[Unit]"
echo "Before=initrd-root-fs.target"
echo "After=zfs-import.target"
echo
echo "[Mount]"
if [ "${root}" = "zfs:AUTO" ] ; then
if [ "${root}" = "zfs:AUTO" ]; then
echo "PassEnvironment=BOOTFS"
echo 'What=${BOOTFS}'
else
root="${root##zfs:}"
root="${root##ZFS=}"
echo "What=${root}"
fi
echo "Type=${rootfstype}"
echo "Type=zfs"
echo "Options=${rootflags}"
} > "$GENERATOR_DIR"/sysroot.mount.d/zfs-enhancement.conf
ln -fs ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount

[ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires
ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount

if [ "${root}" = "zfs:AUTO" ]; then
{
echo "[Unit]"
echo "Before=initrd-root-fs.target"
echo "After=sysroot.mount"
echo "DefaultDependencies=no"
echo
echo "[Service]"
echo "Type=oneshot"
echo "PassEnvironment=BOOTFS"
echo "ExecStart=/bin/sh -c '" ' \
. /lib/dracut-zfs-lib.sh; \
_zfs_nonroot_necessities_cb() { \
zfs mount | grep -m1 -q "^$1 " && return 0; \
echo "Mounting $1 on /sysroot$2"; \
mount -o zfsutil -t zfs "$1" "/sysroot$2"; \
}; \
for_relevant_root_children "${BOOTFS}" _zfs_nonroot_necessities_cb;' \
"'"
} > "$GENERATOR_DIR"/zfs-nonroot-necessities.service
ln -fs ../zfs-nonroot-necessities.service "$GENERATOR_DIR"/initrd-root-fs.target.requires/zfs-nonroot-necessities.service
else
# We can solve this statically at generation time, so do!
_zfs_generator_cb() {
dset="${1}"
mpnt="${2}"
unit="sysroot$(echo "$mpnt" | sed 's;/;-;g').mount"

{
echo "[Unit]"
echo "Before=initrd-root-fs.target"
echo "After=sysroot.mount"
echo
echo "[Mount]"
echo "Where=/sysroot${mpnt}"
echo "What=${dset}"
echo "Type=zfs"
echo "Options=zfsutil"
} > "$GENERATOR_DIR/${unit}"
ln -fs ../"${unit}" "$GENERATOR_DIR"/initrd-root-fs.target.requires/"${unit}"
}

for_relevant_root_children "${root}" _zfs_generator_cb
fi

[ -d "$GENERATOR_DIR"/dracut-pre-mount.service.d ] || mkdir "$GENERATOR_DIR"/dracut-pre-mount.service.d

{
echo "[Unit]"
echo "After=zfs-import.target"
} > "$GENERATOR_DIR"/dracut-pre-mount.service.d/zfs-enhancement.conf

echo "zfs-generator: finished" >> /dev/kmsg
[ -n "$debug" ] && echo "zfs-generator: finished" >> /dev/kmsg

exit 0
49 changes: 43 additions & 6 deletions contrib/dracut/90zfs/zfs-lib.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ command -v getargbool >/dev/null || {
OLDIFS="${IFS}"
NEWLINE="
"
TAB=" "

ZPOOL_IMPORT_OPTS=""
if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then
Expand Down Expand Up @@ -58,7 +59,7 @@ find_bootfs() {
# import_pool POOL
# imports the given zfs pool if it isn't imported already.
import_pool() {
pool="${1}"
pool="${1}"

if ! zpool list -H "${pool}" > /dev/null 2>&1; then
info "ZFS: Importing pool ${pool}..."
Expand All @@ -71,26 +72,62 @@ import_pool() {
return 0
}

_mount_dataset_cb() {
mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}"
}

# mount_dataset DATASET
# mounts the given zfs dataset.
mount_dataset() {
dataset="${1}"
dataset="${1}"
mountpoint="$(zfs get -H -o value mountpoint "${dataset}")"
ret=0

# We need zfsutil for non-legacy mounts and not for legacy mounts.
if [ "${mountpoint}" = "legacy" ] ; then
mount -t zfs "${dataset}" "${NEWROOT}"
mount -t zfs "${dataset}" "${NEWROOT}" || ret=$?
else
mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}"
mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" || ret=$?

if [ "$ret" = "0" ]; then
for_relevant_root_children "${dataset}" _mount_dataset_cb || ret=$?
fi
fi

return $?
return ${ret}
}

# for_relevant_root_children DATASET EXEC
# Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup
# Used by zfs-generator.sh and friends, too!
for_relevant_root_children() {
dataset="${1}"
exec="${2}"

zfs list -t filesystem -Ho name,mountpoint,canmount -r "${dataset}" |
(
_ret=0
while IFS="${TAB}" read -r dataset mountpoint canmount; do
[ "$canmount" != "on" ] && continue

case "$mountpoint" in
/etc|/bin|/lib|/lib??|/libx32|/usr)
# If these aren't mounted we may not be able to get to the real init at all, or pollute the dataset holding the rootfs
"${exec}" "${dataset}" "${mountpoint}" || _ret=$?
;;
*)
# Up to the real init to remount everything else it might need
;;
esac
done
exit ${_ret}
)
}

# export_all OPTS
# exports all imported zfs pools.
export_all() {
opts="${@}"
opts="${@}"
ret=0

IFS="${NEWLINE}"
Expand Down
2 changes: 1 addition & 1 deletion contrib/dracut/90zfs/zfs-rollback-bootfs.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ ConditionKernelCommandLine=bootfs.rollback
# ${BOOTFS} should have been set by zfs-env-bootfs.service
Type=oneshot
ExecStartPre=/bin/sh -c 'test -n "${BOOTFS}"'
ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; /sbin/zfs rollback -Rf "${BOOTFS}@${SNAPNAME:-%v}"'
ExecStart=/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.rollback)"; @sbindir@/zfs rollback -Rf "${BOOTFS}@${SNAPNAME:-%v}"'
RemainAfterExit=yes
2 changes: 1 addition & 1 deletion contrib/dracut/90zfs/zfs-snapshot-bootfs.service.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ ConditionKernelCommandLine=bootfs.snapshot
# ${BOOTFS} should have been set by zfs-env-bootfs.service
Type=oneshot
ExecStartPre=/bin/sh -c 'test -n "${BOOTFS}"'
ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; /sbin/zfs snapshot "${BOOTFS}@${SNAPNAME:-%v}"'
ExecStart=-/bin/sh -c '. /lib/dracut-lib.sh; SNAPNAME="$(getarg bootfs.snapshot)"; @sbindir@/zfs snapshot "${BOOTFS}@${SNAPNAME:-%v}"'
RemainAfterExit=yes
11 changes: 8 additions & 3 deletions contrib/initramfs/scripts/zfs
Original file line number Diff line number Diff line change
Expand Up @@ -935,9 +935,14 @@ mountroot()

# Go through the complete list (recursively) of all filesystems below
# the real root dataset
filesystems=$("${ZFS}" list -oname -tfilesystem -H -r "${ZFS_BOOTFS}")
for fs in $filesystems $ZFS_INITRD_ADDITIONAL_DATASETS
do
filesystems="$("${ZFS}" list -oname -tfilesystem -H -r "${ZFS_BOOTFS}")"
OLD_IFS="$IFS" ; IFS="
"
for fs in $filesystems; do
IFS="$OLD_IFS" mount_fs "$fs"
done
IFS="$OLD_IFS"
for fs in $ZFS_INITRD_ADDITIONAL_DATASETS; do
mount_fs "$fs"
done

Expand Down