mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
162cc80b81
Let Debian use the sysv-rc variant of the script, even when OpenRC is
installed. Unlike on Gentoo, OpenRC on Debian consumes both the
sysv-rc scripts and OpenRC ones. ZFS initscripts on Debian should be
the sysv-rc version to provide most compatibility and to integrate
with the rest of initscripts for dependency tracking.
Restrict the substitution in the Makefile to the dedicated list.
This construct is inspired by Mo Zhou's detection of the execution
shell and follows the strategy of Peter in 6ef28c526b
.
As of 2024, the initscripts are mostly relevant on Debian, Gentoo and
their derivatives.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Benda Xu <orv@debian.org>
Issue #8063
Issue #8204
Issue #8359
Closes #15977
339 lines
8.3 KiB
Plaintext
Executable File
339 lines
8.3 KiB
Plaintext
Executable File
#!@DEFAULT_INIT_SHELL@
|
|
# shellcheck disable=SC2154
|
|
#
|
|
# zfs-import This script will import ZFS pools
|
|
#
|
|
# chkconfig: 2345 01 99
|
|
# description: This script will perform a verbatim import of ZFS pools
|
|
# during system boot.
|
|
# probe: true
|
|
#
|
|
### BEGIN INIT INFO
|
|
# Provides: zfs-import
|
|
# Required-Start: mtab
|
|
# Required-Stop: $local_fs mtab
|
|
# 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` command.
|
|
### END INIT INFO
|
|
#
|
|
# NOTE: Not having '$local_fs' on Required-Start but only on Required-Stop
|
|
# is on purpose. If we have '$local_fs' in both (and X-Start-Before=checkfs)
|
|
# we get conflicts - import needs to be started extremely early,
|
|
# but not stopped too late.
|
|
#
|
|
# Released under the 2-clause BSD license.
|
|
#
|
|
# This script is based on debian/zfsutils.zfs.init from the
|
|
# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
|
|
|
|
# Source the common init script
|
|
. @sysconfdir@/zfs/zfs-functions
|
|
|
|
# ----------------------------------------------------
|
|
|
|
do_depend()
|
|
{
|
|
before swap
|
|
after sysfs udev
|
|
keyword -lxc -openvz -prefix -vserver
|
|
}
|
|
|
|
# Use the zpool cache file to import pools
|
|
do_verbatim_import()
|
|
{
|
|
if [ -f "$ZPOOL_CACHE" ]
|
|
then
|
|
zfs_action "Importing ZFS pool(s)" \
|
|
"$ZPOOL" import -c "$ZPOOL_CACHE" -N -a
|
|
fi
|
|
}
|
|
|
|
# Support function to get a list of all pools, separated with ';'
|
|
find_pools()
|
|
{
|
|
local pools
|
|
|
|
pools=$("$@" 2> /dev/null | \
|
|
sed -Ee '/pool:|^[a-zA-Z0-9]/!d' -e 's@.*: @@' | \
|
|
sort | \
|
|
tr '\n' ';')
|
|
|
|
echo "${pools%%;}" # Return without the last ';'.
|
|
}
|
|
|
|
# Find and import all visible pools, even exported ones
|
|
do_import_all_visible()
|
|
{
|
|
local already_imported available_pools pool npools
|
|
local exception dir ZPOOL_IMPORT_PATH RET=0 r=1
|
|
|
|
# In case not shutdown cleanly.
|
|
# shellcheck disable=SC2154
|
|
[ -n "$init" ] && rm -f /etc/dfs/sharetab
|
|
|
|
# Just simplify code later on.
|
|
if [ -n "$USE_DISK_BY_ID" ] && [ "$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 visible/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 'normally', 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'
|
|
|
|
if [ -n "$available_pools" ]
|
|
then
|
|
# 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,,")
|
|
|
|
# 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 compatibility, 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" ] && [ -z "$ZPOOL_IMPORT_PATH" ]
|
|
then
|
|
local dirs
|
|
dirs="$(for dir in $(echo /dev/disk/by-*)
|
|
do
|
|
# Ignore by-vdev here - we want it first!
|
|
echo "$dir" | grep -q /by-vdev && continue
|
|
[ ! -d "$dir" ] && continue
|
|
|
|
printf "%s" "$dir:"
|
|
done | sed 's,:$,,g')"
|
|
|
|
if [ -d "/dev/disk/by-vdev" ]
|
|
then
|
|
# Add by-vdev at the beginning.
|
|
ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:"
|
|
fi
|
|
|
|
# Help with getting LUKS partitions etc imported.
|
|
if [ -d "/dev/mapper" ]; then
|
|
if [ -n "$ZPOOL_IMPORT_PATH" ]; then
|
|
ZPOOL_IMPORT_PATH="$ZPOOL_IMPORT_PATH:/dev/mapper:"
|
|
else
|
|
ZPOOL_IMPORT_PATH="/dev/mapper:"
|
|
fi
|
|
fi
|
|
|
|
# ... and /dev at the very end, just for good measure.
|
|
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 available 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 preferred way.
|
|
# shellcheck disable=SC2086
|
|
"$ZPOOL" import -N ${ZPOOL_IMPORT_OPTS} "$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 ] && [ -f "$ZPOOL_CACHE" ]
|
|
then
|
|
# Failed to import without a cache file. Try WITH...
|
|
if [ -z "$init" ] && check_boolean "$VERBOSE_MOUNT"
|
|
then
|
|
# Interactive + Verbose = more information
|
|
zfs_log_progress_msg " using cache file"
|
|
fi
|
|
|
|
# shellcheck disable=SC2086
|
|
"$ZPOOL" import -c "$ZPOOL_CACHE" -N ${ZPOOL_IMPORT_OPTS} \
|
|
"$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" ] && [ -z "$available_pools" ] && return 0
|
|
|
|
return "$RET"
|
|
}
|
|
|
|
do_import()
|
|
{
|
|
if check_boolean "$ZPOOL_IMPORT_ALL_VISIBLE"
|
|
then
|
|
do_import_all_visible
|
|
else
|
|
# This is the default option
|
|
do_verbatim_import
|
|
fi
|
|
}
|
|
|
|
# Output the status and list of pools
|
|
do_status()
|
|
{
|
|
check_module_loaded "zfs" || exit 0
|
|
|
|
"$ZPOOL" status && echo "" && "$ZPOOL" list
|
|
}
|
|
|
|
do_start()
|
|
{
|
|
if check_boolean "$VERBOSE_MOUNT"
|
|
then
|
|
zfs_log_begin_msg "Checking if ZFS userspace tools present"
|
|
fi
|
|
|
|
if checksystem
|
|
then
|
|
check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0
|
|
|
|
check_boolean "$VERBOSE_MOUNT" && \
|
|
zfs_log_begin_msg "Loading kernel ZFS infrastructure"
|
|
|
|
if ! load_module "zfs"
|
|
then
|
|
check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 1
|
|
return 5
|
|
fi
|
|
check_boolean "$VERBOSE_MOUNT" && zfs_log_end_msg 0
|
|
|
|
do_import && udev_trigger # just to make sure we get zvols.
|
|
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ----------------------------------------------------
|
|
|
|
if @IS_SYSV_RC@
|
|
then
|
|
case "$1" in
|
|
start)
|
|
do_start
|
|
;;
|
|
stop)
|
|
# no-op
|
|
;;
|
|
status)
|
|
do_status
|
|
;;
|
|
force-reload|condrestart|reload|restart)
|
|
# no-op
|
|
;;
|
|
*)
|
|
[ -n "$1" ] && echo "Error: Unknown command $1."
|
|
echo "Usage: $0 {start|status}"
|
|
exit 3
|
|
;;
|
|
esac
|
|
|
|
exit $?
|
|
else
|
|
# Create wrapper functions since Gentoo don't use the case part.
|
|
depend() { do_depend; }
|
|
start() { do_start; }
|
|
status() { do_status; }
|
|
fi
|