Skip to content

Commit 230970d

Browse files
rlaagertonyhutter
authored andcommitted
Fix a dependency loop
When generating units with zfs-mount-generator, if the pool is already imported, zfs-import.target is not needed. This avoids a dependency loop on root-on-ZFS systems: systemd-random-seed.service After (via RequiresMountsFor) var-lib.mount After zfs-import.target After zfs-import-{cache,scan}.service After cryptsetup.service After systemd-random-seed.service Reviewed-by: Antonio Russo <[email protected]> Reviewed-by: InsanePrawn <[email protected]> Signed-off-by: Richard Laager <[email protected]> Closes openzfs#10388
1 parent 7929106 commit 230970d

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

etc/systemd/system-generators/zfs-mount-generator.in

+25-6
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ do_fail() {
3838
is_known() {
3939
query="$1"
4040
IFS=' '
41-
# protect against special characters
42-
set -f
4341
for element in $2 ; do
4442
if [ "$query" = "$element" ] ; then
4543
return 0
@@ -54,8 +52,7 @@ is_known() {
5452
create_dependencies() {
5553
unitfile="$1"
5654
suffix="$2"
57-
# protect against special characters
58-
set -f
55+
IFS=' '
5956
for target in $3 ; do
6057
target_dir="${dest_norm}/${target}.${suffix}/"
6158
mkdir -p "${target_dir}"
@@ -72,6 +69,7 @@ else
7269
do_fail "zero or three arguments required"
7370
fi
7471

72+
pools=$(zpool list -H -o name || true)
7573

7674
# All needed information about each ZFS is available from
7775
# zfs list -H -t filesystem -o <properties>
@@ -83,11 +81,11 @@ process_line() {
8381
# zfs list -H -o name,...
8482
# fields are tab separated
8583
IFS="$(printf '\t')"
86-
# protect against special characters in, e.g., mountpoints
87-
set -f
8884
# shellcheck disable=SC2086
8985
set -- $1
86+
9087
dataset="${1}"
88+
pool="${dataset%%/*}"
9189
p_mountpoint="${2}"
9290
p_canmount="${3}"
9391
p_atime="${4}"
@@ -120,6 +118,25 @@ process_line() {
120118
requiredby=""
121119
noauto="off"
122120

121+
# If the pool is already imported, zfs-import.target is not needed. This
122+
# avoids a dependency loop on root-on-ZFS systems:
123+
# systemd-random-seed.service After (via RequiresMountsFor) var-lib.mount
124+
# After zfs-import.target After zfs-import-{cache,scan}.service After
125+
# cryptsetup.service After systemd-random-seed.service.
126+
#
127+
# Pools are newline-separated and may contain spaces in their names.
128+
# There is no better portable way to set IFS to just a newline. Using
129+
# $(printf '\n') doesn't work because $(...) strips trailing newlines.
130+
IFS="
131+
"
132+
for p in $pools ; do
133+
if [ "$p" = "$pool" ] ; then
134+
after=""
135+
wants=""
136+
break
137+
fi
138+
done
139+
123140
if [ -n "${p_systemd_after}" ] && \
124141
[ "${p_systemd_after}" != "-" ] ; then
125142
after="${p_systemd_after} ${after}"
@@ -438,6 +455,8 @@ Options=defaults${opts},zfsutil" > "${dest_norm}/${mountfile}"
438455
}
439456

440457
for cachefile in "${FSLIST}/"* ; do
458+
# Disable glob expansion to protect against special characters when parsing.
459+
set -f
441460
# Sort cachefile's lines by canmount, "on" before "noauto"
442461
# and feed each line into process_line
443462
sort -t "$(printf '\t')" -k 3 -r "${cachefile}" | \

etc/systemd/system/zfs-mount.service.in

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ After=systemd-udev-settle.service
66
After=zfs-import.target
77
After=systemd-remount-fs.service
88
Before=local-fs.target
9-
Before=systemd-random-seed.service
109
ConditionPathIsDirectory=/sys/module/zfs
1110

1211
[Service]

0 commit comments

Comments
 (0)