xref: /freebsd/sys/contrib/openzfs/etc/zfs/zfs-functions.in (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1*61145dc2SMartin Matuska# SPDX-License-Identifier: BSD-2-Clause
2681ce946SMartin Matuska# This is a script with common functions etc used by zfs-import, zfs-load-key,
3681ce946SMartin Matuska# zfs-mount, zfs-share and zfs-zed.
4eda14cbcSMatt Macy#
5eda14cbcSMatt Macy# It is _NOT_ to be called independently
6eda14cbcSMatt Macy#
7eda14cbcSMatt Macy# Released under the 2-clause BSD license.
8eda14cbcSMatt Macy#
916038816SMartin Matuska# This script is based on debian/zfsutils.zfs.init from the
1016038816SMartin Matuska# Debian GNU/kFreeBSD zfsutils 8.1-3 package, written by Aurelien Jarno.
11eda14cbcSMatt Macy
12eda14cbcSMatt MacyPATH=/sbin:/bin:/usr/bin:/usr/sbin
13eda14cbcSMatt Macy
14eda14cbcSMatt Macy# Source function library
15eda14cbcSMatt Macyif [ -f /etc/rc.d/init.d/functions ]; then
1616038816SMartin Matuska	# RedHat and derivatives
17eda14cbcSMatt Macy	. /etc/rc.d/init.d/functions
18eda14cbcSMatt Macyelif [ -L /etc/init.d/functions.sh ]; then
19eda14cbcSMatt Macy	# Gentoo
20eda14cbcSMatt Macy	. /etc/init.d/functions.sh
21eda14cbcSMatt Macyelif [ -f /lib/lsb/init-functions ]; then
2216038816SMartin Matuska	# LSB, Debian, and derivatives
23eda14cbcSMatt Macy	. /lib/lsb/init-functions
24eda14cbcSMatt Macyfi
25eda14cbcSMatt Macy
26eda14cbcSMatt Macy# Of course the functions we need are called differently
27eda14cbcSMatt Macy# on different distributions - it would be way too easy
28eda14cbcSMatt Macy# otherwise!!
29eda14cbcSMatt Macyif type log_failure_msg > /dev/null 2>&1 ; then
30eda14cbcSMatt Macy	# LSB functions - fall through
31eda14cbcSMatt Macy	zfs_log_begin_msg() { log_begin_msg "$1"; }
32eda14cbcSMatt Macy	zfs_log_end_msg() { log_end_msg "$1"; }
33eda14cbcSMatt Macy	zfs_log_failure_msg() { log_failure_msg "$1"; }
34eda14cbcSMatt Macy	zfs_log_progress_msg() { log_progress_msg "$1"; }
35eda14cbcSMatt Macyelif type success > /dev/null 2>&1 ; then
36eda14cbcSMatt Macy	# Fedora/RedHat functions
37eda14cbcSMatt Macy	zfs_set_ifs() {
38eda14cbcSMatt Macy		# For some reason, the init function library have a problem
39eda14cbcSMatt Macy		# with a changed IFS, so this function goes around that.
40eda14cbcSMatt Macy		local tIFS="$1"
41eda14cbcSMatt Macy		if [ -n "$tIFS" ]
42eda14cbcSMatt Macy		then
43eda14cbcSMatt Macy			TMP_IFS="$IFS"
44eda14cbcSMatt Macy			IFS="$tIFS"
45eda14cbcSMatt Macy		fi
46eda14cbcSMatt Macy	}
47eda14cbcSMatt Macy
4816038816SMartin Matuska	zfs_log_begin_msg() { printf "%s" "$1 "; }
49eda14cbcSMatt Macy	zfs_log_end_msg() {
50e92ffd9bSMartin Matuska		# shellcheck disable=SC2154
51eda14cbcSMatt Macy		zfs_set_ifs "$OLD_IFS"
52eda14cbcSMatt Macy		if [ "$1" -eq 0 ]; then
53eda14cbcSMatt Macy			success
54eda14cbcSMatt Macy		else
55eda14cbcSMatt Macy			failure
56eda14cbcSMatt Macy		fi
57eda14cbcSMatt Macy		echo
58eda14cbcSMatt Macy		zfs_set_ifs "$TMP_IFS"
59eda14cbcSMatt Macy	}
60eda14cbcSMatt Macy	zfs_log_failure_msg() {
61eda14cbcSMatt Macy		zfs_set_ifs "$OLD_IFS"
62eda14cbcSMatt Macy		failure
63eda14cbcSMatt Macy		echo
64eda14cbcSMatt Macy		zfs_set_ifs "$TMP_IFS"
65eda14cbcSMatt Macy	}
6616038816SMartin Matuska	zfs_log_progress_msg() { printf "%s" "$""$1"; }
67eda14cbcSMatt Macyelif type einfo > /dev/null 2>&1 ; then
68eda14cbcSMatt Macy	# Gentoo functions
69eda14cbcSMatt Macy	zfs_log_begin_msg() { ebegin "$1"; }
70eda14cbcSMatt Macy	zfs_log_end_msg() { eend "$1"; }
71eda14cbcSMatt Macy	zfs_log_failure_msg() { eend "$1"; }
7216038816SMartin Matuska#	zfs_log_progress_msg() { printf "%s" "$1"; }
7316038816SMartin Matuska	zfs_log_progress_msg() { :; }
74eda14cbcSMatt Macyelse
75eda14cbcSMatt Macy	# Unknown - simple substitutes.
7616038816SMartin Matuska	zfs_log_begin_msg() { printf "%s" "$1"; }
77eda14cbcSMatt Macy	zfs_log_end_msg() {
78eda14cbcSMatt Macy		ret=$1
79eda14cbcSMatt Macy		if [ "$ret" -ge 1 ]; then
80eda14cbcSMatt Macy			echo " failed!"
81eda14cbcSMatt Macy		else
82eda14cbcSMatt Macy			echo " success"
83eda14cbcSMatt Macy		fi
84eda14cbcSMatt Macy		return "$ret"
85eda14cbcSMatt Macy	}
86eda14cbcSMatt Macy	zfs_log_failure_msg() { echo "$1"; }
8716038816SMartin Matuska	zfs_log_progress_msg() { printf "%s" "$1"; }
88eda14cbcSMatt Macyfi
89eda14cbcSMatt Macy
90eda14cbcSMatt Macy# Paths to what we need
91eda14cbcSMatt MacyZFS="@sbindir@/zfs"
92eda14cbcSMatt MacyZED="@sbindir@/zed"
93eda14cbcSMatt MacyZPOOL="@sbindir@/zpool"
94eda14cbcSMatt MacyZPOOL_CACHE="@sysconfdir@/zfs/zpool.cache"
95eda14cbcSMatt Macy
96eda14cbcSMatt Macy# Sensible defaults
97681ce946SMartin MatuskaZFS_LOAD_KEY='yes'
98681ce946SMartin MatuskaZFS_UNLOAD_KEY='no'
99eda14cbcSMatt MacyZFS_MOUNT='yes'
100eda14cbcSMatt MacyZFS_UNMOUNT='yes'
101eda14cbcSMatt MacyZFS_SHARE='yes'
102eda14cbcSMatt MacyZFS_UNSHARE='yes'
103eda14cbcSMatt Macy
104eda14cbcSMatt Macy# Source zfs configuration, overriding the defaults
105eda14cbcSMatt Macyif [ -f @initconfdir@/zfs ]; then
106eda14cbcSMatt Macy	. @initconfdir@/zfs
107eda14cbcSMatt Macyfi
108eda14cbcSMatt Macy
109eda14cbcSMatt Macy# ----------------------------------------------------
110eda14cbcSMatt Macy
111681ce946SMartin Matuskaexport ZFS ZED ZPOOL ZPOOL_CACHE ZFS_LOAD_KEY ZFS_UNLOAD_KEY ZFS_MOUNT ZFS_UNMOUNT \
112681ce946SMartin Matuska    ZFS_SHARE ZFS_UNSHARE
113eda14cbcSMatt Macy
114eda14cbcSMatt Macyzfs_action()
115eda14cbcSMatt Macy{
116eda14cbcSMatt Macy	local MSG="$1";	shift
117eda14cbcSMatt Macy	local CMD="$*"
118eda14cbcSMatt Macy	local ret
119eda14cbcSMatt Macy
120eda14cbcSMatt Macy	zfs_log_begin_msg "$MSG "
121eda14cbcSMatt Macy	$CMD
122eda14cbcSMatt Macy	ret=$?
123eda14cbcSMatt Macy	if [ "$ret" -eq 0 ]; then
124e92ffd9bSMartin Matuska		zfs_log_end_msg "$ret"
125eda14cbcSMatt Macy	else
126e92ffd9bSMartin Matuska		zfs_log_failure_msg "$ret"
127eda14cbcSMatt Macy	fi
128eda14cbcSMatt Macy
129e92ffd9bSMartin Matuska	return "$ret"
130eda14cbcSMatt Macy}
131eda14cbcSMatt Macy
132eda14cbcSMatt Macy# Returns
133eda14cbcSMatt Macy#   0 if daemon has been started
134eda14cbcSMatt Macy#   1 if daemon was already running
135eda14cbcSMatt Macy#   2 if daemon could not be started
136eda14cbcSMatt Macy#   3 if unsupported
137eda14cbcSMatt Macy#
138eda14cbcSMatt Macyzfs_daemon_start()
139eda14cbcSMatt Macy{
140eda14cbcSMatt Macy	local PIDFILE="$1";	shift
141eda14cbcSMatt Macy	local DAEMON_BIN="$1";	shift
142eda14cbcSMatt Macy
143eda14cbcSMatt Macy	if type start-stop-daemon > /dev/null 2>&1 ; then
144eda14cbcSMatt Macy		# LSB functions
145eda14cbcSMatt Macy		start-stop-daemon --start --quiet --pidfile "$PIDFILE" \
146eda14cbcSMatt Macy		    --exec "$DAEMON_BIN" --test > /dev/null || return 1
147eda14cbcSMatt Macy
14816038816SMartin Matuska		# shellcheck disable=SC2086
149eda14cbcSMatt Macy		start-stop-daemon --start --quiet --exec "$DAEMON_BIN" -- \
15016038816SMartin Matuska		    "$@" || return 2
151eda14cbcSMatt Macy
15216038816SMartin Matuska		# On Debian, there's a 'sendsigs' script that will
153eda14cbcSMatt Macy		# kill basically everything quite early and zed is stopped
154eda14cbcSMatt Macy		# much later than that. We don't want zed to be among them,
155eda14cbcSMatt Macy		# so add the zed pid to list of pids to ignore.
15616038816SMartin Matuska		if [ -f "$PIDFILE" ] && [ -d /run/sendsigs.omit.d ]
157eda14cbcSMatt Macy		then
158eda14cbcSMatt Macy			ln -sf "$PIDFILE" /run/sendsigs.omit.d/zed
159eda14cbcSMatt Macy		fi
160eda14cbcSMatt Macy	elif type daemon > /dev/null 2>&1 ; then
161eda14cbcSMatt Macy		# Fedora/RedHat functions
16216038816SMartin Matuska		# shellcheck disable=SC2086
16316038816SMartin Matuska		daemon --pidfile "$PIDFILE" "$DAEMON_BIN" "$@"
164eda14cbcSMatt Macy		return $?
165eda14cbcSMatt Macy	else
166eda14cbcSMatt Macy		# Unsupported
167eda14cbcSMatt Macy		return 3
168eda14cbcSMatt Macy	fi
169eda14cbcSMatt Macy
170eda14cbcSMatt Macy	return 0
171eda14cbcSMatt Macy}
172eda14cbcSMatt Macy
173eda14cbcSMatt Macy# Returns
174eda14cbcSMatt Macy#   0 if daemon has been stopped
175eda14cbcSMatt Macy#   1 if daemon was already stopped
176eda14cbcSMatt Macy#   2 if daemon could not be stopped
177eda14cbcSMatt Macy#   3 if unsupported
178eda14cbcSMatt Macy#
179eda14cbcSMatt Macyzfs_daemon_stop()
180eda14cbcSMatt Macy{
181eda14cbcSMatt Macy	local PIDFILE="$1"
182eda14cbcSMatt Macy	local DAEMON_BIN="$2"
183eda14cbcSMatt Macy	local DAEMON_NAME="$3"
184eda14cbcSMatt Macy
185eda14cbcSMatt Macy	if type start-stop-daemon > /dev/null 2>&1 ; then
186eda14cbcSMatt Macy		# LSB functions
187eda14cbcSMatt Macy		start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
188eda14cbcSMatt Macy		    --pidfile "$PIDFILE" --name "$DAEMON_NAME"
18916038816SMartin Matuska		ret="$?"
19016038816SMartin Matuska		[ "$ret" = 0 ] && rm -f "$PIDFILE"
191eda14cbcSMatt Macy
19216038816SMartin Matuska		return "$ret"
193eda14cbcSMatt Macy	elif type killproc > /dev/null 2>&1 ; then
194eda14cbcSMatt Macy		# Fedora/RedHat functions
195eda14cbcSMatt Macy		killproc -p "$PIDFILE" "$DAEMON_NAME"
19616038816SMartin Matuska		ret="$?"
19716038816SMartin Matuska		[ "$ret" = 0 ] && rm -f "$PIDFILE"
198eda14cbcSMatt Macy
19916038816SMartin Matuska		return "$ret"
200eda14cbcSMatt Macy	else
201eda14cbcSMatt Macy		# Unsupported
202eda14cbcSMatt Macy		return 3
203eda14cbcSMatt Macy	fi
204eda14cbcSMatt Macy
205eda14cbcSMatt Macy	return 0
206eda14cbcSMatt Macy}
207eda14cbcSMatt Macy
208eda14cbcSMatt Macy# Returns status
209eda14cbcSMatt Macyzfs_daemon_status()
210eda14cbcSMatt Macy{
211eda14cbcSMatt Macy	local PIDFILE="$1"
212eda14cbcSMatt Macy	local DAEMON_BIN="$2"
213eda14cbcSMatt Macy	local DAEMON_NAME="$3"
214eda14cbcSMatt Macy
215eda14cbcSMatt Macy	if type status_of_proc > /dev/null 2>&1 ; then
216eda14cbcSMatt Macy		# LSB functions
217eda14cbcSMatt Macy		status_of_proc "$DAEMON_NAME" "$DAEMON_BIN"
218eda14cbcSMatt Macy		return $?
219eda14cbcSMatt Macy	elif type status > /dev/null 2>&1 ; then
220eda14cbcSMatt Macy		# Fedora/RedHat functions
221eda14cbcSMatt Macy		status -p "$PIDFILE" "$DAEMON_NAME"
222eda14cbcSMatt Macy		return $?
223eda14cbcSMatt Macy	else
224eda14cbcSMatt Macy		# Unsupported
225eda14cbcSMatt Macy		return 3
226eda14cbcSMatt Macy	fi
227eda14cbcSMatt Macy
228eda14cbcSMatt Macy	return 0
229eda14cbcSMatt Macy}
230eda14cbcSMatt Macy
231eda14cbcSMatt Macyzfs_daemon_reload()
232eda14cbcSMatt Macy{
233eda14cbcSMatt Macy	local PIDFILE="$1"
234eda14cbcSMatt Macy	local DAEMON_NAME="$2"
235eda14cbcSMatt Macy
236eda14cbcSMatt Macy	if type start-stop-daemon > /dev/null 2>&1 ; then
237eda14cbcSMatt Macy		# LSB functions
238eda14cbcSMatt Macy		start-stop-daemon --stop --signal 1 --quiet \
239eda14cbcSMatt Macy		    --pidfile "$PIDFILE" --name "$DAEMON_NAME"
240eda14cbcSMatt Macy		return $?
241eda14cbcSMatt Macy	elif type killproc > /dev/null 2>&1 ; then
242eda14cbcSMatt Macy		# Fedora/RedHat functions
243eda14cbcSMatt Macy		killproc -p "$PIDFILE" "$DAEMON_NAME" -HUP
244eda14cbcSMatt Macy		return $?
245eda14cbcSMatt Macy	else
246eda14cbcSMatt Macy		# Unsupported
247eda14cbcSMatt Macy		return 3
248eda14cbcSMatt Macy	fi
249eda14cbcSMatt Macy
250eda14cbcSMatt Macy	return 0
251eda14cbcSMatt Macy}
252eda14cbcSMatt Macy
253eda14cbcSMatt Macyzfs_installed()
254eda14cbcSMatt Macy{
255eda14cbcSMatt Macy	if [ ! -x "$ZPOOL" ]; then
256eda14cbcSMatt Macy		return 1
257eda14cbcSMatt Macy	else
258eda14cbcSMatt Macy		# Test if it works (will catch missing/broken libs etc)
259eda14cbcSMatt Macy		"$ZPOOL" -? > /dev/null 2>&1
260eda14cbcSMatt Macy		return $?
261eda14cbcSMatt Macy	fi
262eda14cbcSMatt Macy
263eda14cbcSMatt Macy	if [ ! -x "$ZFS" ]; then
264eda14cbcSMatt Macy		return 2
265eda14cbcSMatt Macy	else
266eda14cbcSMatt Macy		# Test if it works (will catch missing/broken libs etc)
267eda14cbcSMatt Macy		"$ZFS" -? > /dev/null 2>&1
268eda14cbcSMatt Macy		return $?
269eda14cbcSMatt Macy	fi
270eda14cbcSMatt Macy
271eda14cbcSMatt Macy	return 0
272eda14cbcSMatt Macy}
273eda14cbcSMatt Macy
274eda14cbcSMatt Macy# Trigger udev and wait for it to settle.
275eda14cbcSMatt Macyudev_trigger()
276eda14cbcSMatt Macy{
277eda14cbcSMatt Macy	if [ -x /sbin/udevadm ]; then
278eda14cbcSMatt Macy		/sbin/udevadm trigger --action=change --subsystem-match=block
279eda14cbcSMatt Macy		/sbin/udevadm settle
280eda14cbcSMatt Macy	elif [ -x /sbin/udevsettle ]; then
281eda14cbcSMatt Macy		/sbin/udevtrigger
282eda14cbcSMatt Macy		/sbin/udevsettle
283eda14cbcSMatt Macy	fi
284eda14cbcSMatt Macy}
285eda14cbcSMatt Macy
286eda14cbcSMatt Macy# Do a lot of checks to make sure it's 'safe' to continue with the import.
287eda14cbcSMatt Macychecksystem()
288eda14cbcSMatt Macy{
289eda14cbcSMatt Macy	if grep -qiE '(^|[^\\](\\\\)* )zfs=(off|no|0)( |$)' /proc/cmdline;
290eda14cbcSMatt Macy	then
291eda14cbcSMatt Macy		# Called with zfs=(off|no|0) - bail because we don't
292eda14cbcSMatt Macy		# want anything import, mounted or shared.
293eda14cbcSMatt Macy		# HOWEVER, only do this if we're called at the boot up
294eda14cbcSMatt Macy		# (from init), not if we're running interactively (as in
295eda14cbcSMatt Macy		# from the shell - we know what we're doing).
29616038816SMartin Matuska		# shellcheck disable=SC2154
297eda14cbcSMatt Macy		[ -n "$init" ] && exit 3
298eda14cbcSMatt Macy	fi
299eda14cbcSMatt Macy
300eda14cbcSMatt Macy	# Check if ZFS is installed.
301eda14cbcSMatt Macy	zfs_installed || return 5
302eda14cbcSMatt Macy
303eda14cbcSMatt Macy	# Just make sure that /dev/zfs is created.
304eda14cbcSMatt Macy	udev_trigger
305eda14cbcSMatt Macy
306eda14cbcSMatt Macy	return 0
307eda14cbcSMatt Macy}
308eda14cbcSMatt Macy
309eda14cbcSMatt Macyget_root_pool()
310eda14cbcSMatt Macy{
31116038816SMartin Matuska	# shellcheck disable=SC2046
312eda14cbcSMatt Macy	set -- $(mount | grep ' on / ')
313eda14cbcSMatt Macy	[ "$5" = "zfs" ] && echo "${1%%/*}"
314eda14cbcSMatt Macy}
315eda14cbcSMatt Macy
316eda14cbcSMatt Macy# Check if a variable is 'yes' (any case) or '1'
317eda14cbcSMatt Macy# Returns TRUE if set.
318eda14cbcSMatt Macycheck_boolean()
319eda14cbcSMatt Macy{
320eda14cbcSMatt Macy	local var="$1"
321eda14cbcSMatt Macy
322eda14cbcSMatt Macy	echo "$var" | grep -Eiq "^yes$|^on$|^true$|^1$" && return 0 || return 1
323eda14cbcSMatt Macy}
324eda14cbcSMatt Macy
325eda14cbcSMatt Macycheck_module_loaded()
326eda14cbcSMatt Macy{
327eda14cbcSMatt Macy	module="$1"
328eda14cbcSMatt Macy
329eda14cbcSMatt Macy	[ -r "/sys/module/${module}/version" ] && return 0 || return 1
330eda14cbcSMatt Macy}
331eda14cbcSMatt Macy
332eda14cbcSMatt Macyload_module()
333eda14cbcSMatt Macy{
334eda14cbcSMatt Macy	module="$1"
335eda14cbcSMatt Macy
336eda14cbcSMatt Macy	# Load the zfs module stack
337eda14cbcSMatt Macy	if ! check_module_loaded "$module"; then
338eda14cbcSMatt Macy		if ! /sbin/modprobe "$module"; then
339eda14cbcSMatt Macy			return 5
340eda14cbcSMatt Macy		fi
341eda14cbcSMatt Macy	fi
342eda14cbcSMatt Macy	return 0
343eda14cbcSMatt Macy}
344eda14cbcSMatt Macy
345eda14cbcSMatt Macy# first parameter is a regular expression that filters mtab
346eda14cbcSMatt Macyread_mtab()
347eda14cbcSMatt Macy{
348eda14cbcSMatt Macy	local match="$1"
34916038816SMartin Matuska	local fs mntpnt fstype opts rest
350eda14cbcSMatt Macy
351eda14cbcSMatt Macy	# Unset all MTAB_* variables
35216038816SMartin Matuska	# shellcheck disable=SC2046
353dae17134SMartin Matuska	unset $(env | sed -e '/^MTAB_/!d' -e 's,=.*,,')
354eda14cbcSMatt Macy
355eda14cbcSMatt Macy	while read -r fs mntpnt fstype opts rest; do
356eda14cbcSMatt Macy		if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then
357eda14cbcSMatt Macy			# * Fix problems (!?) in the mounts file. It will record
358eda14cbcSMatt Macy			#   'rpool 1' as 'rpool\0401' instead of 'rpool\00401'
359eda14cbcSMatt Macy			#   which seems to be the correct (at least as far as
360eda14cbcSMatt Macy			#   'printf' is concerned).
361eda14cbcSMatt Macy			# * We need to use the external echo, because the
362eda14cbcSMatt Macy			#   internal one would interpret the backslash code
363eda14cbcSMatt Macy			#   (incorrectly), giving us a  instead.
36416038816SMartin Matuska			mntpnt=$(/bin/echo "$mntpnt" | sed 's,\\0,\\00,g')
36516038816SMartin Matuska			fs=$(/bin/echo "$fs" | sed 's,\\0,\\00,')
366eda14cbcSMatt Macy
367eda14cbcSMatt Macy			# Remove 'unwanted' characters.
368dae17134SMartin Matuska			mntpnt=$(printf '%b' "$mntpnt" | tr -d '/. -')
369dae17134SMartin Matuska			fs=$(printf '%b' "$fs")
370eda14cbcSMatt Macy
371eda14cbcSMatt Macy			# Set the variable.
37216038816SMartin Matuska			eval export "MTAB_$mntpnt=\"$fs\""
373eda14cbcSMatt Macy		fi
374eda14cbcSMatt Macy	done < /proc/self/mounts
375eda14cbcSMatt Macy}
376eda14cbcSMatt Macy
377eda14cbcSMatt Macyin_mtab()
378eda14cbcSMatt Macy{
379eda14cbcSMatt Macy	local mntpnt="$1"
380eda14cbcSMatt Macy	# Remove 'unwanted' characters.
381dae17134SMartin Matuska	mntpnt=$(printf '%b' "$mntpnt" | tr -d '/. -')
382eda14cbcSMatt Macy	local var
383eda14cbcSMatt Macy
38416038816SMartin Matuska	var="$(eval echo "MTAB_$mntpnt")"
385eda14cbcSMatt Macy	[ "$(eval echo "$""$var")" != "" ]
386eda14cbcSMatt Macy	return "$?"
387eda14cbcSMatt Macy}
388eda14cbcSMatt Macy
389eda14cbcSMatt Macy# first parameter is a regular expression that filters fstab
390eda14cbcSMatt Macyread_fstab()
391eda14cbcSMatt Macy{
392eda14cbcSMatt Macy	local match="$1"
39316038816SMartin Matuska	local i var
394eda14cbcSMatt Macy
395eda14cbcSMatt Macy	# Unset all FSTAB_* variables
39616038816SMartin Matuska	# shellcheck disable=SC2046
397dae17134SMartin Matuska	unset $(env | sed -e '/^FSTAB_/!d' -e 's,=.*,,')
398eda14cbcSMatt Macy
399eda14cbcSMatt Macy	i=0
400eda14cbcSMatt Macy	while read -r fs mntpnt fstype opts; do
40116038816SMartin Matuska		echo "$fs" | grep -qE '^#|^$' && continue
40216038816SMartin Matuska		echo "$mntpnt" | grep -qE '^none|^swap' && continue
40316038816SMartin Matuska		echo "$fstype" | grep -qE '^swap' && continue
404eda14cbcSMatt Macy
405eda14cbcSMatt Macy		if echo "$fs $mntpnt $fstype $opts" | grep -qE "$match"; then
40616038816SMartin Matuska			eval export "FSTAB_dev_$i=$fs"
407dae17134SMartin Matuska			fs=$(printf '%b' "$fs" | tr '/' '_')
40816038816SMartin Matuska			eval export "FSTAB_$i=$mntpnt"
409eda14cbcSMatt Macy
410eda14cbcSMatt Macy			i=$((i + 1))
411eda14cbcSMatt Macy		fi
412eda14cbcSMatt Macy	done < /etc/fstab
413eda14cbcSMatt Macy}
414eda14cbcSMatt Macy
415eda14cbcSMatt Macyin_fstab()
416eda14cbcSMatt Macy{
417eda14cbcSMatt Macy	local var
418eda14cbcSMatt Macy
41916038816SMartin Matuska	var="$(eval echo "FSTAB_$1")"
420eda14cbcSMatt Macy	[ "${var}" != "" ]
421eda14cbcSMatt Macy	return $?
422eda14cbcSMatt Macy}
423eda14cbcSMatt Macy
424eda14cbcSMatt Macyis_mounted()
425eda14cbcSMatt Macy{
426eda14cbcSMatt Macy	local mntpt="$1"
42716038816SMartin Matuska	local mp
428eda14cbcSMatt Macy
42916038816SMartin Matuska	while read -r _ mp _; do
43016038816SMartin Matuska		[ "$mp" = "$mntpt" ] && return 0
43116038816SMartin Matuska	done < /proc/self/mounts
43216038816SMartin Matuska
433eda14cbcSMatt Macy	return 1
434eda14cbcSMatt Macy}
435