fix booting via dracut generated initramfs
Dracut and Systemd updated how they integrate with each other, because of this our current integrations stopped working (around the time 4.1.13 came out). This patch addresses that issue and gets us booting again. Thanks to @Rudd-O for doing the work to get dracut working again and letting me submit this on his behalf. Signed-off-by: Manuel Amador (Rudd-O) <rudd-o@rudd-o.com> Signed-off-by: Matthew Thode <mthode@mthode.org> Closes #3605 Closes #4478
This commit is contained in:
parent
232604b58e
commit
a5a370227e
|
@ -114,6 +114,7 @@ AC_CONFIG_FILES([
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
contrib/bash_completion.d/Makefile
|
contrib/bash_completion.d/Makefile
|
||||||
contrib/dracut/Makefile
|
contrib/dracut/Makefile
|
||||||
|
contrib/dracut/02zfsexpandknowledge/Makefile
|
||||||
contrib/dracut/90zfs/Makefile
|
contrib/dracut/90zfs/Makefile
|
||||||
contrib/initramfs/Makefile
|
contrib/initramfs/Makefile
|
||||||
module/Makefile
|
module/Makefile
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
pkgdracutdir = $(dracutdir)/modules.d/02zfsexpandknowledge
|
||||||
|
pkgdracut_SCRIPTS = \
|
||||||
|
module-setup.sh
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
$(top_srcdir)/contrib/dracut/02zfsexpandknowledge/module-setup.sh.in
|
||||||
|
|
||||||
|
$(pkgdracut_SCRIPTS):
|
||||||
|
-$(SED) -e 's,@bindir\@,$(bindir),g' \
|
||||||
|
-e 's,@sbindir\@,$(sbindir),g' \
|
||||||
|
-e 's,@datadir\@,$(datadir),g' \
|
||||||
|
-e 's,@dracutdir\@,$(dracutdir),g' \
|
||||||
|
-e 's,@udevdir\@,$(udevdir),g' \
|
||||||
|
-e 's,@udevruledir\@,$(udevruledir),g' \
|
||||||
|
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
||||||
|
"$(top_srcdir)/contrib/dracut/02zfsexpandknowledge/$@.in" >'$@'
|
||||||
|
|
||||||
|
clean-local::
|
||||||
|
-$(RM) $(pkgdracut_SCRIPTS)
|
||||||
|
|
||||||
|
distclean-local::
|
||||||
|
-$(RM) $(pkgdracut_SCRIPTS)
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
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
|
||||||
|
poolconfigtemp=`mktemp`
|
||||||
|
@sbindir@/zpool list -v -H "$1" > "$poolconfigtemp" 2>&1
|
||||||
|
if [ "$?" != "0" ] ; then
|
||||||
|
poolconfigoutput=$(cat "$poolconfigtemp")
|
||||||
|
dinfo "zfsexpandknowledge: pool $1 cannot be listed: $poolconfigoutput"
|
||||||
|
else
|
||||||
|
while read pooldev ; do
|
||||||
|
for prefix in /dev/disk/* /dev/mapper ; do
|
||||||
|
if [ -e "$prefix"/"$pooldev" ] ; then
|
||||||
|
dinfo "zfsexpandknowledge: pool $1 has device $prefix/$pooldev"
|
||||||
|
echo `readlink -f "$prefix"/"$pooldev"`
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done < <(cat "$poolconfigtemp" | awk -F '\t' 'NR>1 { print $2 }')
|
||||||
|
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 _slavedev
|
||||||
|
local _slavedevname
|
||||||
|
local _slavedevtype
|
||||||
|
local _slavemajmin
|
||||||
|
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"
|
||||||
|
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 _slavedev in /sys/dev/block/$majmin/slaves/*; do
|
||||||
|
[[ -f $_slavedev/dev ]] || continue
|
||||||
|
_slavedev=/dev/$(basename "$_slavedev")
|
||||||
|
_slavedevname=$(udevadm info --query=property --name="$_slavedev" | grep "^DEVNAME=" | sed 's|^DEVNAME=||')
|
||||||
|
_slavedevtype=$(get_devtype "$_slavedevname")
|
||||||
|
_slavemajmin=$(get_maj_min "$_slavedevname")
|
||||||
|
dinfo "zfsexpandknowledge: slave block device backing ZFS dataset $mp: $_slavedevname"
|
||||||
|
array_contains "$_slavedevname" "${host_devs[@]}" || host_devs+=("$_slavedevname")
|
||||||
|
host_fs_types["$_slavedevname"]="$_slavedevtype"
|
||||||
|
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
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ pkgdracut_SCRIPTS = \
|
||||||
module-setup.sh \
|
module-setup.sh \
|
||||||
mount-zfs.sh \
|
mount-zfs.sh \
|
||||||
parse-zfs.sh \
|
parse-zfs.sh \
|
||||||
|
zfs-generator.sh \
|
||||||
zfs-lib.sh
|
zfs-lib.sh
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
@ -11,6 +12,7 @@ EXTRA_DIST = \
|
||||||
$(top_srcdir)/contrib/dracut/90zfs/module-setup.sh.in \
|
$(top_srcdir)/contrib/dracut/90zfs/module-setup.sh.in \
|
||||||
$(top_srcdir)/contrib/dracut/90zfs/mount-zfs.sh.in \
|
$(top_srcdir)/contrib/dracut/90zfs/mount-zfs.sh.in \
|
||||||
$(top_srcdir)/contrib/dracut/90zfs/parse-zfs.sh.in \
|
$(top_srcdir)/contrib/dracut/90zfs/parse-zfs.sh.in \
|
||||||
|
$(top_srcdir)/contrib/dracut/90zfs/zfs-generator.sh.in \
|
||||||
$(top_srcdir)/contrib/dracut/90zfs/zfs-lib.sh.in
|
$(top_srcdir)/contrib/dracut/90zfs/zfs-lib.sh.in
|
||||||
|
|
||||||
$(pkgdracut_SCRIPTS):
|
$(pkgdracut_SCRIPTS):
|
||||||
|
@ -19,6 +21,7 @@ $(pkgdracut_SCRIPTS):
|
||||||
-e 's,@udevdir\@,$(udevdir),g' \
|
-e 's,@udevdir\@,$(udevdir),g' \
|
||||||
-e 's,@udevruledir\@,$(udevruledir),g' \
|
-e 's,@udevruledir\@,$(udevruledir),g' \
|
||||||
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
-e 's,@sysconfdir\@,$(sysconfdir),g' \
|
||||||
|
-e 's,@systemdunitdir\@,$(systemdunitdir),g' \
|
||||||
"$(top_srcdir)/contrib/dracut/90zfs/$@.in" >'$@'
|
"$(top_srcdir)/contrib/dracut/90zfs/$@.in" >'$@'
|
||||||
|
|
||||||
distclean-local::
|
distclean-local::
|
||||||
|
|
|
@ -40,16 +40,22 @@ install() {
|
||||||
dracut_install awk
|
dracut_install awk
|
||||||
dracut_install head
|
dracut_install head
|
||||||
inst_hook cmdline 95 "${moddir}/parse-zfs.sh"
|
inst_hook cmdline 95 "${moddir}/parse-zfs.sh"
|
||||||
inst_hook mount 98 "${moddir}/mount-zfs.sh"
|
if [ -n "$systemdutildir" ] ; then
|
||||||
|
inst_script "${moddir}/zfs-generator.sh" "$systemdutildir"/system-generators/dracut-zfs-generator
|
||||||
|
else
|
||||||
|
inst_hook mount 98 "${moddir}/mount-zfs.sh"
|
||||||
|
fi
|
||||||
inst_hook shutdown 30 "${moddir}/export-zfs.sh"
|
inst_hook shutdown 30 "${moddir}/export-zfs.sh"
|
||||||
|
|
||||||
inst_simple "${moddir}/zfs-lib.sh" "/lib/dracut-zfs-lib.sh"
|
inst_simple "${moddir}/zfs-lib.sh" "/lib/dracut-zfs-lib.sh"
|
||||||
if [ -e @sysconfdir@/zfs/zpool.cache ]; then
|
if [ -e @sysconfdir@/zfs/zpool.cache ]; then
|
||||||
inst @sysconfdir@/zfs/zpool.cache
|
inst @sysconfdir@/zfs/zpool.cache
|
||||||
|
type mark_hostonly >/dev/null 2>&1 && mark_hostonly @sysconfdir@/zfs/zpool.cache
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -e @sysconfdir@/zfs/vdev_id.conf ]; then
|
if [ -e @sysconfdir@/zfs/vdev_id.conf ]; then
|
||||||
inst @sysconfdir@/zfs/vdev_id.conf
|
inst @sysconfdir@/zfs/vdev_id.conf
|
||||||
|
type mark_hostonly >/dev/null 2>&1 && mark_hostonly @sysconfdir@/zfs/vdev_id.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Synchronize initramfs and system hostid
|
# Synchronize initramfs and system hostid
|
||||||
|
@ -58,4 +64,15 @@ install() {
|
||||||
CC=`hostid | cut -b 5,6`
|
CC=`hostid | cut -b 5,6`
|
||||||
DD=`hostid | cut -b 7,8`
|
DD=`hostid | cut -b 7,8`
|
||||||
printf "\x${DD}\x${CC}\x${BB}\x${AA}" > "${initdir}/etc/hostid"
|
printf "\x${DD}\x${CC}\x${BB}\x${AA}" > "${initdir}/etc/hostid"
|
||||||
|
|
||||||
|
if dracut_module_included "systemd"; then
|
||||||
|
mkdir -p "${initdir}/$systemdsystemunitdir/initrd.target.wants"
|
||||||
|
for _item in scan cache ; do
|
||||||
|
dracut_install @systemdunitdir@/zfs-import-$_item.service
|
||||||
|
if ! [ -L "${initdir}/$systemdsystemunitdir/initrd.target.wants"/zfs-import-$_item.service ]; then
|
||||||
|
ln -s ../zfs-import-$_item.service "${initdir}/$systemdsystemunitdir/initrd.target.wants"/zfs-import-$_item.service
|
||||||
|
type mark_hostonly >/dev/null 2>&1 && mark_hostonly @systemdunitdir@/zfs-import-$_item.service
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
GENERATOR_DIR="$1"
|
||||||
|
[ -z "$GENERATOR_DIR" ] && exit 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
|
||||||
|
|
||||||
|
type getarg >/dev/null 2>&1 || . "$dracutlib"
|
||||||
|
|
||||||
|
[ -z "$root" ] && root=$(getarg root=)
|
||||||
|
[ -z "$rootfstype" ] && rootfstype=$(getarg rootfstype=)
|
||||||
|
[ -z "$rootflags" ] && rootflags=$(getarg rootflags=)
|
||||||
|
|
||||||
|
[ "${root##zfs:}" = "${root}" -a "${root##ZFS=}" = "${root}" -a "$rootfstype" != "zfs" ] && exit 0
|
||||||
|
|
||||||
|
rootfstype=zfs
|
||||||
|
if echo "${rootflags}" | grep -q zfsutil ; then
|
||||||
|
true
|
||||||
|
else
|
||||||
|
rootflags=zfsutil
|
||||||
|
fi
|
||||||
|
|
||||||
|
root="${root##zfs:}"
|
||||||
|
root="${root##ZFS=}"
|
||||||
|
|
||||||
|
[ -d "$GENERATOR_DIR" ] || mkdir "$GENERATOR_DIR"
|
||||||
|
[ -d "$GENERATOR_DIR/sysroot.mount.d" ] || mkdir "$GENERATOR_DIR/sysroot.mount.d"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "[Unit]"
|
||||||
|
echo "After=zfs-import-scan.service"
|
||||||
|
echo "After=zfs-import-cache.service"
|
||||||
|
echo ""
|
||||||
|
echo "[Mount]"
|
||||||
|
echo "What=${root}"
|
||||||
|
echo "Type=${rootfstype}"
|
||||||
|
echo "Options=${rootflags}"
|
||||||
|
} > "$GENERATOR_DIR/sysroot.mount.d/zfs-enhancement.conf"
|
|
@ -1,3 +1,3 @@
|
||||||
SUBDIRS = 90zfs
|
SUBDIRS = 02zfsexpandknowledge 90zfs
|
||||||
|
|
||||||
EXTRA_DIST = README.dracut.markdown
|
EXTRA_DIST = README.dracut.markdown
|
||||||
|
|
Loading…
Reference in New Issue