]> granicus.if.org Git - zfs/commitdiff
Refactor dracut module
authorSören Tempel <soeren+git@soeren-tempel.net>
Sun, 15 Feb 2015 19:28:42 +0000 (20:28 +0100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 17 Jun 2015 23:45:18 +0000 (16:45 -0700)
Provide '/lib/dracut-zfs-lib.sh' with utility functions.

Signed-off-by: Sören Tempel <soeren+git@soeren-tempel.net>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #3109

dracut/90zfs/.gitignore
dracut/90zfs/Makefile.am
dracut/90zfs/export-zfs.sh.in
dracut/90zfs/module-setup.sh.in
dracut/90zfs/mount-zfs.sh.in
dracut/90zfs/parse-zfs.sh.in
dracut/90zfs/zfs-lib.sh.in [new file with mode: 0755]
dracut/README.dracut.markdown

index 72a710a0ef2c71342de4ce741acd18712906dd35..9502be9851355cadbaac92b76d554b79350d257a 100644 (file)
@@ -2,3 +2,4 @@ export-zfs.sh
 module-setup.sh
 mount-zfs.sh
 parse-zfs.sh
+zfs-lib.sh
index 2d1360aded1b4832101a3f1b9b2170759c7e2b1c..650953c1b56f5ffcd86646c261c07d9f7c009f1e 100644 (file)
@@ -3,13 +3,15 @@ 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
+       $(top_srcdir)/dracut/90zfs/parse-zfs.sh \
+       $(top_srcdir)/dracut/90zfs/zfs-lib.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
+       $(top_srcdir)/dracut/90zfs/parse-zfs.sh.in \
+       $(top_srcdir)/dracut/90zfs/zfs-lib.sh.in
 
 $(pkgdracut_SCRIPTS):
        -$(SED) -e 's,@bindir\@,$(bindir),g' \
index 6382d762aa9783f81b51ab034d887a054b1e81d1..393753fbf6abe8017f4e476c79a86745136fa889 100755 (executable)
@@ -1,35 +1,29 @@
 #!/bin/sh
 
+. /lib/dracut-zfs-lib.sh
+
 _do_zpool_export() {
        local ret=0
-       local final=$1
-       local force
-       local OLDIFS="$IFS"
-       local NEWLINE="
-"
+       local final="${1}"
+       local opts=""
 
-       if [ "x$final" != "x" ]; then
-               force="-f"
+       if [ "x${final}" != "x" ]; then
+               opts="-f"
        fi
 
-       info "Exporting ZFS storage pools"
-       # Change IFS to allow for blanks in pool names.
-       IFS="$NEWLINE"
-       for fs in `zpool list -H -o name` ; do
-               zpool export $force "$fs" || ret=$?
-       done
-       IFS="$OLDIFS"
+       info "Exporting ZFS storage pools."
+       export_all ${opts} || ret=$?
 
-       if [ "x$final" != "x" ]; then
+       if [ "x${final}" != "x" ]; then
                info "zpool list"
                zpool list 2>&1 | vinfo
        fi
 
-       return $ret
+       return ${ret}
 }
 
 if command -v zpool >/dev/null; then
-       _do_zpool_export $1
+       _do_zpool_export "${1}"
 else
        :
 fi
index 81401f2b5dd8379bec6bd2130faeb6ef4b0b69b8..9eb9f576521a1b7a71ab2c88e6c2b98a43e569f7 100755 (executable)
@@ -2,7 +2,7 @@
 
 check() {
        # We depend on udev-rules being loaded
-       [ "$1" = "-d" ] && return 0
+       [ "${1}" = "-d" ] && return 0
 
        # Verify the zfs tool chain
        which zpool >/dev/null 2>&1 || return 1
@@ -39,10 +39,11 @@ install() {
        dracut_install hostid
        dracut_install awk
        dracut_install head
-       inst_hook cmdline 95 "$moddir/parse-zfs.sh"
-       inst_hook mount 98 "$moddir/mount-zfs.sh"
-       inst_hook shutdown 30 "$moddir/export-zfs.sh"
+       inst_hook cmdline 95 "${moddir}/parse-zfs.sh"
+       inst_hook mount 98 "${moddir}/mount-zfs.sh"
+       inst_hook shutdown 30 "${moddir}/export-zfs.sh"
 
+       inst_simple "${moddir}/zfs-lib.sh" "/lib/dracut-zfs-lib.sh"
        if [ -e @sysconfdir@/zfs/zpool.cache ]; then
                inst @sysconfdir@/zfs/zpool.cache
        fi
@@ -56,5 +57,5 @@ install() {
        BB=`hostid | cut -b 3,4`
        CC=`hostid | cut -b 5,6`
        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"
 }
index 8237d76f2efee9e15bbcc8f3c1d0a8b47f93874e..47c01d14c8d94f775a361f434c423b8b9f23a568 100755 (executable)
@@ -1,82 +1,45 @@
 #!/bin/sh
 
 . /lib/dracut-lib.sh
+. /lib/dracut-zfs-lib.sh
 
-ZPOOL_FORCE=""
-OLDIFS="$IFS"
-NEWLINE="
-"
+ZFS_DATASET=""
+ZFS_POOL=""
 
-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:*) ;;
+       *) return ;;
+esac
 
 # Delay until all required block devices are present.
 udevadm settle
 
-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 -n '/^-$/ !p' | sed 'q'`
-                       if [ $? -ne 0 ] || [ -z "$zfsbootfs" ] || \
-                               [ "$zfsbootfs" = "no pools available" ] ; 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 -n '/^-$/ !p' | sed 'q'`
-                               if [ $? -ne 0 ] || [ -z "$zfsbootfs" ] || \
-                                       [ "$zfsbootfs" = "no pools available" ] ; 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.
-                                       # Change IFS to allow for blanks in pool names.
-                                       IFS="$NEWLINE"
-                                       for fs in `zpool list -H -o name` ; do
-                                               zpool export "$fs"
-                                       done
-                                       IFS="$OLDIFS"
-
-                                       return 1
-                               fi
-                       fi
-                       info "ZFS: Using ${zfsbootfs} as root."
-               else
-                       # 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
+if [ "${root}" = "zfs:AUTO" ] ; then
+       ZFS_DATASET="$(find_bootfs)"
+       if [ $? -ne 0 ] ; then
+               zpool import -N -a ${ZPOOL_IMPORT_OPTS}
+               ZFS_DATASET="$(find_bootfs)"
+               if [ $? -ne 0 ] ; then
+                       warn "ZFS: No bootfs attribute found in importable pools."
+                       export_all
+
+                       rootok=0
+                       return 1
                fi
+       fi
+       info "ZFS: Using ${ZFS_DATASET} as root."
+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
+ZFS_DATASET="${ZFS_DATASET:-${root#zfs:}}"
+ZFS_POOL="${ZFS_DATASET%%/*}"
 
-               need_shutdown
-               ;;
-esac
+if import_pool "${ZFS_POOL}" ; then
+       info "ZFS: Mounting dataset ${ZFS_DATASET}..."
+       if mount_dataset "${ZFS_DATASET}" ; then
+               ROOTFS_MOUNTED=yes
+               return 0
+       fi
+fi
+
+rootok=0
+need_shutdown
index f45a629f3845b880c102c0f476929d517c0f7506..c305c782174b094b3aa1dd49a42f94efb819e706 100755 (executable)
@@ -4,22 +4,22 @@
 
 # Let the command line override our host id.
 spl_hostid=`getarg spl_hostid=`
-if [ "${spl_hostid}" != "" ] ; then
+if [ -n "${spl_hostid}" ] ; then
        info "ZFS: Using hostid from command line: ${spl_hostid}"
        AA=`echo ${spl_hostid} | cut -b 1,2`
        BB=`echo ${spl_hostid} | cut -b 3,4`
        CC=`echo ${spl_hostid} | cut -b 5,6`
        DD=`echo ${spl_hostid} | cut -b 7,8`
-       printf "\x$DD\x$CC\x$BB\x$AA" >/etc/hostid
-elif [ -f /etc/hostid ] ; then
+       printf "\x${DD}\x${CC}\x${BB}\x${AA}" >/etc/hostid
+elif [ -f "/etc/hostid" ] ; then
        info "ZFS: Using hostid from /etc/hostid: `hostid`"
 else
-       warn "ZFS: No hostid found on kernel command line or /etc/hostid.  "
+       warn "ZFS: No hostid found on kernel command line or /etc/hostid."
        warn "ZFS: Pools may not import correctly."
 fi
 
 wait_for_zfs=0
-case "$root" in
+case "${root}" in
        ""|zfs|zfs:)
                # We'll take root unset, root=zfs, or root=zfs:
                # No root set, so we want to read the bootfs attribute.  We
