summaryrefslogtreecommitdiffstats
path: root/dracut
diff options
context:
space:
mode:
authorZachary Bedell <[email protected]>2011-07-04 13:25:31 -0400
committerBrian Behlendorf <[email protected]>2011-07-06 09:20:28 -0700
commitfde4ce992db516796df3a7d1c0e018c5f8c537f6 (patch)
tree50714e99cd11b1ad75f29adcea03d5ae512216d7 /dracut
parente93ced48475b697734ae4fbc65c4e600b9752849 (diff)
Update for Dracut-010
Update Dracut module for Dracut-010 and fix race conditions that caused boot to fail on MP systems. Add support for zfs_force flag and parsing of spl_hostid from kernel command line. Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'dracut')
-rw-r--r--dracut/90zfs/90-zfs.rules3
-rw-r--r--dracut/90zfs/Makefile.am5
-rw-r--r--dracut/90zfs/Makefile.in5
-rwxr-xr-xdracut/90zfs/check10
-rwxr-xr-xdracut/90zfs/install17
-rwxr-xr-xdracut/90zfs/installkernel10
-rwxr-xr-xdracut/90zfs/module-setup.sh46
-rwxr-xr-xdracut/90zfs/mount-zfs.sh72
-rwxr-xr-xdracut/90zfs/parse-zfs.sh66
-rwxr-xr-xdracut/90zfs/zfs-genrules.sh12
10 files changed, 159 insertions, 87 deletions
diff --git a/dracut/90zfs/90-zfs.rules b/dracut/90zfs/90-zfs.rules
index 918d726d7..52e1d6393 100644
--- a/dracut/90zfs/90-zfs.rules
+++ b/dracut/90zfs/90-zfs.rules
@@ -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"
diff --git a/dracut/90zfs/Makefile.am b/dracut/90zfs/Makefile.am
index e2e3ff8cb..605654c23 100644
--- a/dracut/90zfs/Makefile.am
+++ b/dracut/90zfs/Makefile.am
@@ -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:
diff --git a/dracut/90zfs/Makefile.in b/dracut/90zfs/Makefile.in
index 49ed26264..aa40fe5ef 100644
--- a/dracut/90zfs/Makefile.in
+++ b/dracut/90zfs/Makefile.in
@@ -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
diff --git a/dracut/90zfs/check b/dracut/90zfs/check
deleted file mode 100755
index ac4006b86..000000000
--- a/dracut/90zfs/check
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-# We depend on udev-rules being loaded
-[ "$1" = "-d" ] && exit 0
-
-# Verify the zfs tool chain
-which zpool >/dev/null 2>&1 || exit 1
-which zfs >/dev/null 2>&1 || exit 1
-
-exit 0
diff --git a/dracut/90zfs/install b/dracut/90zfs/install
deleted file mode 100755
index 5be976860..000000000
--- a/dracut/90zfs/install
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-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/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"
-inst_hook pre-udev 29 "$moddir/zfs-genrules.sh"
diff --git a/dracut/90zfs/installkernel b/dracut/90zfs/installkernel
deleted file mode 100755
index c3fa7de17..000000000
--- a/dracut/90zfs/installkernel
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-instmods zfs
-instmods zcommon
-instmods znvpair
-instmods zavl
-instmods zunicode
-instmods spl
-instmods zlib_deflate
-instmods zlib_inflate
diff --git a/dracut/90zfs/module-setup.sh b/dracut/90zfs/module-setup.sh
new file mode 100755
index 000000000..1816b38d7
--- /dev/null
+++ b/dracut/90zfs/module-setup.sh
@@ -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"
+}
diff --git a/dracut/90zfs/mount-zfs.sh b/dracut/90zfs/mount-zfs.sh
index b4a4de6ff..e067c18a0 100755
--- a/dracut/90zfs/mount-zfs.sh
+++ b/dracut/90zfs/mount-zfs.sh
@@ -2,15 +2,67 @@
. /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
diff --git a/dracut/90zfs/parse-zfs.sh b/dracut/90zfs/parse-zfs.sh
index ef3d058ac..f8974b95e 100755
--- a/dracut/90zfs/parse-zfs.sh
+++ b/dracut/90zfs/parse-zfs.sh
@@ -1,23 +1,49 @@
+#!/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
diff --git a/dracut/90zfs/zfs-genrules.sh b/dracut/90zfs/zfs-genrules.sh
deleted file mode 100755
index ffbd51ff1..000000000
--- a/dracut/90zfs/zfs-genrules.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-if [ "${root%%:*}" = "zfs" ]; then
- [ -d /dev/.udev/rules.d ] || mkdir -p /dev/.udev/rules.d
- {
- printf 'KERNEL=="%s", SYMLINK+="root"\n' null
- printf 'SYMLINK=="%s", SYMLINK+="root"\n' null
- } >> /dev/.udev/rules.d/99-zfs.rules
-
- printf '[ -e "%s" ] && { ln -s "%s" /dev/root 2>/dev/null; rm "$job"; }\n' \
- "/dev/null" "/dev/null" >> /initqueue-settled/zfssymlink.sh
-
- echo '[ -e /dev/root ]' > /initqueue-finished/zfs.sh
-fi