Skip to content

Commit

Permalink
Update Dracut module for Dracut-010 & fix race conditions that caused…
Browse files Browse the repository at this point in the history
… boot to fail on MP systems.

Add support for zfs_force flag & parsing of spl_hostid from kernel command line.
  • Loading branch information
pendor committed Jul 4, 2011
1 parent 37d7a49 commit fad1a79
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 87 deletions.
3 changes: 3 additions & 0 deletions dracut/90zfs/90-zfs.rules
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ ACTION!="add|change", GOTO="zfs_end"
ENV{ID_FS_TYPE}=="zfs", RUN+="/sbin/modprobe zfs"
ENV{ID_FS_TYPE}=="zfs_member", RUN+="/sbin/modprobe zfs"

KERNEL=="null", SYMLINK+="root"
SYMLINK=="null", SYMLINK+="root"

LABEL="zfs_end"
5 changes: 1 addition & 4 deletions dracut/90zfs/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
pkgdracutdir = $(datadir)/dracut/modules.d/90zfs
dist_pkgdracut_SCRIPTS = \
$(top_srcdir)/dracut/90zfs/90-zfs.rules \
$(top_srcdir)/dracut/90zfs/check \
$(top_srcdir)/dracut/90zfs/install \
$(top_srcdir)/dracut/90zfs/installkernel \
$(top_srcdir)/dracut/90zfs/module-setup.sh \
$(top_srcdir)/dracut/90zfs/mount-zfs.sh \
$(top_srcdir)/dracut/90zfs/zfs-genrules.sh \
$(top_srcdir)/dracut/90zfs/parse-zfs.sh

all:
Expand Down
5 changes: 1 addition & 4 deletions dracut/90zfs/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,8 @@ top_srcdir = @top_srcdir@
pkgdracutdir = $(datadir)/dracut/modules.d/90zfs
dist_pkgdracut_SCRIPTS = \
$(top_srcdir)/dracut/90zfs/90-zfs.rules \
$(top_srcdir)/dracut/90zfs/check \
$(top_srcdir)/dracut/90zfs/install \
$(top_srcdir)/dracut/90zfs/installkernel \
$(top_srcdir)/dracut/90zfs/module-setup.sh \
$(top_srcdir)/dracut/90zfs/mount-zfs.sh \
$(top_srcdir)/dracut/90zfs/zfs-genrules.sh \
$(top_srcdir)/dracut/90zfs/parse-zfs.sh

all: all-am
Expand Down
10 changes: 0 additions & 10 deletions dracut/90zfs/check

This file was deleted.

17 changes: 0 additions & 17 deletions dracut/90zfs/install

This file was deleted.

10 changes: 0 additions & 10 deletions dracut/90zfs/installkernel

This file was deleted.

46 changes: 46 additions & 0 deletions dracut/90zfs/module-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/sh

check() {
# We depend on udev-rules being loaded
[ "$1" = "-d" ] && return 0

# Verify the zfs tool chain
which zpool >/dev/null 2>&1 || return 1
which zfs >/dev/null 2>&1 || return 1

return 0
}

depends() {
echo udev-rules
return 0
}

installkernel() {
instmods zfs
instmods zcommon
instmods znvpair
instmods zavl
instmods zunicode
instmods spl
instmods zlib_deflate
instmods zlib_inflate
}

install() {
inst_rules "$moddir/90-zfs.rules"
inst_rules /etc/udev/rules.d/60-zpool.rules
inst_rules /etc/udev/rules.d/60-zvol.rules
inst /etc/zfs/zdev.conf
inst /etc/zfs/zpool.cache
inst /etc/hostid
dracut_install zfs
dracut_install zpool
dracut_install zpool_layout
dracut_install zpool_id
dracut_install zvol_id
dracut_install mount.zfs
dracut_install hostid
inst_hook cmdline 95 "$moddir/parse-zfs.sh"
inst_hook mount 98 "$moddir/mount-zfs.sh"
}
69 changes: 59 additions & 10 deletions dracut/90zfs/mount-zfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,64 @@

. /lib/dracut-lib.sh

if [ "$rootfs" = "zfs" ]; then
zfsrootfs=`echo "$root" | sed 's|^zfs:||'`
zfspool=`echo "$zfsrootfs" | sed 's|/.*||g'`
zpool import -N "$zfspool"
mount -o zfsutil -t "$rootfs" "$zfsrootfs" "$NEWROOT"
if [ "$?" = "0" ]
then
ROOTFS_MOUNTED=yes
ZPOOL_FORCE=""
if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then
warn "ZFS: Will force-import pools if necessary."
ZPOOL_FORCE="-f"
fi

case "$root" in
zfs:*)
# We have ZFS modules loaded, so we're able to import pools now.
if [ "$root" = "zfs:AUTO" ] ; then
# Need to parse bootfs attribute
info "ZFS: Attempting to detect root from imported ZFS pools."

