aboutsummaryrefslogtreecommitdiffstats
path: root/etc/init.d/zfs-import.in
diff options
context:
space:
mode:
Diffstat (limited to 'etc/init.d/zfs-import.in')
-rwxr-xr-xetc/init.d/zfs-import.in338
1 files changed, 338 insertions, 0 deletions
diff --git a/etc/init.d/zfs-import.in b/etc/init.d/zfs-import.in
new file mode 100755
index 000000000..1bc3ebe9a
--- /dev/null
+++ b/etc/init.d/zfs-import.in
@@ -0,0 +1,338 @@
+#!@SHELL@
+#
+# zfs-import This script will import/export zfs pools.
+#
+# chkconfig: 2345 01 99
+# description: This script will import/export zfs pools during system
+# boot/shutdown.
+# It is also responsible for all userspace zfs services.
+# probe: true
+#
+### BEGIN INIT INFO
+# Provides: zfs-import
+# Required-Start: zfs-zed
+# Required-Stop: zfs-zed
+# Default-Start: S
+# Default-Stop: 0 1 6
+# X-Start-Before: checkfs
+# X-Stop-After: zfs-mount
+# Short-Description: Import ZFS pools
+# Description: Run the `zpool import` or `zpool export` commands.
+### END INIT INFO
+#
+# Released under the 2-clause BSD license.
+#
+# The original script that acted as a template for this script came from
+# the Debian GNU/Linux kFreeBSD ZFS packages (which did not include a
+# licensing stansa) in the commit dated Mar 24, 2011:
+# https://github.com/zfsonlinux/pkg-zfs/commit/80a3ae582b59c0250d7912ba794dca9e669e605a
+
+# Source the common init script
+. @sysconfdir@/zfs/zfs-functions
+
+# ----------------------------------------------------
+
+do_depend()
+{
+ after sysfs udev zfs-zed
+ keyword -lxc -openvz -prefix -vserver
+}
+
+# Support function to get a list of all pools, separated with ';'
+find_pools()
+{
+ local CMD="$*"
+ local pools
+
+ pools=$($CMD 2> /dev/null | \
+ grep -E "pool:|^[a-zA-Z0-9]" | \
+ sed 's@.*: @@' | \
+ sort | \
+ while read pool; do \
+ echo -n "$pool;"
+ done)
+
+ echo "${pools%%;}" # Return without the last ';'.
+}
+
+# Import all pools
+do_import()
+{
+ local already_imported available_pools pool npools
+ local exception dir ZPOOL_IMPORT_PATH RET=0 r=1
+
+ # In case not shutdown cleanly.
+ [ -n "$init" ] && rm -f /etc/dfs/sharetab
+
+ # Just simplify code later on.
+ if [ -n "$USE_DISK_BY_ID" -a "$USE_DISK_BY_ID" != 'yes' ]
+ then
+ # It's something, but not 'yes' so it's no good to us.
+ unset USE_DISK_BY_ID
+ fi
+
+ # Find list of already imported pools.
+ already_imported=$(find_pools "$ZPOOL" list -H -oname)
+ available_pools=$(find_pools "$ZPOOL" import)
+
+ # Just in case - seen it happen (that a pool isn't visable/found
+ # with a simple "zpool import" but only when using the "-d"
+ # option or setting ZPOOL_IMPORT_PATH).
+ if [ -d "/dev/disk/by-id" ]
+ then
+ npools=$(find_pools "$ZPOOL" import -d /dev/disk/by-id)
+ if [ -n "$npools" ]
+ then
+ # Because we have found extra pool(s) here, which wasn't
+ # found 'normaly', we need to force USE_DISK_BY_ID to
+ # make sure we're able to actually import it/them later.
+ USE_DISK_BY_ID='yes'
+
+ # Filter out duplicates (pools found with the simpl
+ # "zpool import" but which is also found with the
+ # "zpool import -d ...").
+ npools=$(echo "$npools" | sed "s,$available_pools,,")
+
+ if [ -n "$available_pools" ]
+ then
+ # Add the list to the existing list of
+ # available pools
+ available_pools="$available_pools;$npools"
+ else
+ available_pools="$npools"
+ fi
+ fi
+ fi
+
+ # Filter out any exceptions...
+ if [ -n "$ZFS_POOL_EXCEPTIONS" ]
+ then
+ local found=""
+ local apools=""
+ OLD_IFS="$IFS" ; IFS=";"
+
+ for pool in $available_pools
+ do
+ for exception in $ZFS_POOL_EXCEPTIONS
+ do
+ [ "$pool" = "$exception" ] && continue 2
+ found="$pool"
+ done
+
+ if [ -n "$found" ]
+ then
+ if [ -n "$apools" ]
+ then
+ apools="$apools;$pool"
+ else
+ apools="$pool"
+ fi
+ fi
+ done
+
+ IFS="$OLD_IFS"
+ available_pools="$apools"
+ fi
+
+ # For backwards compability, make sure that ZPOOL_IMPORT_PATH is set
+ # to something we can use later with the real import(s). We want to
+ # make sure we find all by* dirs, BUT by-vdev should be first (if it
+ # exists).
+ if [ -n "$USE_DISK_BY_ID" -a -z "$ZPOOL_IMPORT_PATH" ]
+ then
+ local dirs
+ dirs="$(find /dev/disk/by-* -maxdepth 0 -type d | \
+ grep -v by-vdev)"
+ dirs="$(echo "$dirs" | sed 's, ,:,g')"
+ if [ -d "/dev/disk/by-vdev" ]
+ then
+ # Add by-vdev at the beginning.
+ ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:"
+ fi
+ ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH$dirs:/dev"
+ fi
+
+ # Needs to be exported for "zpool" to catch it.
+ [ -n "$ZPOOL_IMPORT_PATH" ] && export ZPOOL_IMPORT_PATH
+
+ # Mount all availible pools (except those set in ZFS_POOL_EXCEPTIONS.
+ #
+ # If not interactive (run from init - variable init='/sbin/init')
+ # we get ONE line for all pools being imported, with just a dot
+ # as status for each pool.
+ # Example: Importing ZFS pool(s)... [OK]
+ #
+ # If it IS interactive (started from the shell manually), then we
+ # get one line per pool importing.
+ # Example: Importing ZFS pool pool1 [OK]
+ # Importing ZFS pool pool2 [OK]
+ # [etc]
+ [ -n "$init" ] && zfs_log_begin_msg "Importing ZFS pool(s)"
+ OLD_IFS="$IFS" ; IFS=";"
+ for pool in $available_pools
+ do
+ [ -z "$pool" ] && continue
+
+ # We have pools that haven't been imported - import them
+ if [ -n "$init" ]
+ then
+ # Not interactive - a dot for each pool.
+ # Except on Gentoo where this doesn't work.
+ zfs_log_progress_msg "."
+ else
+ # Interactive - one 'Importing ...' line per pool
+ zfs_log_begin_msg "Importing ZFS pool $pool"
+ fi
+
+ # Import by using ZPOOL_IMPORT_PATH (either set above or in
+ # the config file) _or_ with the 'built in' default search
+ # paths. This is the prefered way.
+ "$ZPOOL" import -N "$pool" 2> /dev/null
+ r="$?" ; RET=$((RET + r))
+ if [ "$r" -eq 0 ]
+ then
+ # Output success and process the next pool
+ [ -z "$init" ] && zfs_log_end_msg 0
+ continue
+ fi
+ # We don't want a fail msg here, we're going to try import
+ # using the cache file soon and that might succeed.
+ [ ! -f "$ZPOOL_CACHE" ] && zfs_log_end_msg "$RET"
+
+ if [ "$r" -gt 0 -a -f "$ZPOOL_CACHE" ]
+ then
+ # Failed to import without a cache file. Try WITH...
+ if [ -z "$init" -a "$VERBOSE_MOUNT" = 'yes' ]
+ then
+ # Interactive + Verbose = more information
+ zfs_log_progress_msg " using cache file"
+ fi
+
+ "$ZPOOL" import -c "$ZPOOL_CACHE" -N "$pool" 2> /dev/null
+ r="$?" ; RET=$((RET + r))
+ if [ "$r" -eq 0 ]
+ then
+ [ -z "$init" ] && zfs_log_end_msg 0
+ continue 3 # Next pool
+ fi
+ zfs_log_end_msg "$RET"
+ fi
+ done
+ [ -n "$init" ] && zfs_log_end_msg "$RET"
+
+ IFS="$OLD_IFS"
+ [ -n "$already_imported" -a -z "$available_pools" ] && return 0
+
+ return "$RET"
+}
+
+# Export all pools
+do_export()
+{
+ local pool root_pool RET r
+ RET=0
+
+ root_pool=$(get_root_pool)
+
+ [ -n "$init" ] && zfs_log_begin_msg "Exporting ZFS pool(s)"
+ TMPFILE=$(mktemp --tmpdir=/var/tmp zpool.XXXXX)
+ "$ZPOOL" list -H -oname > "$TMPFILE"
+ while read pool; do
+ [ "$pool" = "$root_pool" ] && continue
+
+ if [ -z "$init" ]
+ then
+ # Interactive - one 'Importing ...' line per pool
+ zfs_log_begin_msg "Exporting ZFS pool $pool"
+ else
+ # Not interactive - a dot for each pool.
+ zfs_log_progress_msg "."
+ fi
+
+ "$ZPOOL" export "$pool"
+ r="$?" ; RET=$((RET + r))
+ [ -z "$init" ] && zfs_log_end_msg "$r"
+ done < "$TMPFILE"
+ rm -f "$TMPFILE"
+ [ -n "$init" ] && zfs_log_end_msg "$RET"
+}
+
+# Output the status and list of pools
+do_status()
+{
+ check_module_loaded || exit 0
+
+ "$ZPOOL" status && echo "" && "$ZPOOL" list
+}
+
+do_start()
+{
+ if [ "$VERBOSE_MOUNT" = 'yes' ]
+ then
+ zfs_log_begin_msg "Checking if ZFS userspace tools present"
+ fi
+
+ if checksystem
+ then
+ [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0
+
+ if [ "$VERBOSE_MOUNT" = 'yes' ]
+ then
+ zfs_log_begin_msg "Loading kernel ZFS infrastructure"
+ fi
+
+ if ! load_module
+ then
+ [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 1
+ return 5
+ fi
+ [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0
+
+ do_import && udev_trigger # just to make sure we get zvols.
+
+ return 0
+ else
+ return 1
+ fi
+}
+
+do_stop()
+{
+ # Check to see if the module is even loaded.
+ check_module_loaded || exit 0
+
+ do_export
+}
+
+# ----------------------------------------------------
+
+if [ ! -e /etc/gentoo-release ]
+then
+ case "$1" in
+ start)
+ do_start
+ ;;
+ stop)
+ do_stop
+ ;;
+ status)
+ do_status
+ ;;
+ force-reload|condrestart|reload|restart)
+ # no-op
+ ;;
+ *)
+ [ -n "$1" ] && echo "Error: Unknown command $1."
+ echo "Usage: $0 {start|stop|status}"
+ exit 3
+ ;;
+ esac
+
+ exit $?
+else
+ # Create wrapper functions since Gentoo don't use the case part.
+ depend() { do_depend; }
+ start() { do_start; }
+ stop() { do_stop; }
+ status() { do_status; }
+fi