Skip to content

Commit 07a3312

Browse files
l1kbehlendorf
authored andcommitted
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 <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #2195 Issue #2476 Issue #2498 Issue #2556 Issue #2563 Issue #2575 Issue #2600 Issue #2755 Issue #2766
1 parent 8ac9b5e commit 07a3312

6 files changed

+60
-0
lines changed

dracut/90zfs/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export-zfs.sh
12
module-setup.sh
23
mount-zfs.sh
34
parse-zfs.sh

dracut/90zfs/Makefile.am

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
pkgdracutdir = $(dracutdir)/modules.d/90zfs
22
pkgdracut_SCRIPTS = \
3+
$(top_srcdir)/dracut/90zfs/export-zfs.sh \
34
$(top_srcdir)/dracut/90zfs/module-setup.sh \
45
$(top_srcdir)/dracut/90zfs/mount-zfs.sh \
56
$(top_srcdir)/dracut/90zfs/parse-zfs.sh
67

78
EXTRA_DIST = \
9+
$(top_srcdir)/dracut/90zfs/export-zfs.sh.in \
810
$(top_srcdir)/dracut/90zfs/module-setup.sh.in \
911
$(top_srcdir)/dracut/90zfs/mount-zfs.sh.in \
1012
$(top_srcdir)/dracut/90zfs/parse-zfs.sh.in

dracut/90zfs/export-zfs.sh.in

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!/bin/sh
2+
3+
_do_zpool_export() {
4+
local ret=0
5+
local final=$1
6+
local force
7+
8+
if [ "x$final" != "x" ]; then
9+
force="-f"
10+
fi
11+
12+
info "Exporting ZFS storage pools"
13+
zpool list -H | while read fs rest ; do
14+
zpool export $force "$fs" || ret=$?
15+
done
16+
17+
if [ "x$final" != "x" ]; then
18+
info "zpool list"
19+
zpool list 2>&1 | vinfo
20+
fi
21+
22+
return $ret
23+
}
24+
25+
if command -v zpool >/dev/null; then
26+
_do_zpool_export $1
27+
else
28+
:
29+
fi

dracut/90zfs/module-setup.sh.in

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ install() {
3939
dracut_install hostid
4040
inst_hook cmdline 95 "$moddir/parse-zfs.sh"
4141
inst_hook mount 98 "$moddir/mount-zfs.sh"
42+
inst_hook shutdown 30 "$moddir/export-zfs.sh"
4243

4344
if [ -e @sysconfdir@/zfs/zpool.cache ]; then
4445
inst @sysconfdir@/zfs/zpool.cache

dracut/90zfs/mount-zfs.sh.in

+2
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,7 @@ case "$root" in
6767
else
6868
mount -o zfsutil -t zfs "$zfsbootfs" "$NEWROOT" && ROOTFS_MOUNTED=yes
6969
fi
70+
71+
need_shutdown
7072
;;
7173
esac

dracut/README.dracut.markdown

+25
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ command line and determine if ZFS is the active root filesystem.
7777
* `mount-zfs.sh`: Run later in initramfs boot process after udev has settled
7878
to mount the root dataset.
7979

80+
* `export-zfs.sh`: Run on shutdown after dracut has restored the initramfs
81+
and pivoted to it, allowing for a clean unmount and export of the ZFS root.
82+
8083
`module-setup.sh`
8184
---------------
8285

@@ -164,3 +167,25 @@ import can lead to serious data corruption and loss of pools, so this option
164167
should be used with extreme caution. Note that even with this flag set, if
165168
the required zpool was auto-imported by the kernel module, no additional
166169
`zpool import` commands are run, so nothing is forced.
170+
171+
`export-zfs.sh`
172+
-------------
173+
174+
Normally the zpool containing the root dataset cannot be exported on
175+
shutdown as it is still in use by the init process. To work around this,
176+
Dracut is able to restore the initramfs on shutdown and pivot to it.
177+
All remaining process are then running from a ramdisk, allowing for a
178+
clean unmount and export of the ZFS root. The theory of operation is
179+
described in detail in the [Dracut manual](https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html#_dracut_on_shutdown).
180+
181+
This script will try to export all remaining zpools after Dracut has
182+
pivoted to the initramfs. If an initial regular export is not successful,
183+
Dracut will call this script once more with the `final` option,
184+
in which case a forceful export is attempted.
185+
186+
Other Dracut modules include similar shutdown scripts and Dracut
187+
invokes these scripts round-robin until they succeed. In particular,
188+
the `90dm` module installs a script which tries to close and remove
189+
all device mapper targets. Thus, if there are ZVOLs containing
190+
dm-crypt volumes or if the zpool itself is backed by a dm-crypt
191+
volume, the shutdown scripts will try to untangle this.

0 commit comments

Comments
 (0)