# Might be imported by the kernel module, so try searching before we import anything.
zfsbootfs=`zpool list -H -o bootfs | sed 'q'`
if [ "$zfsbootfs" = "" ] ; then
# Not there, so we need to import everything.
info "ZFS: Attempting to import additional pools."
zpool import -N -a ${ZPOOL_FORCE}
zfsbootfs=`zpool list -H -o bootfs | sed 'q'`
if [ "$zfsbootfs" = "" ] ; then
rootok=0
pool=""

warn "ZFS: No bootfs attribute found in importable pools."

# Re-export everything since we're not prepared to take responsibility for them
zpool list -H | while read fs rest ; do
zpool export "$fs"
done

return 1
fi
fi
info "ZFS: Using ${zfsbootfs} as root."
else
mount -t "$rootfs" "$zfsrootfs" "$NEWROOT" && ROOTFS_MOUNTED=yes
# Should have an explicit pool set, so just import it and we're done.
zfsbootfs="${root#zfs:}"
pool="${zfsbootfs%%/*}"
if ! zpool list -H $pool > /dev/null ; then
# pool wasn't imported automatically by the kernel module, so try it manually.
info "ZFS: Importing pool ${pool}..."
if ! zpool import -N ${ZPOOL_FORCE} $pool ; then
warn "ZFS: Unable to import pool ${pool}."
rootok=0

return 1
fi
fi
fi
fi

# Above should have left our rpool imported and pool/dataset in $root.
# We need zfsutil for non-legacy mounts and not for legacy mounts.
mountpoint=`zfs get -H -o value mountpoint $zfsbootfs`
if [ "$mountpoint" = "legacy" ] ; then
mount -t zfs "$zfsbootfs" "$NEWROOT" && ROOTFS_MOUNTED=yes
else
mount -o zfsutil -t zfs "$zfsbootfs" "$NEWROOT" && ROOTFS_MOUNTED=yes
fi
;;
esac
64 changes: 44 additions & 20 deletions dracut/90zfs/parse-zfs.sh
Original file line number Diff line number Diff line change
@@ -1,23 +1,47 @@
#!/bin/sh

. /lib/dracut-lib.sh

# Let the command line override our host id.
spl_hostid=`getarg spl_hostid=`
if [ "${spl_hostid}" != "" ] ; then
info "ZFS: Using hostid from command line: ${spl_hostid}"
echo "${spl_hostid}" > /etc/hostid
elif [ -f /etc/hostid ] ; then
info "ZFS: Using hostid from /etc/hostid: `cat /etc/hostid`"
else
warn "ZFS: No hostid found on kernel command line or /etc/hostid. ZFS pools may not import correctly."
fi

case "$root" in
zfs:FILESYSTEM=*|FILESYSTEM=*)
root="${root#zfs:}"
root="zfs:${root#FILESYSTEM=}"
rootfs="zfs"
rootok=1 ;;
zfs:ZFS=*|ZFS=*)
root="${root#zfs:}"
root="zfs:${root#ZFS=}"
rootfs="zfs"
rootok=1 ;;
""|zfs|zfs:)
# We'll take root unset, root=zfs, or root=zfs:
# No root set, so we want to read the bootfs attribute. We can't do that until udev settles,
# so we'll set dummy values and hope for the best later on.
root="zfs:AUTO"
rootok=1

info "ZFS: Enabling autodetection of bootfs after udev settles."
;;

ZFS\=*|zfs:*|zfs:FILESYSTEM\=*|FILESYSTEM\=*)
# root is explicit ZFS root. Parse it now.
# We can handle a root=... param in any of the following formats:
# root=ZFS=rpool/ROOT
# root=zfs:rpool/ROOT
# root=zfs:FILESYSTEM=rpool/ROOT
# root=FILESYSTEM=rpool/ROOT

# Strip down to just the pool/fs
root="${root#zfs:}"
root="${root#FILESYSTEM=}"
root="zfs:${root#ZFS=}"
rootok=1

info "ZFS: Set ${root} as bootfs."
;;
esac

if [ "$rootok" != "1" ] ; then
zpool import -aN
zfsbootfs=`zpool list -H -o bootfs | grep -v ^-$ -m 1`
if [ -n "$zfsbootfs" ] ; then
root="zfs:$zfsbootfs"
rootfs="zfs"
rootok=1
fi
zpool list -H | while read fs rest ; do zpool export "$fs" ; done
fi
# Make sure Dracut is happy that we have a root and will wait for ZFS modules to settle before mounting.
ln -s /dev/null /dev/root 2>/dev/null
echo '[ -e /dev/zfs ]' > $hookdir/initqueue/finished/zfs.sh
12 changes: 0 additions & 12 deletions dracut/90zfs/zfs-genrules.sh

This file was deleted.

0 comments on commit fad1a79

Please sign in to comment.