summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2014-10-06 13:08:33 +0200
committerBrian Behlendorf <behlendorf1@llnl.gov>2014-10-07 10:20:56 -0700
commit07a3312f170ac56cb480b0df9fdf4c83f116b59b (patch)
tree7c12a27f405327a662ed1e34903cb0e8a9fb2219
parent8ac9b5e6b5b59ad3bf7a65f9de3c8ed46ba4240e (diff)
Amend Dracut module to export ZFS root on shutdown
Make use of Dracut's ability to restore the initramfs on shutdown and pivot to it, allowing for a clean unmount and export of the ZFS root. No need to force-import on every reboot anymore. Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #2195 Issue #2476 Issue #2498 Issue #2556 Issue #2563 Issue #2575 Issue #2600 Issue #2755 Issue #2766
-rw-r--r--dracut/90zfs/.gitignore1
-rw-r--r--dracut/90zfs/Makefile.am2
-rwxr-xr-xdracut/90zfs/export-zfs.sh.in29
-rwxr-xr-xdracut/90zfs/module-setup.sh.in1
-rwxr-xr-xdracut/90zfs/mount-zfs.sh.in2
-rw-r--r--dracut/README.dracut.markdown25
6 files changed, 60 insertions, 0 deletions
diff --git a/dracut/90zfs/.gitignore b/dracut/90zfs/.gitignore
index 6f4a5ae10..72a710a0e 100644
--- a/dracut/90zfs/.gitignore
+++ b/dracut/90zfs/.gitignore
@@ -1,3 +1,4 @@
+export-zfs.sh
module-setup.sh
mount-zfs.sh
parse-zfs.sh
diff --git a/dracut/90zfs/Makefile.am b/dracut/90zfs/Makefile.am
index 759aae81d..2d1360ade 100644
--- a/dracut/90zfs/Makefile.am
+++ b/dracut/90zfs/Makefile.am
@@ -1,10 +1,12 @@
pkgdracutdir = $(dracutdir)/modules.d/90zfs
pkgdracut_SCRIPTS = \
+ $(top_srcdir)/dracut/90zfs/export-zfs.sh \
$(top_srcdir)/dracut/90zfs/module-setup.sh \
$(top_srcdir)/dracut/90zfs/mount-zfs.sh \
$(top_srcdir)/dracut/90zfs/parse-zfs.sh
EXTRA_DIST = \
+ $(top_srcdir)/dracut/90zfs/export-zfs.sh.in \
$(top_srcdir)/dracut/90zfs/module-setup.sh.in \
$(top_srcdir)/dracut/90zfs/mount-zfs.sh.in \
$(top_srcdir)/dracut/90zfs/parse-zfs.sh.in
diff --git a/dracut/90zfs/export-zfs.sh.in b/dracut/90zfs/export-zfs.sh.in
new file mode 100755
index 000000000..dd1ea8121
--- /dev/null
+++ b/dracut/90zfs/export-zfs.sh.in
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+_do_zpool_export() {
+ local ret=0
+ local final=$1
+ local force
+
+ if [ "x$final" != "x" ]; then
+ force="-f"
+ fi
+
+ info "Exporting ZFS storage pools"
+ zpool list -H | while read fs rest ; do
+ zpool export $force "$fs" || ret=$?
+ done
+
+ if [ "x$final" != "x" ]; then
+ info "zpool list"
+ zpool list 2>&1 | vinfo
+ fi
+
+ return $ret
+}
+
+if command -v zpool >/dev/null; then
+ _do_zpool_export $1
+else
+ :
+fi
diff --git a/dracut/90zfs/module-setup.sh.in b/dracut/90zfs/module-setup.sh.in
index 6eb684381..2d0b335cf 100755
--- a/dracut/90zfs/module-setup.sh.in
+++ b/dracut/90zfs/module-setup.sh.in
@@ -39,6 +39,7 @@ install() {
dracut_install hostid
inst_hook cmdline 95 "$moddir/parse-zfs.sh"
inst_hook mount 98 "$moddir/mount-zfs.sh"
+ inst_hook shutdown 30 "$moddir/export-zfs.sh"
if [ -e @sysconfdir@/zfs/zpool.cache ]; then
inst @sysconfdir@/zfs/zpool.cache
diff --git a/dracut/90zfs/mount-zfs.sh.in b/dracut/90zfs/mount-zfs.sh.in
index 23ec7e45b..ca4e46614 100755
--- a/dracut/90zfs/mount-zfs.sh.in
+++ b/dracut/90zfs/mount-zfs.sh.in
@@ -67,5 +67,7 @@ case "$root" in
else
mount -o zfsutil -t zfs "$zfsbootfs" "$NEWROOT" && ROOTFS_MOUNTED=yes
fi
+
+ need_shutdown
;;
esac
diff --git a/dracut/README.dracut.markdown b/dracut/README.dracut.markdown
index 909273a65..27e94fff9 100644
--- a/dracut/README.dracut.markdown
+++ b/dracut/README.dracut.markdown
@@ -77,6 +77,9 @@ command line and determine if ZFS is the active root filesystem.
* `mount-zfs.sh`: Run later in initramfs boot process after udev has settled
to mount the root dataset.
+* `export-zfs.sh`: Run on shutdown after dracut has restored the initramfs
+and pivoted to it, allowing for a clean unmount and export of the ZFS root.
+
`module-setup.sh`
---------------
@@ -164,3 +167,25 @@ import can lead to serious data corruption and loss of pools, so this option
should be used with extreme caution. Note that even with this flag set, if
the required zpool was auto-imported by the kernel module, no additional
`zpool import` commands are run, so nothing is forced.
+
+`export-zfs.sh`
+-------------
+
+Normally the zpool containing the root dataset cannot be exported on
+shutdown as it is still in use by the init process. To work around this,
+Dracut is able to restore the initramfs on shutdown and pivot to it.
+All remaining process are then running from a ramdisk, allowing for a
+clean unmount and export of the ZFS root. The theory of operation is
+described in detail in the [Dracut manual](https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html#_dracut_on_shutdown).
+
+This script will try to export all remaining zpools after Dracut has
+pivoted to the initramfs. If an initial regular export is not successful,
+Dracut will call this script once more with the `final` option,
+in which case a forceful export is attempted.
+
+Other Dracut modules include similar shutdown scripts and Dracut
+invokes these scripts round-robin until they succeed. In particular,
+the `90dm` module installs a script which tries to close and remove
+all device mapper targets. Thus, if there are ZVOLs containing
+dm-crypt volumes or if the zpool itself is backed by a dm-crypt
+volume, the shutdown scripts will try to untangle this.