@@ -55,5 +55,5 @@ esac
 # modules to settle before mounting.
 if [ ${wait_for_zfs} -eq 1 ]; then
        ln -s /dev/null /dev/root 2>/dev/null
-       echo '[ -e /dev/zfs ]' > $hookdir/initqueue/finished/zfs.sh
+       echo '[ -e /dev/zfs ]' > "${hookdir}/initqueue/finished/zfs.sh"
 fi
diff --git a/dracut/90zfs/zfs-lib.sh.in b/dracut/90zfs/zfs-lib.sh.in
new file mode 100755 (executable)
index 0000000..a6ed4c3
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+. /lib/dracut-lib.sh
+
+OLDIFS="${IFS}"
+NEWLINE="
+"
+
+ZPOOL_IMPORT_OPTS=""
+if getargbool 0 zfs_force -y zfs.force -y zfsforce ; then
+       warn "ZFS: Will force-import pools if necessary."
+       ZPOOL_IMPORT_OPTS="${ZPOOL_IMPORT_OPTS} -f"
+fi
+
+# find_bootfs
+#   returns the first dataset with the bootfs attribute.
+find_bootfs() {
+       IFS="${NEWLINE}"
+       for dataset in $(zpool list -H -o bootfs); do
+               case "${dataset}" in
+                       "" | "-")
+                               continue
+                               ;;
+                       "no pools available")
+                               IFS="${OLDIFS}"
+                               return 1
+                               ;;
+                       *)
+                               IFS="${OLDIFS}"
+                               echo "${dataset}"
+                               return 0
+                               ;;
+               esac
+       done
+
+       IFS="${OLDIFS}"
+       return 1
+}
+
+# import_pool POOL
+#   imports the given zfs pool if it isn't imported already.
+import_pool() {
+       local pool="${1}"
+
+       if ! zpool list -H "${pool}" 2>&1 > /dev/null ; then
+               info "ZFS: Importing pool ${pool}..."
+               if ! zpool import -N ${ZPOOL_IMPORT_OPTS} "${pool}" ; then
+                       warn "ZFS: Unable to import pool ${pool}"
+                       return 1
+               fi
+       fi
+
+       return 0
+}
+
+# mount_dataset DATASET
+#   mounts the given zfs dataset.
+mount_dataset() {
+       local dataset="${1}"
+       local mountpoint="$(zfs get -H -o value mountpoint "${dataset}")"
+
+       # We need zfsutil for non-legacy mounts and not for legacy mounts.
+       if [ "${mountpoint}" = "legacy" ] ; then
+               mount -t zfs "${dataset}" "${NEWROOT}"
+       else
+               mount -o zfsutil -t zfs "${dataset}" "${NEWROOT}"
+       fi
+
+       return $?
+}
+
+# export_all OPTS
+#   exports all imported zfs pools.
+export_all() {
+       local opts="${1}"
+       local ret=0
+
+       IFS="${NEWLINE}"
+       for pool in `zpool list -H -o name` ; do
+               if zpool list -H "${pool}" 2>&1 > /dev/null ; then
+                       zpool export "${pool}" ${opts} || ret=$?
+               fi
+       done
+       IFS="${OLDIFS}"
+
+       return ${ret}
+}
index 27e94fff9d8184cdc37e21e3712ff869b7cb128a..e07326493fe116d42db082b1b78e1a1d1307fd5d 100644 (file)
@@ -80,6 +80,8 @@ 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.
 
+* `zfs-lib.sh`: Utility functions used by the other files.
+
 `module-setup.sh`
 ---------------