mkdir -p './cups/interfaces'
mkdir -p './cups/ssl'
mkdir -p './dbus-1/session.d'
+mkdir -p './docker'
mkdir -p './glvnd/egl_vendor.d'
mkdir -p './gss/mech.d'
mkdir -p './guest-session'
maybe chmod 0644 'cron.d/anacron'
maybe chmod 0644 'cron.d/mdadm'
maybe chmod 0644 'cron.d/timeshift-hourly'
+maybe chmod 0644 'cron.d/zfsutils-linux'
maybe chmod 0755 'cron.daily'
maybe chmod 0644 'cron.daily/.placeholder'
maybe chmod 0755 'cron.daily/0anacron'
maybe chmod 0644 'default/amd64-microcode'
maybe chmod 0644 'default/anacron'
maybe chmod 0644 'default/apport'
+maybe chmod 0644 'default/aufs'
maybe chmod 0644 'default/avahi-daemon'
maybe chmod 0644 'default/bind9'
maybe chmod 0644 'default/bridge-utils'
maybe chmod 0644 'default/virtlockd'
maybe chmod 0644 'default/virtlogd'
maybe chmod 0644 'default/winbind'
+maybe chmod 0644 'default/zfs'
maybe chmod 0644 'deluser.conf'
maybe chmod 0755 'depmod.d'
maybe chmod 0644 'depmod.d/ubuntu.conf'
maybe chmod 0755 'doc-base'
maybe chmod 0755 'doc-base/documents'
maybe chmod 0644 'doc-base/documents/README'
+maybe chmod 0755 'docker'
maybe chmod 0755 'dpkg'
maybe chmod 0644 'dpkg/dpkg.cfg'
maybe chmod 0755 'dpkg/dpkg.cfg.d'
maybe chmod 0755 'init.d/avahi-daemon'
maybe chmod 0755 'init.d/bind9'
maybe chmod 0755 'init.d/bluetooth'
+maybe chmod 0755 'init.d/cgroupfs-mount'
maybe chmod 0755 'init.d/chrony'
maybe chmod 0755 'init.d/console-setup.sh'
maybe chmod 0755 'init.d/cron'
maybe chmod 0440 'sudoers.d/README'
maybe chmod 0440 'sudoers.d/ctdb'
maybe chmod 0440 'sudoers.d/mintupdate'
+maybe chmod 0440 'sudoers.d/zfs'
maybe chmod 0644 'sysctl.conf'
maybe chmod 0755 'sysctl.d'
maybe chmod 0644 'sysctl.d/10-console-messages.conf'
maybe chmod 0755 'systemd/system/sockets.target.wants'
maybe chmod 0755 'systemd/system/sysinit.target.wants'
maybe chmod 0755 'systemd/system/timers.target.wants'
+maybe chmod 0755 'systemd/system/zfs-import.target.wants'
+maybe chmod 0755 'systemd/system/zfs-mount.service.wants'
+maybe chmod 0755 'systemd/system/zfs-share.service.wants'
+maybe chmod 0755 'systemd/system/zfs.target.wants'
maybe chmod 0644 'systemd/timesyncd.conf'
maybe chmod 0755 'systemd/user'
maybe chmod 0644 'systemd/user.conf'
maybe chmod 0644 'xrdb/Motif.ad'
maybe chmod 0644 'xrdb/Tk.ad'
maybe chmod 0644 'xrdb/Xaw.ad'
+maybe chmod 0755 'zfs'
+maybe chmod 0755 'zfs/zed.d'
+maybe chmod 0644 'zfs/zed.d/zed-functions.sh'
+maybe chmod 0644 'zfs/zed.d/zed.rc'
+maybe chmod 0644 'zfs/zfs-functions'
+maybe chmod 0755 'zfs/zpool.d'
maybe chmod 0644 'zsh_command_not_found'
--- /dev/null
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+# Scrub the second Sunday of every month.
+24 0 8-14 * * root [ $(date +\%w) -eq 0 ] && [ -x /usr/lib/zfs-linux/scrub ] && /usr/lib/zfs-linux/scrub
--- /dev/null
+# aufs variables for shell scripts
+AUFS_VERSION=4.13-20170911
+AUFS_SUPER_MAGIC=1635083891
+AUFS_SUPER_MAGIC_HEX=0x61756673
+AUFS_ROOT_INO=2
+AUFS_WH_PFX=.wh.
+AUFS_WH_PFX2=.wh..wh.
+AUFS_MAX_NAMELEN=242
+AUFS_WKQ_NAME=aufsd
+AUFS_WH_DIROPQ=.wh..wh..opq
+AUFS_WH_BASE=.wh..wh.aufs
+AUFS_WH_PLINKDIR=.wh..wh.plnk
+AUFS_WH_ORPHDIR=.wh..wh.orph
+
+# library functions for aufs shell scripts
+
+# path in canonical representation
+# note: bash builtin "pwd -P" modies $PWD unexpectedly
+SetDir() # var dir
+{
+ cd "$2"
+ eval "$1=\"$(pwd -P)\""
+ cd "$OLDPWD"
+}
+
+# escape the unprintable characters, mainly for grep-ping /proc/mounts
+Esc() # [-e]
+{
+ sed -r -e '
+ s/\\/\\134/g
+ s/$/\\012/
+ ' |
+ tr -d '\n' |
+ sed -r -e '
+ s/ /\\040/g
+ s/\t/\\011/g
+ s/\r/\\015/g
+ s/\\012$//
+ ' |
+ { test $# -eq 1 &&
+ test "$1" = "-e" &&
+ sed -r -e 's/\\/\\\\/g' ||
+ cat; }
+ echo
+}
+
+# find a mount-entry by its mount-point
+FindMntEnt() # mntpnt
+{
+ proc_mounts=/proc/self/mounts
+ test ! -e $proc_mounts && proc_mounts=/proc/$$/mounts
+ test ! -e $proc_mounts && proc_mounts=/proc/mounts
+ fgrep \ $(echo "$1" | Esc)\ aufs\ $proc_mounts |
+ tail -n 1
+}
+
+# current mount options
+MntOpts() # mntpnt
+{
+ FindMntEnt "$1" |
+ cut -f4 -d' '
+}
+
+########################################
+
+AuDebug() # 1 | 0 [sec]
+{
+ test $1 -eq 0 && set +x
+ aufs_debug=/sys/module/aufs/parameters/debug
+ if [ -f $aufs_debug ]
+ then
+ echo $1 | sudo dd of=$aufs_debug 2> /dev/null
+ test $# -eq 2 && sleep $2
+ fi
+ test $1 -eq 1 && set -x
+ true
+}
+
+# Local variables: ;
+# mode: text;
+# End: ;
--- /dev/null
+# 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'
+
+# Run `zfs unmount -a` during system stop?
+ZFS_UNMOUNT='yes'
+
+# Run `zfs share -a` during system start?
+# nb: The shareiscsi, sharenfs, and sharesmb dataset properties.
+ZFS_SHARE='yes'
+
+# Run `zfs unshare -a` during system stop?
+ZFS_UNSHARE='yes'
+
+# By default, a verbatim import of all pools is performed at boot based on the
+# contents of the default zpool cache file. The contents of the cache are
+# managed automatically by the 'zpool import' and 'zpool export' commands.
+#
+# By setting this to 'yes', the system will instead search all devices for
+# pools and attempt to import them all at boot, even those that have been
+# exported. Under this mode, the search path can be controlled by the
+# ZPOOL_IMPORT_PATH variable and a list of pools that should not be imported
+# can be listed in the ZFS_POOL_EXCEPTIONS variable.
+#
+# Note that importing all visible pools may include pools that you don't
+# expect, such as those on removable devices and SANs, and those pools may
+# proceed to mount themselves in places you do not want them to. The results
+# can be unpredictable and possibly dangerous. Only enable this option if you
+# understand this risk and have complete physical control over your system and
+# SAN to prevent the insertion of malicious pools.
+ZPOOL_IMPORT_ALL_VISIBLE='no'
+
+# Specify specific path(s) to look for device nodes and/or links for the
+# pool import(s). See zpool(8) for more information about this variable.
+# It supersedes the old USE_DISK_BY_ID which indicated that it would only
+# try '/dev/disk/by-id'.
+# The old variable will still work in the code, but is deprecated.
+#ZPOOL_IMPORT_PATH="/dev/disk/by-vdev:/dev/disk/by-id"
+
+# List of pools that should NOT be imported at boot
+# when ZPOOL_IMPORT_ALL_VISIBLE is 'yes'.
+# This is a space separated list.
+#ZFS_POOL_EXCEPTIONS="test2"
+
+# List of pools that SHOULD be imported at boot by the initramfs
+# instead of trying to import all available pools. If this is set
+# then ZFS_POOL_EXCEPTIONS is ignored.
+# Only applicable for Debian GNU/Linux {dkms,initramfs}.
+# This is a semi-colon separated list.
+#ZFS_POOL_IMPORT="pool1;pool2"
+
+# Should the datasets be mounted verbosely?
+# A mount counter will be used when mounting if set to 'yes'.
+VERBOSE_MOUNT='no'
+
+# Should we allow overlay mounts?
+# This is standard in Linux, but not ZFS which comes from Solaris where this
+# 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 "/etc/zfs/zpool.cache".
+#ZPOOL_CACHE="/etc/zfs/zpool.cache"
+#
+# Setting ZPOOL_CACHE to an empty string ('') AND setting ZPOOL_IMPORT_OPTS to
+# "-c /etc/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 /etc/zfs/zpool.cache"
+#ZPOOL_CACHE=""
+
+# Any additional option to the 'zfs mount' command line?
+# Include '-o' for each option wanted.
+MOUNT_EXTRA_OPTIONS=""
+
+# Build kernel modules with the --enable-debug switch?
+# Only applicable for Debian GNU/Linux {dkms,initramfs}.
+ZFS_DKMS_ENABLE_DEBUG='no'
+
+# Keep debugging symbols in kernel modules?
+# Only applicable for Debian GNU/Linux {dkms,initramfs}.
+ZFS_DKMS_DISABLE_STRIP='no'
+
+# Wait for this many seconds in the initrd pre_mountroot?
+# This delays startup and should be '0' on most systems.
+# Only applicable for Debian GNU/Linux {dkms,initramfs}.
+ZFS_INITRD_PRE_MOUNTROOT_SLEEP='0'
+
+# Wait for this many seconds in the initrd mountroot?
+# This delays startup and should be '0' on most systems. This might help on
+# systems which have their ZFS root on a USB disk that takes just a little
+# longer to be available
+# Only applicable for Debian GNU/Linux {dkms,initramfs}.
+ZFS_INITRD_POST_MODPROBE_SLEEP='0'
+
+# List of additional datasets to mount after the root dataset is mounted?
+#
+# The init script will use the mountpoint specified in the 'mountpoint'
+# property value in the dataset to determine where it should be mounted.
+#
+# This is a space separated list, and will be mounted in the order specified,
+# so if one filesystem depends on a previous mountpoint, make sure to put
+# them in the right order.
+#
+# It is not necessary to add filesystems below the root fs here. It is
+# taken care of by the initrd script automatically. These are only for
+# additional filesystems needed. Such as /opt, /usr/local which is not
+# located under the root fs.
+# Example: If root FS is 'rpool/ROOT/rootfs', this would make sense.
+#ZFS_INITRD_ADDITIONAL_DATASETS="rpool/ROOT/usr rpool/ROOT/var"
+
+# Optional arguments for the ZFS Event Daemon (ZED).
+# See zed(8) for more information on available options.
+#ZED_ARGS="-M"
vde2-net:x:145:
nobody:x:1000:
gast:x:1126:
+docker:x:146:
ulog:x:144:
vde2-net:x:145:
nobody:x:1000:
+gast:x:1126:
vde2-net:!::
nobody:!::
gast:!::
+docker:!::
ulog:!::
vde2-net:!::
nobody:!::
+gast:!::
--- /dev/null
+#!/bin/sh
+set -e
+
+### BEGIN INIT INFO
+# Provides: cgroupfs-mount
+# Required-Start: $syslog $remote_fs
+# Required-Stop: $syslog $remote_fs
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: Set up cgroupfs mounts.
+# Description:
+# Control groups are a kernel mechanism for tracking and imposing
+# limits on resource usage on groups of tasks.
+### END INIT INFO
+
+BASE=cgroupfs-mount
+
+# Test for systemd and bail (we have to test before sourcing init-functions, or systemd hijacks us)
+# We bail because systemd already mounts cgroups sanely, so we just silently pretend we were successful in mounting them here
+if [ -d /run/systemd/system ]; then
+ exit 0
+fi
+
+# Get lsb functions
+. /lib/lsb/init-functions
+
+if [ -f /etc/default/$BASE ]; then
+ . /etc/default/$BASE
+fi
+
+# see also init_is_upstart in /lib/lsb/init-functions (which isn't available in Ubuntu 12.04, or we'd use it)
+if [ -x /sbin/initctl ] && /sbin/initctl version 2>/dev/null | /bin/grep -q upstart; then
+ log_failure_msg "$BASE is managed via upstart, try using service $BASE $1"
+ exit 1
+fi
+
+case "$1" in
+ start)
+ test -x /usr/bin/cgroupfs-mount || exit 0
+ log_begin_msg 'Mounting cgroupfs hierarchy'
+ /usr/bin/cgroupfs-mount
+ log_end_msg $?
+ ;;
+
+ stop)
+ test -x /usr/bin/cgroupfs-umount || exit 0
+ log_begin_msg 'Unmounting cgroupfs hierarchy'
+ /usr/bin/cgroupfs-umount
+ log_end_msg $?
+ ;;
+
+ restart|force-reload)
+ if mountpoint -q /sys/fs/cgroup; then
+ $0 stop
+ fi
+ exec $0 start
+ ;;
+
+ status)
+ if mountpoint -q /sys/fs/cgroup; then
+ # TODO decide whether to detect "partial mounted" status (ie, whether all available subsystems are mounted correctly)
+ log_success_msg 'cgroupfs hierarchy is mounted'
+ exit 0
+ else
+ log_failure_msg 'cgroupfs hierarchy is not mounted'
+ exit 1
+ fi
+ ;;
+
+ *)
+ echo "Usage: $0 {start|stop|restart|status}"
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+../init.d/cgroupfs-mount
\ No newline at end of file
--- /dev/null
+## Allow read-only ZoL commands to be called through sudo
+## without a password. Remove the first '#' column to enable.
+##
+## CAUTION: Any syntax error introduced here will break sudo.
+##
+## Cmnd alias specification
+#Cmnd_Alias C_ZFS = \
+# /sbin/zfs "", /sbin/zfs help *, \
+# /sbin/zfs get, /sbin/zfs get *, \
+# /sbin/zfs list, /sbin/zfs list *, \
+# /sbin/zpool "", /sbin/zpool help *, \
+# /sbin/zpool iostat, /sbin/zpool iostat *, \
+# /sbin/zpool list, /sbin/zpool list *, \
+# /sbin/zpool status, /sbin/zpool status *, \
+# /sbin/zpool upgrade, /sbin/zpool upgrade -v
+#
+## allow any user to use basic read-only ZFS commands
+#ALL ALL = (root) NOPASSWD: C_ZFS
--- /dev/null
+/lib/systemd/system/containerd.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs.target
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/docker.socket
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-zed.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-import-cache.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-import.target
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-load-module.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-mount.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-import.target
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-load-module.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-mount.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-share.service
\ No newline at end of file
--- /dev/null
+/lib/systemd/system/zfs-zed.service
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/all-syslog.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/data-notify.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/pool_import-led.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/resilver_finish-notify.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/scrub_finish-notify.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/statechange-led.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/statechange-notify.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/vdev_attach-led.sh
\ No newline at end of file
--- /dev/null
+/usr/lib/x86_64-linux-gnu/zfs/zed.d/vdev_clear-led.sh
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+# shellcheck disable=SC2039
+# zed-functions.sh
+#
+# ZED helper functions for use in ZEDLETs
+
+
+# Variable Defaults
+#
+: "${ZED_LOCKDIR:="/var/lock"}"
+: "${ZED_NOTIFY_INTERVAL_SECS:=3600}"
+: "${ZED_NOTIFY_VERBOSE:=0}"
+: "${ZED_RUNDIR:="/var/run"}"
+: "${ZED_SYSLOG_PRIORITY:="daemon.notice"}"
+: "${ZED_SYSLOG_TAG:="zed"}"
+
+ZED_FLOCK_FD=8
+
+
+# zed_check_cmd (cmd, ...)
+#
+# For each argument given, search PATH for the executable command [cmd].
+# Log a message if [cmd] is not found.
+#
+# Arguments
+# cmd: name of executable command for which to search
+#
+# Return
+# 0 if all commands are found in PATH and are executable
+# n for a count of the command executables that are not found
+#
+zed_check_cmd()
+{
+ local cmd
+ local rv=0
+
+ for cmd; do
+ if ! command -v "${cmd}" >/dev/null 2>&1; then
+ zed_log_err "\"${cmd}\" not installed"
+ rv=$((rv + 1))
+ fi
+ done
+ return "${rv}"
+}
+
+
+# zed_log_msg (msg, ...)
+#
+# Write all argument strings to the system log.
+#
+# Globals
+# ZED_SYSLOG_PRIORITY
+# ZED_SYSLOG_TAG
+#
+# Return
+# nothing
+#
+zed_log_msg()
+{
+ logger -p "${ZED_SYSLOG_PRIORITY}" -t "${ZED_SYSLOG_TAG}" -- "$@"
+}
+
+
+# zed_log_err (msg, ...)
+#
+# Write an error message to the system log. This message will contain the
+# script name, EID, and all argument strings.
+#
+# Globals
+# ZED_SYSLOG_PRIORITY
+# ZED_SYSLOG_TAG
+# ZEVENT_EID
+#
+# Return
+# nothing
+#
+zed_log_err()
+{
+ logger -p "${ZED_SYSLOG_PRIORITY}" -t "${ZED_SYSLOG_TAG}" -- "error:" \
+ "$(basename -- "$0"):""${ZEVENT_EID:+" eid=${ZEVENT_EID}:"}" "$@"
+}
+
+
+# zed_lock (lockfile, [fd])
+#
+# Obtain an exclusive (write) lock on [lockfile]. If the lock cannot be
+# immediately acquired, wait until it becomes available.
+#
+# Every zed_lock() must be paired with a corresponding zed_unlock().
+#
+# By default, flock-style locks associate the lockfile with file descriptor 8.
+# The bash manpage warns that file descriptors >9 should be used with care as
+# they may conflict with file descriptors used internally by the shell. File
+# descriptor 9 is reserved for zed_rate_limit(). If concurrent locks are held
+# within the same process, they must use different file descriptors (preferably
+# decrementing from 8); otherwise, obtaining a new lock with a given file
+# descriptor will release the previous lock associated with that descriptor.
+#
+# Arguments
+# lockfile: pathname of the lock file; the lock will be stored in
+# ZED_LOCKDIR unless the pathname contains a "/".
+# fd: integer for the file descriptor used by flock (OPTIONAL unless holding
+# concurrent locks)
+#
+# Globals
+# ZED_FLOCK_FD
+# ZED_LOCKDIR
+#
+# Return
+# nothing
+#
+zed_lock()
+{
+ local lockfile="$1"
+ local fd="${2:-${ZED_FLOCK_FD}}"
+ local umask_bak
+ local err
+
+ [ -n "${lockfile}" ] || return
+ if ! expr "${lockfile}" : '.*/' >/dev/null 2>&1; then
+ lockfile="${ZED_LOCKDIR}/${lockfile}"
+ fi
+
+ umask_bak="$(umask)"
+ umask 077
+
+ # Obtain a lock on the file bound to the given file descriptor.
+ #
+ eval "exec ${fd}> '${lockfile}'"
+ err="$(flock --exclusive "${fd}" 2>&1)"
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ]; then
+ zed_log_err "failed to lock \"${lockfile}\": ${err}"
+ fi
+
+ umask "${umask_bak}"
+}
+
+
+# zed_unlock (lockfile, [fd])
+#
+# Release the lock on [lockfile].
+#
+# Arguments
+# lockfile: pathname of the lock file
+# fd: integer for the file descriptor used by flock (must match the file
+# descriptor passed to the zed_lock function call)
+#
+# Globals
+# ZED_FLOCK_FD
+# ZED_LOCKDIR
+#
+# Return
+# nothing
+#
+zed_unlock()
+{
+ local lockfile="$1"
+ local fd="${2:-${ZED_FLOCK_FD}}"
+ local err
+
+ [ -n "${lockfile}" ] || return
+ if ! expr "${lockfile}" : '.*/' >/dev/null 2>&1; then
+ lockfile="${ZED_LOCKDIR}/${lockfile}"
+ fi
+
+ # Release the lock and close the file descriptor.
+ err="$(flock --unlock "${fd}" 2>&1)"
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ]; then
+ zed_log_err "failed to unlock \"${lockfile}\": ${err}"
+ fi
+ eval "exec ${fd}>&-"
+}
+
+
+# zed_notify (subject, pathname)
+#
+# Send a notification via all available methods.
+#
+# Arguments
+# subject: notification subject
+# pathname: pathname containing the notification message (OPTIONAL)
+#
+# Return
+# 0: notification succeeded via at least one method
+# 1: notification failed
+# 2: no notification methods configured
+#
+zed_notify()
+{
+ local subject="$1"
+ local pathname="$2"
+ local num_success=0
+ local num_failure=0
+
+ zed_notify_email "${subject}" "${pathname}"; rv=$?
+ [ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
+ [ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
+
+ zed_notify_pushbullet "${subject}" "${pathname}"; rv=$?
+ [ "${rv}" -eq 0 ] && num_success=$((num_success + 1))
+ [ "${rv}" -eq 1 ] && num_failure=$((num_failure + 1))
+
+ [ "${num_success}" -gt 0 ] && return 0
+ [ "${num_failure}" -gt 0 ] && return 1
+ return 2
+}
+
+
+# zed_notify_email (subject, pathname)
+#
+# Send a notification via email to the address specified by ZED_EMAIL_ADDR.
+#
+# Requires the mail executable to be installed in the standard PATH, or
+# ZED_EMAIL_PROG to be defined with the pathname of an executable capable of
+# reading a message body from stdin.
+#
+# Command-line options to the mail executable can be specified in
+# ZED_EMAIL_OPTS. This undergoes the following keyword substitutions:
+# - @ADDRESS@ is replaced with the space-delimited recipient email address(es)
+# - @SUBJECT@ is replaced with the notification subject
+#
+# Arguments
+# subject: notification subject
+# pathname: pathname containing the notification message (OPTIONAL)
+#
+# Globals
+# ZED_EMAIL_PROG
+# ZED_EMAIL_OPTS
+# ZED_EMAIL_ADDR
+#
+# Return
+# 0: notification sent
+# 1: notification failed
+# 2: not configured
+#
+zed_notify_email()
+{
+ local subject="$1"
+ local pathname="${2:-"/dev/null"}"
+
+ : "${ZED_EMAIL_PROG:="mail"}"
+ : "${ZED_EMAIL_OPTS:="-s '@SUBJECT@' @ADDRESS@"}"
+
+ # For backward compatibility with ZED_EMAIL.
+ if [ -n "${ZED_EMAIL}" ] && [ -z "${ZED_EMAIL_ADDR}" ]; then
+ ZED_EMAIL_ADDR="${ZED_EMAIL}"
+ fi
+ [ -n "${ZED_EMAIL_ADDR}" ] || return 2
+
+ zed_check_cmd "${ZED_EMAIL_PROG}" || return 1
+
+ [ -n "${subject}" ] || return 1
+ if [ ! -r "${pathname}" ]; then
+ zed_log_err \
+ "$(basename "${ZED_EMAIL_PROG}") cannot read \"${pathname}\""
+ return 1
+ fi
+
+ ZED_EMAIL_OPTS="$(echo "${ZED_EMAIL_OPTS}" \
+ | sed -e "s/@ADDRESS@/${ZED_EMAIL_ADDR}/g" \
+ -e "s/@SUBJECT@/${subject}/g")"
+
+ # shellcheck disable=SC2086
+ eval "${ZED_EMAIL_PROG}" ${ZED_EMAIL_OPTS} < "${pathname}" >/dev/null 2>&1
+ rv=$?
+ if [ "${rv}" -ne 0 ]; then
+ zed_log_err "$(basename "${ZED_EMAIL_PROG}") exit=${rv}"
+ return 1
+ fi
+ return 0
+}
+
+
+# zed_notify_pushbullet (subject, pathname)
+#
+# Send a notification via Pushbullet <https://www.pushbullet.com/>.
+# The access token (ZED_PUSHBULLET_ACCESS_TOKEN) identifies this client to the
+# Pushbullet server. The optional channel tag (ZED_PUSHBULLET_CHANNEL_TAG) is
+# for pushing to notification feeds that can be subscribed to; if a channel is
+# not defined, push notifications will instead be sent to all devices
+# associated with the account specified by the access token.
+#
+# Requires awk, curl, and sed executables to be installed in the standard PATH.
+#
+# References
+# https://docs.pushbullet.com/
+# https://www.pushbullet.com/security
+#
+# Arguments
+# subject: notification subject
+# pathname: pathname containing the notification message (OPTIONAL)
+#
+# Globals
+# ZED_PUSHBULLET_ACCESS_TOKEN
+# ZED_PUSHBULLET_CHANNEL_TAG
+#
+# Return
+# 0: notification sent
+# 1: notification failed
+# 2: not configured
+#
+zed_notify_pushbullet()
+{
+ local subject="$1"
+ local pathname="${2:-"/dev/null"}"
+ local msg_body
+ local msg_tag
+ local msg_json
+ local msg_out
+ local msg_err
+ local url="https://api.pushbullet.com/v2/pushes"
+
+ [ -n "${ZED_PUSHBULLET_ACCESS_TOKEN}" ] || return 2
+
+ [ -n "${subject}" ] || return 1
+ if [ ! -r "${pathname}" ]; then
+ zed_log_err "pushbullet cannot read \"${pathname}\""
+ return 1
+ fi
+
+ zed_check_cmd "awk" "curl" "sed" || return 1
+
+ # Escape the following characters in the message body for JSON:
+ # newline, backslash, double quote, horizontal tab, vertical tab,
+ # and carriage return.
+ #
+ msg_body="$(awk '{ ORS="\\n" } { gsub(/\\/, "\\\\"); gsub(/"/, "\\\"");
+ gsub(/\t/, "\\t"); gsub(/\f/, "\\f"); gsub(/\r/, "\\r"); print }' \
+ "${pathname}")"
+
+ # Push to a channel if one is configured.
+ #
+ [ -n "${ZED_PUSHBULLET_CHANNEL_TAG}" ] && msg_tag="$(printf \
+ '"channel_tag": "%s", ' "${ZED_PUSHBULLET_CHANNEL_TAG}")"
+
+ # Construct the JSON message for pushing a note.
+ #
+ msg_json="$(printf '{%s"type": "note", "title": "%s", "body": "%s"}' \
+ "${msg_tag}" "${subject}" "${msg_body}")"
+
+ # Send the POST request and check for errors.
+ #
+ msg_out="$(curl -u "${ZED_PUSHBULLET_ACCESS_TOKEN}:" -X POST "${url}" \
+ --header "Content-Type: application/json" --data-binary "${msg_json}" \
+ 2>/dev/null)"; rv=$?
+ if [ "${rv}" -ne 0 ]; then
+ zed_log_err "curl exit=${rv}"
+ return 1
+ fi
+ msg_err="$(echo "${msg_out}" \
+ | sed -n -e 's/.*"error" *:.*"message" *: *"\([^"]*\)".*/\1/p')"
+ if [ -n "${msg_err}" ]; then
+ zed_log_err "pushbullet \"${msg_err}"\"
+ return 1
+ fi
+ return 0
+}
+
+
+# zed_rate_limit (tag, [interval])
+#
+# Check whether an event of a given type [tag] has already occurred within the
+# last [interval] seconds.
+#
+# This function obtains a lock on the statefile using file descriptor 9.
+#
+# Arguments
+# tag: arbitrary string for grouping related events to rate-limit
+# interval: time interval in seconds (OPTIONAL)
+#
+# Globals
+# ZED_NOTIFY_INTERVAL_SECS
+# ZED_RUNDIR
+#
+# Return
+# 0 if the event should be processed
+# 1 if the event should be dropped
+#
+# State File Format
+# time;tag
+#
+zed_rate_limit()
+{
+ local tag="$1"
+ local interval="${2:-${ZED_NOTIFY_INTERVAL_SECS}}"
+ local lockfile="zed.zedlet.state.lock"
+ local lockfile_fd=9
+ local statefile="${ZED_RUNDIR}/zed.zedlet.state"
+ local time_now
+ local time_prev
+ local umask_bak
+ local rv=0
+
+ [ -n "${tag}" ] || return 0
+
+ zed_lock "${lockfile}" "${lockfile_fd}"
+ time_now="$(date +%s)"
+ time_prev="$(egrep "^[0-9]+;${tag}\$" "${statefile}" 2>/dev/null \
+ | tail -1 | cut -d\; -f1)"
+
+ if [ -n "${time_prev}" ] \
+ && [ "$((time_now - time_prev))" -lt "${interval}" ]; then
+ rv=1
+ else
+ umask_bak="$(umask)"
+ umask 077
+ egrep -v "^[0-9]+;${tag}\$" "${statefile}" 2>/dev/null \
+ > "${statefile}.$$"
+ echo "${time_now};${tag}" >> "${statefile}.$$"
+ mv -f "${statefile}.$$" "${statefile}"
+ umask "${umask_bak}"
+ fi
+
+ zed_unlock "${lockfile}" "${lockfile_fd}"
+ return "${rv}"
+}
+
+
+# zed_guid_to_pool (guid)
+#
+# Convert a pool GUID into its pool name (like "tank")
+# Arguments
+# guid: pool GUID (decimal or hex)
+#
+# Return
+# Pool name
+#
+zed_guid_to_pool()
+{
+ if [ -z "$1" ] ; then
+ return
+ fi
+
+ guid=$(printf "%llu" "$1")
+ if [ ! -z "$guid" ] ; then
+ $ZPOOL get -H -ovalue,name guid | awk '$1=='"$guid"' {print $2}'
+ fi
+}
--- /dev/null
+##
+# zed.rc
+#
+# This file should be owned by root and permissioned 0600.
+##
+
+##
+# Absolute path to the debug output file.
+#
+#ZED_DEBUG_LOG="/tmp/zed.debug.log"
+
+##
+# Email address of the zpool administrator for receipt of notifications;
+# multiple addresses can be specified if they are delimited by whitespace.
+# Email will only be sent if ZED_EMAIL_ADDR is defined.
+# Disabled by default; uncomment to enable.
+#
+ZED_EMAIL_ADDR="root"
+
+##
+# Name or path of executable responsible for sending notifications via email;
+# the mail program must be capable of reading a message body from stdin.
+# Email will only be sent if ZED_EMAIL_ADDR is defined.
+#
+#ZED_EMAIL_PROG="mail"
+
+##
+# Command-line options for ZED_EMAIL_PROG.
+# The string @ADDRESS@ will be replaced with the recipient email address(es).
+# The string @SUBJECT@ will be replaced with the notification subject;
+# this should be protected with quotes to prevent word-splitting.
+# Email will only be sent if ZED_EMAIL_ADDR is defined.
+#
+#ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"
+
+##
+# Default directory for zed lock files.
+#
+#ZED_LOCKDIR="/var/lock"
+
+##
+# Minimum number of seconds between notifications for a similar event.
+#
+ZED_NOTIFY_INTERVAL_SECS=3600
+
+##
+# Notification verbosity.
+# If set to 0, suppress notification if the pool is healthy.
+# If set to 1, send notification regardless of pool health.
+#
+#ZED_NOTIFY_VERBOSE=0
+
+##
+# Send notifications for 'ereport.fs.zfs.data' events.
+# Disabled by default
+#
+#ZED_NOTIFY_DATA=1
+
+##
+# Pushbullet access token.
+# This grants full access to your account -- protect it accordingly!
+# <https://www.pushbullet.com/get-started>
+# <https://www.pushbullet.com/account>
+# Disabled by default; uncomment to enable.
+#
+#ZED_PUSHBULLET_ACCESS_TOKEN=""
+
+##
+# Pushbullet channel tag for push notification feeds that can be subscribed to.
+# <https://www.pushbullet.com/my-channel>
+# If not defined, push notifications will instead be sent to all devices
+# associated with the account specified by the access token.
+# Disabled by default; uncomment to enable.
+#
+#ZED_PUSHBULLET_CHANNEL_TAG=""
+
+##
+# Default directory for zed state files.
+#
+#ZED_RUNDIR="/var/run"
+
+##
+# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for
+# device mapper and multipath devices as well. Your enclosure must be
+# supported by the Linux SES driver for this to work.
+#
+ZED_USE_ENCLOSURE_LEDS=1
+
+
+##
+# The syslog priority (e.g., specified as a "facility.level" pair).
+#
+#ZED_SYSLOG_PRIORITY="daemon.notice"
+
+##
+# The syslog tag for marking zed events.
+#
+#ZED_SYSLOG_TAG="zed"
+
--- /dev/null
+# This is a script with common functions etc used by zfs-import, zfs-mount,
+# zfs-share and zfs-zed.
+#
+# It is _NOT_ to be called independently
+#
+# 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
+
+PATH=/sbin:/bin:/usr/bin:/usr/sbin
+
+# Source function library
+if [ -f /etc/rc.d/init.d/functions ]; then
+ # RedHat and derivates
+ . /etc/rc.d/init.d/functions
+elif [ -L /etc/init.d/functions.sh ]; then
+ # Gentoo
+ . /etc/init.d/functions.sh
+elif [ -f /lib/lsb/init-functions ]; then
+ # LSB, Debian GNU/Linux and derivates
+ . /lib/lsb/init-functions
+fi
+
+# Of course the functions we need are called differently
+# on different distributions - it would be way too easy
+# otherwise!!
+if type log_failure_msg > /dev/null 2>&1 ; then
+ # LSB functions - fall through
+ zfs_log_begin_msg() { log_begin_msg "$1"; }
+ zfs_log_end_msg() { log_end_msg "$1"; }
+ zfs_log_failure_msg() { log_failure_msg "$1"; }
+ zfs_log_progress_msg() { log_progress_msg "$1"; }
+elif type success > /dev/null 2>&1 ; then
+ # Fedora/RedHat functions
+ zfs_set_ifs() {
+ # For some reason, the init function library have a problem
+ # with a changed IFS, so this function goes around that.
+ local tIFS="$1"
+ if [ -n "$tIFS" ]
+ then
+ TMP_IFS="$IFS"
+ IFS="$tIFS"
+ fi
+ }
+
+ zfs_log_begin_msg() { echo -n "$1 "; }
+ zfs_log_end_msg() {
+ zfs_set_ifs "$OLD_IFS"
+ if [ "$1" -eq 0 ]; then
+ success
+ else
+ failure
+ fi
+ echo
+ zfs_set_ifs "$TMP_IFS"
+ }
+ zfs_log_failure_msg() {
+ zfs_set_ifs "$OLD_IFS"
+ failure
+ echo
+ zfs_set_ifs "$TMP_IFS"
+ }
+ zfs_log_progress_msg() { echo -n $"$1"; }
+elif type einfo > /dev/null 2>&1 ; then
+ # Gentoo functions
+ zfs_log_begin_msg() { ebegin "$1"; }
+ zfs_log_end_msg() { eend "$1"; }
+ zfs_log_failure_msg() { eend "$1"; }
+# zfs_log_progress_msg() { echo -n "$1"; }
+ zfs_log_progress_msg() { echo -n; }
+else
+ # Unknown - simple substitues.
+ zfs_log_begin_msg() { echo -n "$1"; }
+ zfs_log_end_msg() {
+ ret=$1
+ if [ "$ret" -ge 1 ]; then
+ echo " failed!"
+ else
+ echo " success"
+ fi
+ return "$ret"
+ }
+ zfs_log_failure_msg() { echo "$1"; }
+ zfs_log_progress_msg() { echo -n "$1"; }
+fi
+
+# Paths to what we need
+ZFS="/sbin/zfs"
+ZED="/sbin/zed"
+ZPOOL="/sbin/zpool"
+ZPOOL_CACHE="/etc/zfs/zpool.cache"
+
+# Sensible defaults
+ZFS_MOUNT='yes'
+ZFS_UNMOUNT='yes'
+
+export ZFS ZED ZPOOL ZPOOL_CACHE ZFS_MOUNT ZFS_UNMOUNT
+
+# Source zfs configuration, overriding the defaults
+if [ -f /etc/default/zfs ]; then
+ . /etc/default/zfs
+fi
+
+# ----------------------------------------------------
+
+zfs_action()
+{
+ local MSG="$1"; shift
+ local CMD="$*"
+ local ret
+
+ zfs_log_begin_msg "$MSG "
+ $CMD
+ ret=$?
+ if [ "$ret" -eq 0 ]; then
+ zfs_log_end_msg $ret
+ else
+ zfs_log_failure_msg $ret
+ fi
+
+ return $ret
+}
+
+# Returns
+# 0 if daemon has been started
+# 1 if daemon was already running
+# 2 if daemon could not be started
+# 3 if unsupported
+#
+zfs_daemon_start()
+{
+ local PIDFILE="$1"; shift
+ local DAEMON_BIN="$1"; shift
+ local DAEMON_ARGS="$*"
+
+ if type start-stop-daemon > /dev/null 2>&1 ; then
+ # LSB functions
+ start-stop-daemon --start --quiet --pidfile "$PIDFILE" \
+ --exec "$DAEMON_BIN" --test > /dev/null || return 1
+
+ start-stop-daemon --start --quiet --exec "$DAEMON_BIN" -- \
+ $DAEMON_ARGS || return 2
+
+ # On Debian GNU/Linux, there's a 'sendsigs' script that will
+ # kill basically everything quite early and zed is stopped
+ # much later than that. We don't want zed to be among them,
+ # so add the zed pid to list of pids to ignore.
+ if [ -f "$PIDFILE" -a -d /run/sendsigs.omit.d ]
+ then
+ ln -sf "$PIDFILE" /run/sendsigs.omit.d/zed
+ fi
+ elif type daemon > /dev/null 2>&1 ; then
+ # Fedora/RedHat functions
+ daemon --pidfile "$PIDFILE" "$DAEMON_BIN" $DAEMON_ARGS
+ return $?
+ else
+ # Unsupported
+ return 3
+ fi
+
+ return 0
+}
+
+# Returns
+# 0 if daemon has been stopped
+# 1 if daemon was already stopped
+# 2 if daemon could not be stopped
+# 3 if unsupported
+#
+zfs_daemon_stop()
+{
+ local PIDFILE="$1"
+ local DAEMON_BIN="$2"
+ local DAEMON_NAME="$3"
+
+ if type start-stop-daemon > /dev/null 2>&1 ; then
+ # LSB functions
+ start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
+ --pidfile "$PIDFILE" --name "$DAEMON_NAME"
+ [ "$?" = 0 ] && rm -f "$PIDFILE"
+
+ return $?
+ elif type killproc > /dev/null 2>&1 ; then
+ # Fedora/RedHat functions
+ killproc -p "$PIDFILE" "$DAEMON_NAME"
+ [ "$?" = 0 ] && rm -f "$PIDFILE"
+
+ return $?
+ else
+ # Unsupported
+ return 3
+ fi
+
+ return 0
+}
+
+# Returns status
+zfs_daemon_status()
+{
+ local PIDFILE="$1"
+ local DAEMON_BIN="$2"
+ local DAEMON_NAME="$3"
+
+ if type status_of_proc > /dev/null 2>&1 ; then
+ # LSB functions
+ status_of_proc "$DAEMON_NAME" "$DAEMON_BIN"
+ return $?
+ elif type status > /dev/null 2>&1 ; then
+ # Fedora/RedHat functions
+ status -p "$PIDFILE" "$DAEMON_NAME"
+ return $?
+ else
+ # Unsupported
+ return 3
+ fi
+
+ return 0
+}
+
+zfs_daemon_reload()
+{
+ local PIDFILE="$1"
+ local DAEMON_NAME="$2"
+
+ if type start-stop-daemon > /dev/null 2>&1 ; then
+ # LSB functions
+ start-stop-daemon --stop --signal 1 --quiet \
+ --pidfile "$PIDFILE" --name "$DAEMON_NAME"
+ return $?
+ elif type killproc > /dev/null 2>&1 ; then
+ # Fedora/RedHat functions
+ killproc -p "$PIDFILE" "$DAEMON_NAME" -HUP
+ return $?
+ else
+ # Unsupported
+ return 3
+ fi
+
+ return 0
+}
+
+zfs_installed()
+{
+ if [ ! -x "$ZPOOL" ]; then
+ return 1
+ else
+ # Test if it works (will catch missing/broken libs etc)
+ "$ZPOOL" -? > /dev/null 2>&1
+ return $?
+ fi
+
+ if [ ! -x "$ZFS" ]; then
+ return 2
+ else
+ # Test if it works (will catch missing/broken libs etc)
+ "$ZFS" -? > /dev/null 2>&1
+ return $?
+ fi
+
+ return 0
+}
+
+# Trigger udev and wait for it to settle.
+udev_trigger()
+{
+ if [ -x /sbin/udevadm ]; then
+ /sbin/udevadm trigger --action=change --subsystem-match=block
+ /sbin/udevadm settle
+ elif [ -x /sbin/udevsettle ]; then
+ /sbin/udevtrigger
+ /sbin/udevsettle
+ fi
+}
+
+# Do a lot of checks to make sure it's 'safe' to continue with the import.
+checksystem()
+{
+ if grep -qiE '(^|[^\\](\\\\)* )zfs=(off|no|0)( |$)' /proc/cmdline;
+ then
+ # Called with zfs=(off|no|0) - bail because we don't
+ # want anything import, mounted or shared.
+ # HOWEVER, only do this if we're called at the boot up
+ # (from init), not if we're running interactivly (as in
+ # from the shell - we know what we're doing).
+ [ -n "$init" ] && exit 3
+ fi
+
+ # Check if ZFS is installed.
+ zfs_installed || return 5
+
+ # Just make sure that /dev/zfs is created.
+ udev_trigger
+
+ if ! [ "$(uname -m)" = "x86_64" ]; then
+ echo "Warning: You're not running 64bit. Currently native zfs in";
+ echo " Linux is only supported and tested on 64bit.";
+ # should we break here? People doing this should know what they
+ # do, thus i'm not breaking here.
+ fi
+
+ return 0
+}
+
+get_root_pool()
+{
+ set -- $(mount | grep ' on / ')
+ [ "$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"
+
+ [ -r "/sys/module/${module}/version" ] && return 0 || return 1
+}
+
+load_module()
+{
+ module="$1"
+
+ # Load the zfs module stack
+ if ! check_module_loaded "$module"; then
+ if ! /sbin/modprobe "$module"; then
+ return 5
+ fi
+ fi
+ return 0
+}
+
+# first parameter is a regular expression that filters mtab
+read_mtab()
+{
+ local match="$1"
+ local fs mntpnt fstype opts rest TMPFILE
+
+ # Unset all MTAB_* variables
+ unset $(env | grep ^MTAB_ | sed 's,=.*,,')
+
+ while read -r fs mntpnt fstype opts rest; do
+ if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then
+ # * Fix problems (!?) in the mounts file. It will record
+ # 'rpool 1' as 'rpool\0401' instead of 'rpool\00401'
+ # which seems to be the correct (at least as far as
+ # 'printf' is concerned).
+ # * We need to use the external echo, because the
+ # internal one would interpret the backslash code
+ # (incorrectly), giving us a \ 1 instead.
+ mntpnt=$(/bin/echo "$mntpnt" | sed "s,\\\0,\\\00,g")
+ fs=$(/bin/echo "$fs" | sed "s,\\\0,\\\00,")
+
+ # 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.
+ eval export MTAB_$mntpnt=\"$fs\"
+ fi
+ done < /proc/self/mounts
+}
+
+in_mtab()
+{
+ local fs="$(echo "$1" | sed 's,/,_,g')"
+ local var
+
+ var="$(eval echo MTAB_$fs)"
+ [ "$(eval echo "$""$var")" != "" ]
+ return "$?"
+}
+
+# first parameter is a regular expression that filters fstab
+read_fstab()
+{
+ local match="$1"
+ local i var TMPFILE
+
+ # Unset all FSTAB_* variables
+ unset $(env | grep ^FSTAB_ | sed 's,=.*,,')
+
+ i=0
+ while read -r fs mntpnt fstype opts; do
+ echo "$fs" | egrep -qE '^#|^$' && continue
+
+ if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then
+ eval export FSTAB_dev_$i="$fs"
+ fs=$(printf '%b\n' "$fs" | sed 's,/,_,g')
+ eval export FSTAB_$i="$mntpnt"
+
+ i=$((i + 1))
+ fi
+ done < /etc/fstab
+}
+
+in_fstab()
+{
+ local var
+
+ var="$(eval echo FSTAB_$1)"
+ [ "${var}" != "" ]
+ return $?
+}
+
+is_mounted()
+{
+ local mntpt="$1"
+ local line
+
+ mount | \
+ while read line; do
+ if echo "$line" | grep -q " on $mntpt "; then
+ return 0
+ fi
+ done
+
+ return 1
+}
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/ata_err
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/cmd_to
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/defect
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/enc
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/encdev
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/fault_led
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/health
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/hours_on
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/iostat
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/iostat-10s
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/iostat-1s
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/label
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/locate_led
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/lsblk
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/media
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/model
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/nonmed
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/off_ucor
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/pend_sec
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/pwr_cyc
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/r_proc
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/r_ucor
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/realloc
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/rep_ucor
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/serial
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/ses
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/size
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/slaves
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/slot
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/smart
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/smartx
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/temp
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/upath
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/vendor
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/w_proc
\ No newline at end of file
--- /dev/null
+/usr/lib/zfs-linux/zpool.d/w_ucor
\ No newline at end of file