xref: /freebsd/sys/contrib/openzfs/scripts/zfs-helpers.sh (revision 113e60742ef6ba5c069aa737ee57ba3c2f88b248)
1#!/bin/sh
2# shellcheck disable=SC2154
3#
4# This script is designed to facilitate in-tree development and testing
5# by installing symlinks on your system which refer to in-tree helper
6# utilities.  These helper utilities must be installed to in order to
7# exercise all ZFS functionality.  By using symbolic links and keeping
8# the scripts in-tree during development they can be easily modified
9# and those changes tracked.
10#
11# Use the following configuration option to override the installation
12# paths for these scripts.  The correct path is automatically set for
13# most distributions but you can optionally set it for your environment.
14#
15#   --with-mounthelperdir=DIR  install mount.zfs in dir [/sbin]
16#   --with-udevdir=DIR         install udev helpers [default=check]
17#   --with-udevruledir=DIR     install udev rules [default=UDEVDIR/rules.d]
18#   --sysconfdir=DIR           install zfs configuration files [PREFIX/etc]
19#
20
21BASE_DIR=${0%/*}
22SCRIPT_COMMON=common.sh
23if [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then
24	. "${BASE_DIR}/${SCRIPT_COMMON}"
25else
26	echo "Missing helper script ${SCRIPT_COMMON}" && exit 1
27fi
28
29PROG=zfs-helpers.sh
30DRYRUN="no"
31INSTALL="no"
32REMOVE="no"
33VERBOSE="no"
34
35fail() {
36	echo "${PROG}: $1" >&2
37	exit 1
38}
39
40msg() {
41	if [ "$VERBOSE" = "yes" ]; then
42		echo "$@"
43	fi
44}
45
46usage() {
47cat << EOF
48USAGE:
49$0 [-dhirv]
50
51DESCRIPTION:
52	Install/remove the ZFS helper utilities.
53
54OPTIONS:
55	-d      Dry run
56	-h      Show this message
57	-i      Install the helper utilities
58	-r      Remove the helper utilities
59	-v      Verbose
60
61$0 -iv
62$0 -r
63
64EOF
65}
66
67while getopts 'hdirv' OPTION; do
68	case $OPTION in
69	h)
70		usage
71		exit 1
72		;;
73	d)
74		DRYRUN="yes"
75		;;
76	i)
77		INSTALL="yes"
78		;;
79	r)
80		REMOVE="yes"
81		;;
82	v)
83		VERBOSE="yes"
84		;;
85	?)
86		usage
87		exit
88		;;
89	*)
90		;;
91	esac
92done
93
94if [ "$INSTALL" = "yes" ] && [ "$REMOVE" = "yes" ]; then
95	fail "Specify -i or -r but not both"
96fi
97
98if [ "$INSTALL" = "no" ] && [ "$REMOVE" = "no" ]; then
99	fail "Either -i or -r must be specified"
100fi
101
102if [ "$(id -u)" != "0" ] && [ "$DRYRUN" = "no" ]; then
103	fail "Must run as root"
104fi
105
106if [ "$INTREE" != "yes" ]; then
107	fail "Must be run in-tree"
108fi
109
110if [ "$VERBOSE" = "yes" ]; then
111	echo "--- Configuration ---"
112	echo "udevdir:          $INSTALL_UDEV_DIR"
113	echo "udevruledir:      $INSTALL_UDEV_RULE_DIR"
114	echo "mounthelperdir:   $INSTALL_MOUNT_HELPER_DIR"
115	echo "sysconfdir:       $INSTALL_SYSCONF_DIR"
116	echo "pythonsitedir:    $INSTALL_PYTHON_DIR"
117	echo "dryrun:           $DRYRUN"
118	echo
119fi
120
121install() {
122	src=$1
123	dst=$2
124
125	# We may have an old symlink pointing to different ZFS workspace.
126	# Remove the old symlink if it doesn't point to our workspace.
127	if [ -h "$dst" ] && [ "$(readlink -f """$dst""")" != "$src" ] ; then
128		echo "Removing old symlink: $dst -> $(readlink """$dst""")"
129		rm "$dst"
130	fi
131
132	if [ -h "$dst" ]; then
133		echo "Symlink exists: $dst"
134	elif [ -e "$dst" ]; then
135		echo "File exists: $dst"
136	elif ! [ -e "$src" ]; then
137		echo "Source missing: $src"
138	else
139		msg "ln -s $src $dst"
140
141		if [ "$DRYRUN" = "no" ]; then
142			DIR=${dst%/*}
143			mkdir -p "$DIR" >/dev/null 2>&1
144			ln -s "$src" "$dst"
145		fi
146	fi
147}
148
149remove() {
150	dst=$1
151
152	if [ -h "$dst" ]; then
153		msg "rm $dst"
154		rm "$dst"
155		DIR=${dst%/*}
156		rmdir "$DIR" >/dev/null 2>&1
157	elif [ -e "$dst" ]; then
158		echo "Expected symlink: $dst"
159	fi
160}
161
162if [ "${INSTALL}" = "yes" ]; then
163	for cmd in "mount.zfs" "fsck.zfs"; do
164		install "$CMD_DIR/$cmd" "$INSTALL_MOUNT_HELPER_DIR/$cmd"
165	done
166	for udev in "$UDEV_CMD_DIR/zvol_id" "$UDEV_SCRIPT_DIR/vdev_id"; do
167		install "$udev" "$INSTALL_UDEV_DIR/${udev##*/}"
168	done
169	for rule in "60-zvol.rules" "69-vdev.rules" "90-zfs.rules"; do
170		install "$UDEV_RULE_DIR/$rule" "$INSTALL_UDEV_RULE_DIR/$rule"
171	done
172	install "$ZPOOL_SCRIPT_DIR"              "$INSTALL_SYSCONF_DIR/zfs/zpool.d"
173	install "$ZPOOL_COMPAT_DIR"              "$INSTALL_PKGDATA_DIR/compatibility.d"
174	install "$CONTRIB_DIR/pyzfs/libzfs_core" "$INSTALL_PYTHON_DIR/libzfs_core"
175	# Ideally we would install these in the configured ${libdir}, which is
176	# by default "/usr/local/lib and unfortunately not included in the
177	# dynamic linker search path.
178	install "$LIB_DIR"/libzfs_core.so.?.?.? "/lib/libzfs_core.so"
179	install "$LIB_DIR"/libnvpair.so.?.?.?   "/lib/libnvpair.so"
180	[ "$DRYRUN" = "no" ] && ldconfig
181else
182	remove "$INSTALL_MOUNT_HELPER_DIR/mount.zfs"
183	remove "$INSTALL_MOUNT_HELPER_DIR/fsck.zfs"
184	remove "$INSTALL_UDEV_DIR/zvol_id"
185	remove "$INSTALL_UDEV_DIR/vdev_id"
186	remove "$INSTALL_UDEV_RULE_DIR/60-zvol.rules"
187	remove "$INSTALL_UDEV_RULE_DIR/69-vdev.rules"
188	remove "$INSTALL_UDEV_RULE_DIR/90-zfs.rules"
189	remove "$INSTALL_SYSCONF_DIR/zfs/zpool.d"
190	remove "$INSTALL_PKGDATA_DIR/compatibility.d"
191	remove "$INSTALL_PYTHON_DIR/libzfs_core"
192	remove "/lib/libzfs_core.so"
193	remove "/lib/libnvpair.so"
194	ldconfig
195fi
196
197exit 0
198