mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-11-17 01:51:00 +03:00
3f1cc17c90
ZED depends on /var. When /var is a separate dataset, it must be
mounted before starting ZED. This change moves the zfs-zed service
from starting first, to starting after zfs-mount, but before zfs-share.
As discussed in issue #3513, ZED does not need to start first in order
to consume events made during the zfs-import and zfs-mount services.
The events will be queued and can be handled later in the boot process.
ZED may, however, handle sharing in the future, so it should be started
before the zfs-share service.
This commit also stops the zfs-import service from writing temp files
to /var/tmp on shutdown and it corrects the return code for the OpenRC
service.
Other OpenRC-specific changes noted in issue #3513 were reitereated in
issue #3715 and committed in da619f3
.
Signed-off-by: James Lee <jlee@thestaticvoid.com>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #3513
367 lines
8.9 KiB
Plaintext
Executable File
367 lines
8.9 KiB
Plaintext
Executable File
#!@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: 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` or `zpool export` commands.
|
|
### 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.
|
|
#
|
|
# 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
|
|
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'
|
|
|
|
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 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="$(for dir in $(echo /dev/disk/by-*)
|
|
do
|
|
# Ignore by-vdev here - we wan't it first!
|
|
echo "$dir" | grep -q /by-vdev && continue
|
|
[ ! -d "$dir" ] && continue
|
|
|
|
echo -n "$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 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 already_imported pool root_pool RET r
|
|
RET=0
|
|
|
|
root_pool=$(get_root_pool)
|
|
|
|
[ -n "$init" ] && zfs_log_begin_msg "Exporting ZFS pool(s)"
|
|
|
|
# Find list of already imported pools.
|
|
already_imported=$(find_pools "$ZPOOL" list -H -oname)
|
|
|
|
OLD_IFS="$IFS" ; IFS=";"
|
|
for pool in $already_imported; 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
|
|
IFS="$OLD_IFS"
|
|
|
|
[ -n "$init" ] && zfs_log_end_msg "$RET"
|
|
|
|
return "$RET"
|
|
}
|
|
|
|
# Output the status and list of pools
|
|
do_status()
|
|
{
|
|
check_module_loaded "zfs" || 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 "zfs"
|
|
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 "zfs" || 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
|