diff options
Diffstat (limited to 'etc/init.d/zfs-import.in')
-rwxr-xr-x | etc/init.d/zfs-import.in | 338 |
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 |