dracut: use /bin/sh instead of bash as the intepreter
Despite that dracut has a hard dependency on bash,
its modules doesn't, dracut only has a hard dependency on bash for
module-setup (on a fully usable machine). Inside initramfs, dracut
allows users choose from a list of handful other shells, e.g. bash,
busybox, dash, mkfsh.
In fact, my local machine's initramfs is being built with dash,
and it's functional for a very long time.
Before 64025fa3a (Silence 'make checkbashisms', 2020-08-20), we also
allows our users to have that right, too.
Let's fix the problem 'make checkbashisms' reported and allows our users
to have that right, again.
For 'plymouth' case, let's simply run the command inside the if instead
of checking for the existence of command before running it, because the
status is also failture if plymouth is unavailable.
While we're at it, let's remove an unnecessary fork for grep in
zfs-generator.sh.in and its following complicated 'if elif fi' with
a simple 'case ... esac'.
To support this change, also exclude 90zfs from "make checkbashisms"
because the current CI infrastructure ships an old version of
"checkbashisms", which complains about "command -v", while the current
latest "checkbashisms" thinks it's fine. In the near future, we can
revert that change to "Makefile.am" when CI infrastructure is updated.
Reviewed-by: Gabriel A. Devenyi <gdevenyi@gmail.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Closes #11244
2020-11-28 19:02:08 +00:00
|
|
|
#!/bin/sh
|
2022-04-04 21:24:29 +00:00
|
|
|
# shellcheck disable=SC2034
|
2015-02-15 19:28:42 +00:00
|
|
|
|
2022-04-04 20:45:58 +00:00
|
|
|
command -v getarg >/dev/null || . /lib/dracut-lib.sh || . /usr/lib/dracut/modules.d/99base/dracut-lib.sh
|
2015-02-15 19:28:42 +00:00
|
|
|
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
TAB=" "
|
2015-02-15 19:28:42 +00:00
|
|
|
|
2022-04-04 21:24:29 +00:00
|
|
|
ZPOOL_IMPORT_OPTS=
|
|
|
|
if getargbool 0 zfs_force -y zfs.force -y zfsforce; then
|
2018-02-22 01:54:54 +00:00
|
|
|
warn "ZFS: Will force-import pools if necessary."
|
2022-04-04 21:24:29 +00:00
|
|
|
ZPOOL_IMPORT_OPTS=-f
|
2015-02-15 19:28:42 +00:00
|
|
|
fi
|
|
|
|
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
_mount_dataset_cb() {
|
|
|
|
mount -o zfsutil -t zfs "${1}" "${NEWROOT}${2}"
|
|
|
|
}
|
|
|
|
|
2015-02-15 19:28:42 +00:00
|
|
|
# mount_dataset DATASET
|
|
|
|
# mounts the given zfs dataset.
|
|
|
|
mount_dataset() {
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
dataset="${1}"
|
2018-02-22 01:54:54 +00:00
|
|
|
mountpoint="$(zfs get -H -o value mountpoint "${dataset}")"
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
ret=0
|
2015-02-15 19:28:42 +00:00
|
|
|
|
2018-02-22 01:54:54 +00:00
|
|
|
# We need zfsutil for non-legacy mounts and not for legacy mounts.
|
|
|
|
if [ "${mountpoint}" = "legacy" ] ; then
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
mount -t zfs "${dataset}" "${NEWROOT}" || ret=$?
|
2018-02-22 01:54:54 +00:00
|
|
|
else
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}" || ret=$?
|
|
|
|
|
|
|
|
if [ "$ret" = "0" ]; then
|
|
|
|
for_relevant_root_children "${dataset}" _mount_dataset_cb || ret=$?
|
|
|
|
fi
|
2018-02-22 01:54:54 +00:00
|
|
|
fi
|
2015-02-15 19:28:42 +00:00
|
|
|
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
return ${ret}
|
|
|
|
}
|
|
|
|
|
|
|
|
# for_relevant_root_children DATASET EXEC
|
|
|
|
# Runs "EXEC dataset mountpoint" for all children of DATASET that are needed for system bringup
|
contrib: dracut: fix race with root=zfs:dset when necessities required
This had always worked in my testing, but a user on hardware reported
this to happen 100%, and I reproduced it once with cold VM host caches.
dracut-zfs-generator runs as a systemd generator, i.e. at Some
Relatively Early Time; if root= is a fixed dataset, it tries to
"solve [necessities] statically at generation time".
If by that point zfs-import.target hasn't popped (because the import is
taking a non-negligible amount of time for whatever reason), it'll see
no children for the root datase, and as such generate no mounts.
This has never had any right to work. No-one caught this earlier because
it's just that much more convenient to have root=zfs:AUTO, which orders
itself properly.
To fix this, always run zfs-nonroot-necessities.service;
this additionally simplifies the implementation by:
* making BOOTFS from zfs-env-bootfs.service be the real, canonical,
root dataset name, not just "whatever the first bootfs is",
and only set it if we're ZFS-booting
* zfs-{rollback,snapshot}-bootfs.service can use this instead of
re-implementing it
* having zfs-env-bootfs.service also set BOOTFSFLAGS
* this means the sysroot.mount drop-in can be fixed text
* zfs-nonroot-necessities.service can also be constant and always
enabled, because it's conditioned on BOOTFS being set
There is no longer any code generated at run-time
(the sysroot.mount drop-in is an unavoidable gratuitous cp).
The flow of BOOTFS{,FLAGS} from zfs-env-bootfs.service to sysroot.mount
is not noted explicitly in dracut.zfs(7), because (a) at some point it's
just visual noise and (b) it's already ordered via d-p-m.s from z-i.t.
Backport-of: 3399a30ee02d0d31ba2d43d0ce0a2fd90d5c575d
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
2023-03-28 20:49:50 +00:00
|
|
|
# Used by zfs-nonroot-necessities.service and friends, too!
|
contrib/dracut: 90: mount essential datasets under root
This partly mirrors what the i-t script does (though that mounts all
children, recursively) ‒ /etc, /usr, /lib*, and /bin are all essential,
if present, to successfully invoke the real init, which will then mount
everything else it might need in the right order
The following extreme-case set-up boots w/o issues now:
/ zoot zfs rw,relatime,xattr,noacl
├─/etc zoot/etc zfs rw,relatime,xattr,noacl
├─/usr zoot/usr zfs rw,relatime,xattr,noacl
│ └─/usr/local zoot/usr/local zfs rw,relatime,xattr,noacl
├─/var zoot/var zfs rw,relatime,xattr,noacl
│ ├─/var/lib zoot/var/lib zfs rw,relatime,xattr,noacl
│ ├─/var/log zoot/var/log zfs rw,relatime,xattr,posixacl
│ ├─/var/cache zoot/var/cache zfs rw,relatime,xattr,noacl
│ └─/var/tmp zoot/var/tmp zfs rw,relatime,xattr,noacl
├─/home zoot/home zfs rw,relatime,xattr,noacl
│ └─/home/nab zoot/home/nab zfs rw,relatime,xattr,noacl
├─/boot zoot/boot zfs rw,relatime,xattr,noacl
├─/root zoot/home/root zfs rw,relatime,xattr,noacl
├─/opt zoot/opt zfs rw,relatime,xattr,noacl
└─/srv zoot/srv zfs rw,relatime,xattr,noacl
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Closes #11898
2021-04-13 20:41:10 +00:00
|
|
|
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}
|
|
|
|
)
|
2015-02-15 19:28:42 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 20:45:58 +00:00
|
|
|
# Parse root=, rootfstype=, return them decoded and normalised to zfs:AUTO for auto, plain dset for explicit
|
|
|
|
#
|
|
|
|
# True if ZFS-on-root, false if we shouldn't
|
|
|
|
#
|
|
|
|
# Supported values:
|
|
|
|
# root=
|
|
|
|
# root=zfs
|
|
|
|
# root=zfs:
|
|
|
|
# root=zfs:AUTO
|
|
|
|
#
|
|
|
|
# root=ZFS=data/set
|
|
|
|
# root=zfs:data/set
|
|
|
|
# root=zfs:ZFS=data/set (as a side-effect; allowed but undocumented)
|
|
|
|
#
|
|
|
|
# rootfstype=zfs AND root=data/set <=> root=data/set
|
|
|
|
# rootfstype=zfs AND root= <=> root=zfs:AUTO
|
|
|
|
#
|
|
|
|
# '+'es in explicit dataset decoded to ' 's.
|
|
|
|
decode_root_args() {
|
|
|
|
if [ -n "$rootfstype" ]; then
|
|
|
|
[ "$rootfstype" = zfs ]
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
root=$(getarg root=)
|
|
|
|
rootfstype=$(getarg rootfstype=)
|
|
|
|
|
|
|
|
# shellcheck disable=SC2249
|
|
|
|
case "$root" in
|
|
|
|
""|zfs|zfs:|zfs:AUTO)
|
|
|
|
root=zfs:AUTO
|
|
|
|
rootfstype=zfs
|
|
|
|
return 0
|
|
|
|
;;
|
|
|
|
|
|
|
|
ZFS=*|zfs:*)
|
|
|
|
root="${root#zfs:}"
|
|
|
|
root="${root#ZFS=}"
|
|
|
|
root=$(echo "$root" | tr '+' ' ')
|
|
|
|
rootfstype=zfs
|
|
|
|
return 0
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
if [ "$rootfstype" = "zfs" ]; then
|
|
|
|
case "$root" in
|
|
|
|
"") root=zfs:AUTO ;;
|
|
|
|
*) root=$(echo "$root" | tr '+' ' ') ;;
|
|
|
|
esac
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
return 1
|
|
|
|
}
|