diff --git a/contrib/initramfs/scripts/zfs b/contrib/initramfs/scripts/zfs index 8cdef0b54201..6a78a46d29a1 100644 --- a/contrib/initramfs/scripts/zfs +++ b/contrib/initramfs/scripts/zfs @@ -96,12 +96,11 @@ find_rootfs() find_pools() { local CMD="$*" - local pools + local pools pool pools=$($CMD 2> /dev/null | \ grep -E "pool:|^[a-zA-Z0-9]" | \ sed 's@.*: @@' | \ - sort | \ while read pool; do \ echo -n "$pool;" done) @@ -114,6 +113,11 @@ get_pools() { local available_pools npools + if [ -n "${ZFS_POOL_IMPORT}" ]; then + echo "$ZFS_POOL_IMPORT" + return 0 + fi + # Get the base list of availible pools. available_pools=$(find_pools "$ZPOOL" import) @@ -185,7 +189,7 @@ get_pools() import_pool() { local pool="$1" - local dirs dir ZFS_CMD ZFS_STDERR ZFS_ERROR + local dirs dir # Verify that the pool isn't already imported # Make as sure as we can to not require '-f' to import. @@ -223,7 +227,7 @@ import_pool() [ "$quiet" != "y" ] && zfs_log_begin_msg \ "Importing pool '${pool}' using defaults" - ZFS_CMD="${ZPOOL} import -N ${ZPOOL_FORCE}" + ZFS_CMD="${ZPOOL} import -N ${ZPOOL_FORCE} ${ZPOOL_IMPORT_OPTS}" ZFS_STDERR="$($ZFS_CMD "$pool" 2>&1)" ZFS_ERROR="$?" if [ "${ZFS_ERROR}" != 0 ] @@ -235,7 +239,7 @@ import_pool() [ "$quiet" != "y" ] && zfs_log_begin_msg \ "Importing pool '${pool}' using cachefile." - ZFS_CMD="${ZPOOL} import -c ${ZPOOL_CACHE} -N ${ZPOOL_FORCE}" + ZFS_CMD="${ZPOOL} import -c ${ZPOOL_CACHE} -N ${ZPOOL_FORCE} ${ZPOOL_IMPORT_OPTS}" ZFS_STDERR="$($ZFS_CMD "$pool" 2>&1)" ZFS_ERROR="$?" fi @@ -308,7 +312,11 @@ load_module_initrd() mount_fs() { local fs="$1" - local mountpoint ZFS_CMD ZFS_STDERR ZFS_ERROR + local mountpoint + + # Check that the filesystem exists + "${ZFS}" list -oname -tfilesystem -H "${fs}" > /dev/null 2>&1 + [ "$?" -ne 0 ] && return 1 # Need the _original_ datasets mountpoint! mountpoint=$(get_fs_value "$fs" mountpoint) @@ -378,7 +386,6 @@ mount_fs() decrypt_fs() { local fs="$1" - local ZFS_CMD ZFS_STDERR ZFS_ERROR # If the 'zfs key' command isn't availible, exit right here. "${ZFS}" 2>&1 | grep -q 'key -l ' || return 0 @@ -449,7 +456,6 @@ decrypt_fs() destroy_fs() { local fs="$1" - local ZFS_CMD ZFS_STDERR ZFS_ERROR [ "$quiet" != "y" ] && \ zfs_log_begin_msg "Destroying '$fs'" @@ -487,7 +493,6 @@ clone_snap() local snap="$1" local destfs="$2" local mountpoint="$3" - local ZFS_CMD ZFS_STDERR ZFS_ERROR [ "$quiet" != "y" ] && zfs_log_begin_msg "Cloning '$snap' to '$destfs'" @@ -526,7 +531,6 @@ clone_snap() rollback_snap() { local snap="$1" - local ZFS_CMD ZFS_STDERR ZFS_ERROR [ "$quiet" != "y" ] && zfs_log_begin_msg "Rollback $snap" @@ -616,7 +620,7 @@ setup_snapshot_booting() # already exists, destroy it. Recursivly if [ $(get_fs_value "${rootfs}_${snapname}" type) ]; then filesystems=$("${ZFS}" list -oname -tfilesystem -H \ - -r "${ZFS_BOOTFS}" | sort -r) + -r -Sname "${ZFS_BOOTFS}") for fs in $filesystems; do destroy_fs "${fs}" done @@ -675,9 +679,7 @@ setup_snapshot_booting() # This is the main function. mountroot() { - local snaporig - local snapsub - local destfs + local snaporig snapsub destfs pool POOLS # ---------------------------------------------------------------- # I N I T I A L S E T U P diff --git a/etc/init.d/README.md b/etc/init.d/README.md index f3adc11859fd..89edb1da3118 100644 --- a/etc/init.d/README.md +++ b/etc/init.d/README.md @@ -42,9 +42,9 @@ INSTALLING INIT SCRIPT LINKS To setup the init script links in /etc/rc?.d manually on a Debian GNU/Linux (or derived) system, run the following commands (the order is important!): - update-rc.d zfs-import start 07 S . stop 08 0 1 6 . - update-rc.d zfs-mount start 02 2 3 4 5 . stop 07 0 1 6 . - update-rc.d zfs-zed start 26 2 3 4 5 . stop 06 0 1 6 . + update-rc.d zfs-import start 07 S . stop 07 0 1 6 . + update-rc.d zfs-mount start 02 2 3 4 5 . stop 06 0 1 6 . + update-rc.d zfs-zed start 07 2 3 4 5 . stop 08 0 1 6 . update-rc.d zfs-share start 27 2 3 4 5 . stop 05 0 1 6 . To do the same on RedHat, Fedora and/or CentOS: diff --git a/etc/init.d/zfs-functions.in b/etc/init.d/zfs-functions.in index 95b0a2997ad7..acfdf99263d8 100644 --- a/etc/init.d/zfs-functions.in +++ b/etc/init.d/zfs-functions.in @@ -310,6 +310,15 @@ get_root_pool() [ "$5" = "zfs" ] && echo "${1%%/*}" } +# Check if a variable is 'yes' (any case) or '1' +# Returns TRUE if set. +check_boolean() +{ + local var="$1" + + echo "$var" | grep -Eiq "^yes$|^on$|^true$|^1$" && return 0 || return 1 +} + check_module_loaded() { module="$1" @@ -348,12 +357,12 @@ read_mtab() # * We need to use the external echo, because the # internal one would interpret the backslash code # (incorrectly), giving us a  instead. - mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,") + mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,g") fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,") - # Replace 'unwanted' characters with underscore. - mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,_,g' \ - -e 's,-,_,g' -e 's,\.,_,g' -e 's, ,_,g') + # Remove 'unwanted' characters. + mntpnt=$(printf '%b\n' "$mntpnt" | sed -e 's,/,,g' \ + -e 's,-,,g' -e 's,\.,,g' -e 's, ,,g') fs=$(printf '%b\n' "$fs") # Set the variable. diff --git a/etc/init.d/zfs-import.in b/etc/init.d/zfs-import.in index a3d6c1442cee..5e219296379b 100755 --- a/etc/init.d/zfs-import.in +++ b/etc/init.d/zfs-import.in @@ -209,7 +209,7 @@ do_import() # 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 + "$ZPOOL" import -N ${ZPOOL_IMPORT_OPTS} "$pool" 2> /dev/null r="$?" ; RET=$((RET + r)) if [ "$r" -eq 0 ] then @@ -224,13 +224,14 @@ do_import() 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' ] + if [ -z "$init" ] && check_boolean "$VERBOSE_MOUNT" then # Interactive + Verbose = more information zfs_log_progress_msg " using cache file" fi - "$ZPOOL" import -c "$ZPOOL_CACHE" -N "$pool" 2> /dev/null + "$ZPOOL" import -c "$ZPOOL_CACHE" -N ${ZPOOL_IMPORT_OPTS} \ + "$pool" 2> /dev/null r="$?" ; RET=$((RET + r)) if [ "$r" -eq 0 ] then @@ -295,26 +296,24 @@ do_status() do_start() { - if [ "$VERBOSE_MOUNT" = 'yes' ] + if check_boolean "$VERBOSE_MOUNT" then zfs_log_begin_msg "Checking if ZFS userspace tools present" fi if checksystem then - [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0 + check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0 - if [ "$VERBOSE_MOUNT" = 'yes' ] - then - zfs_log_begin_msg "Loading kernel ZFS infrastructure" - fi + check_boolean "$VERBOSE_MOUNT" && \ + zfs_log_begin_msg "Loading kernel ZFS infrastructure" if ! load_module "zfs" then - [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 1 + check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 1 return 5 fi - [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0 + check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0 do_import && udev_trigger # just to make sure we get zvols. diff --git a/etc/init.d/zfs-mount.in b/etc/init.d/zfs-mount.in index 95aefd6d6cf9..05cea9b88892 100755 --- a/etc/init.d/zfs-mount.in +++ b/etc/init.d/zfs-mount.in @@ -67,8 +67,8 @@ do_mount() { local verbose overlay i mntpt val - [ "$VERBOSE_MOUNT" = 'yes' ] && verbose=v - [ "$OVERLAY_MOUNTS" = 'yes' ] && overlay=O + check_boolean "$VERBOSE_MOUNT" && verbose=v + check_boolean "$DO_OVERLAY_MOUNTS" && overlay=O zfs_action "Mounting ZFS filesystem(s)" \ "$ZFS" mount -a$verbose$overlay "$MOUNT_EXTRA_OPTIONS" @@ -78,7 +78,7 @@ do_mount() # can get zfs-import to run sufficiently early on in the boot # process - before local mounts. This is just here in case/if # this isn't possible. - [ "$VERBOSE_MOUNT" = 'yes' ] && \ + check_boolean "$VERBOSE_MOUNT" && \ zfs_log_begin_msg "Mounting volumes and filesystems registered in fstab" read_mtab "^/dev/(zd|zvol)" @@ -90,7 +90,7 @@ do_mount() dev=$(eval echo "$"FSTAB_dev_$i) if ! in_mtab "$mntpt" && ! is_mounted "$mntpt" && [ -e "$dev" ] then - [ "$VERBOSE_MOUNT" = 'yes' ] && \ + check_boolean "$VERBOSE_MOUNT" && \ zfs_log_progress_msg "$mntpt " fsck "$dev" && mount "$mntpt" fi @@ -107,7 +107,7 @@ do_mount() mntpt=$(eval echo "$""$var") if ! in_mtab "$mntpt" && ! is_mounted "$mntpt" then - [ "$VERBOSE_MOUNT" = 'yes' ] && \ + check_boolean "$VERBOSE_MOUNT" && \ zfs_log_progress_msg "$mntpt " mount "$mntpt" fi @@ -115,7 +115,7 @@ do_mount() i=$((i + 1)) var=$(eval echo FSTAB_$i) done - [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0 + check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0 return 0 } @@ -131,7 +131,7 @@ do_unmount() # this isn't possible. zfs_action "Unmounting ZFS filesystems" "$ZFS" unmount -a - [ "$VERBOSE_MOUNT" = 'yes' ] && \ + check_boolean "$VERBOSE_MOUNT" && \ zfs_log_begin_msg "Unmounting volumes and filesystems registered in fstab" read_mtab "^/dev/(zd|zvol)" @@ -143,7 +143,7 @@ do_unmount() dev=$(eval echo "$"FSTAB_dev_$i) if in_mtab "$mntpt" then - [ "$VERBOSE_MOUNT" = 'yes' ] && \ + check_boolean "$VERBOSE_MOUNT" && \ zfs_log_progress_msg "$mntpt " umount "$mntpt" fi @@ -159,7 +159,7 @@ do_unmount() do mntpt=$(eval echo "$""$var") if in_mtab "$mntpt"; then - [ "$VERBOSE_MOUNT" = 'yes' ] && \ + check_boolean "$VERBOSE_MOUNT" && \ zfs_log_progress_msg "$mntpt " umount "$mntpt" fi @@ -167,20 +167,16 @@ do_unmount() i=$((i + 1)) var=$(eval echo FSTAB_$i) done - [ "$VERBOSE_MOUNT" = 'yes' ] && zfs_log_end_msg 0 + check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0 return 0 } do_start() { - check_module_loaded "zfs" || exit 0 + check_boolean "$ZFS_MOUNT" || exit 0 - case "$ZFS_MOUNT" in - [Oo][Ff][Ff]|[Nn][Oo]|''|0) - exit 3 - ;; - esac + check_module_loaded "zfs" || exit 0 # Ensure / exists in /etc/mtab, if not update mtab accordingly. # This should be handled by rc.sysinit but lets be paranoid. @@ -194,11 +190,7 @@ do_start() do_stop() { - case "$ZFS_UNMOUNT" in - [Oo][Ff][Ff]|[Nn][Oo]|''|0) - exit 0 - ;; - esac + check_boolean "$ZFS_UNMOUNT" || exit 0 check_module_loaded "zfs" || exit 0 diff --git a/etc/init.d/zfs-share.in b/etc/init.d/zfs-share.in index 2b66afe500c7..1b70da4d50c7 100755 --- a/etc/init.d/zfs-share.in +++ b/etc/init.d/zfs-share.in @@ -40,11 +40,7 @@ do_depend() do_start() { - case "$ZFS_SHARE" in - [Oo][Ff][Ff]|[Nn][Oo]|''|0) - exit 0 - ;; - esac + check_boolean "$ZFS_SHARE" || exit 0 check_module_loaded "zfs" || exit 0 @@ -53,11 +49,7 @@ do_start() do_stop() { - case "$ZFS_UNSHARE" in - [Oo][Ff][Ff]|[Nn][Oo]|''|0) - exit 0 - ;; - esac + check_boolean "$ZFS_UNSHARE" || exit 0 check_module_loaded "zfs" || exit 0 diff --git a/etc/init.d/zfs.in b/etc/init.d/zfs.in index d81abfef56c4..eabb7e4675cb 100644 --- a/etc/init.d/zfs.in +++ b/etc/init.d/zfs.in @@ -1,5 +1,8 @@ # ZoL userland configuration. +# To enable a boolean setting, set it to yes, on, true, or 1. +# Anything else will be interpreted as unset. + # Run `zfs mount -a` during system start? ZFS_MOUNT='yes' @@ -29,6 +32,27 @@ VERBOSE_MOUNT='no' # is not allowed). DO_OVERLAY_MOUNTS='no' +# Any additional option to the 'zfs import' commandline? +# Include '-o' for each option wanted. +# You don't need to put '-f' in here, unless you want it ALL the time. +# Using the option 'zfsforce=1' on the grub/kernel command line will +# do the same, but on a case-to-case basis. +ZPOOL_IMPORT_OPTS="" + +# Full path to the ZFS cache file? +# See "cachefile" in zpool(8). +# The default is "@sysconfdir@/zfs/zpool.cache". +#ZPOOL_CACHE="@sysconfdir@/zfs/zpool.cache" +# +# Setting ZPOOL_CACHE to an empty string ('') AND setting ZPOOL_IMPORT_OPTS to +# "-c @sysconfdir@/zfs/zpool.cache" will _enforce_ the use of a cache file. +# This is needed in some cases (extreme amounts of VDEVs, multipath etc). +# Generally, the use of a cache file is usually not recommended on Linux +# because it sometimes is more trouble than it's worth (laptops with external +# devices or when/if device nodes changes names). +#ZPOOL_IMPORT_OPTS="-c @sysconfdir@/zfs/zpool.cache" +#ZPOOL_CACHE="" + # Any additional option to the 'zfs mount' command line? # Include '-o' for each option wanted. MOUNT_EXTRA_OPTIONS="" @@ -77,6 +101,13 @@ ZFS_INITRD_POST_MODPROBE_SLEEP='0' # This is a space separated list. #ZFS_POOL_EXCEPTIONS="test2" +# List of pools to import? +# If this variable is set, there will be NO auto-import of ANY other +# pool. In essence, there will be no auto detection of availible pools. +# This is a semi-colon separated list. +# Makes the variable ZFS_POOL_EXCEPTIONS above redundant (won't be checked). +#ZFS_POOL_IMPORT="pool1;pool2" + # Optional arguments for the ZFS Event Daemon (ZED). # See zed(8) for more information on available options. #ZED_ARGS="-M"