aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/dracut/90zfs
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2015-07-09 11:41:14 -0700
committerBrian Behlendorf <[email protected]>2015-07-09 13:59:37 -0700
commitcc49250563b65c80d87afa5273ae350d06aa8d3b (patch)
tree9fe3928c6279f518c82d0f5fd8a813e8a3ed7d75 /contrib/dracut/90zfs
parent2cac7f5f11756663525a5d4604d9f0a3202d4024 (diff)
Move dracut directory to contrib
The dracut code is analogous to the initramfs code and as such it should be located in the contrib with initramfs for consistency. Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'contrib/dracut/90zfs')
-rw-r--r--contrib/dracut/90zfs/.gitignore5
-rw-r--r--contrib/dracut/90zfs/Makefile.am25
-rwxr-xr-xcontrib/dracut/90zfs/export-zfs.sh.in29
-rwxr-xr-xcontrib/dracut/90zfs/module-setup.sh.in61
-rwxr-xr-xcontrib/dracut/90zfs/mount-zfs.sh.in44
-rwxr-xr-xcontrib/dracut/90zfs/parse-zfs.sh.in59
-rwxr-xr-xcontrib/dracut/90zfs/zfs-lib.sh.in87
7 files changed, 310 insertions, 0 deletions
diff --git a/contrib/dracut/90zfs/.gitignore b/contrib/dracut/90zfs/.gitignore
new file mode 100644
index 000000000..9502be985
--- /dev/null
+++ b/contrib/dracut/90zfs/.gitignore
@@ -0,0 +1,5 @@
+export-zfs.sh
+module-setup.sh
+mount-zfs.sh
+parse-zfs.sh
+zfs-lib.sh
diff --git a/contrib/dracut/90zfs/Makefile.am b/contrib/dracut/90zfs/Makefile.am
new file mode 100644
index 000000000..30880bfc5
--- /dev/null
+++ b/contrib/dracut/90zfs/Makefile.am
@@ -0,0 +1,25 @@
+pkgdracutdir = $(dracutdir)/modules.d/90zfs
+pkgdracut_SCRIPTS = \
+ $(top_srcdir)/contrib/dracut/90zfs/export-zfs.sh \
+ $(top_srcdir)/contrib/dracut/90zfs/module-setup.sh \
+ $(top_srcdir)/contrib/dracut/90zfs/mount-zfs.sh \
+ $(top_srcdir)/contrib/dracut/90zfs/parse-zfs.sh \
+ $(top_srcdir)/contrib/dracut/90zfs/zfs-lib.sh
+
+EXTRA_DIST = \
+ $(top_srcdir)/contrib/dracut/90zfs/export-zfs.sh.in \
+ $(top_srcdir)/contrib/dracut/90zfs/module-setup.sh.in \
+ $(top_srcdir)/contrib/dracut/90zfs/mount-zfs.sh.in \
+ $(top_srcdir)/contrib/dracut/90zfs/parse-zfs.sh.in \
+ $(top_srcdir)/contrib/dracut/90zfs/zfs-lib.sh.in
+
+$(pkgdracut_SCRIPTS):
+ -$(SED) -e 's,@bindir\@,$(bindir),g' \
+ -e 's,@sbindir\@,$(sbindir),g' \
+ -e 's,@udevdir\@,$(udevdir),g' \
+ -e 's,@udevruledir\@,$(udevruledir),g' \
+ -e 's,@sysconfdir\@,$(sysconfdir),g' \
+
+distclean-local::
+ -$(RM) $(pkgdracut_SCRIPTS)
diff --git a/contrib/dracut/90zfs/export-zfs.sh.in b/contrib/dracut/90zfs/export-zfs.sh.in
new file mode 100755
index 000000000..393753fbf
--- /dev/null
+++ b/contrib/dracut/90zfs/export-zfs.sh.in
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+. /lib/dracut-zfs-lib.sh
+
+_do_zpool_export() {
+ local ret=0
+ local final="${1}"
+ local opts=""
+
+ if [ "x${final}" != "x" ]; then
+ opts="-f"
+ fi
+
+ info "Exporting ZFS storage pools."
+ export_all ${opts} || ret=$?
+
+ 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/contrib/dracut/90zfs/module-setup.sh.in b/contrib/dracut/90zfs/module-setup.sh.in
new file mode 100755
index 000000000..9eb9f5765
--- /dev/null
+++ b/contrib/dracut/90zfs/module-setup.sh.in
@@ -0,0 +1,61 @@
+#!/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 @udevruledir@/90-zfs.rules
+ inst_rules @udevruledir@/69-vdev.rules
+ inst_rules @udevruledir@/60-zvol.rules
+ dracut_install @sbindir@/zfs
+ dracut_install @sbindir@/zpool
+ dracut_install @udevdir@/vdev_id
+ dracut_install @udevdir@/zvol_id
+ dracut_install mount.zfs
+ 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_simple "${moddir}/zfs-lib.sh" "/lib/dracut-zfs-lib.sh"
+ if [ -e @sysconfdir@/zfs/zpool.cache ]; then
+ inst @sysconfdir@/zfs/zpool.cache
+ fi
+
+ if [ -e @sysconfdir@/zfs/vdev_id.conf ]; then
+ inst @sysconfdir@/zfs/vdev_id.conf
+ fi
+
+ # Synchronize initramfs and system hostid
+ AA=`hostid | cut -b 1,2`
+ 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"
+}
diff --git a/contrib/dracut/90zfs/mount-zfs.sh.in b/contrib/dracut/90zfs/mount-zfs.sh.in
new file mode 100755
index 000000000..2abc8766b
--- /dev/null
+++ b/contrib/dracut/90zfs/mount-zfs.sh.in
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+. /lib/dracut-zfs-lib.sh
+
+ZFS_DATASET=""
+ZFS_POOL=""
+
+case "${root}" in
+ zfs:*) ;;
+ *) return ;;
+esac
+
+# Delay until all required block devices are present.
+udevadm settle
+
+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 || export_all "-f"
+
+ rootok=0
+ return 1
+ fi
+ fi
+ info "ZFS: Using ${ZFS_DATASET} as root."
+fi
+
+ZFS_DATASET="${ZFS_DATASET:-${root#zfs:}}"
+ZFS_POOL="${ZFS_DATASET%%/*}"
+
+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
diff --git a/contrib/dracut/90zfs/parse-zfs.sh.in b/contrib/dracut/90zfs/parse-zfs.sh.in
new file mode 100755
index 000000000..c305c7821
--- /dev/null
+++ b/contrib/dracut/90zfs/parse-zfs.sh.in
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+. /lib/dracut-lib.sh
+
+# Let the command line override our host id.
+spl_hostid=`getarg spl_hostid=`
+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
+ info "ZFS: Using hostid from /etc/hostid: `hostid`"
+else
+ 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
+ ""|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
+ wait_for_zfs=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
+ wait_for_zfs=1
+
+ info "ZFS: Set ${root} as bootfs."
+ ;;
+esac
+
+# Make sure Dracut is happy that we have a root and will wait for ZFS
+# 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"
+fi
diff --git a/contrib/dracut/90zfs/zfs-lib.sh.in b/contrib/dracut/90zfs/zfs-lib.sh.in
new file mode 100755
index 000000000..1c223befd
--- /dev/null
+++ b/contrib/dracut/90zfs/zfs-lib.sh.in
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+command -v getarg >/dev/null || . /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}
+}