mirror of
https://github.com/systemd/systemd.git
synced 2025-05-30 05:05:57 +03:00
Merge pull request #27158 from mrc0mmand/more-tests
test: introduce TEST-81-GENERATORS
This commit is contained in:
commit
0864b5eb6e
@ -698,10 +698,10 @@ static int parse_fstab(bool initrd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sysfs_check < 0) {
|
if (sysfs_check < 0) {
|
||||||
r = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
|
k = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
|
||||||
if (r < 0 && r != -ENXIO)
|
if (k < 0 && k != -ENXIO)
|
||||||
log_debug_errno(r, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
|
log_debug_errno(k, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
|
||||||
sysfs_check = r != 0;
|
sysfs_check = k != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sysfs_check && is_device_path(what)) {
|
if (sysfs_check && is_device_path(what)) {
|
||||||
|
1
test/TEST-81-GENERATORS/Makefile
Symbolic link
1
test/TEST-81-GENERATORS/Makefile
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../TEST-01-BASIC/Makefile
|
10
test/TEST-81-GENERATORS/test.sh
Executable file
10
test/TEST-81-GENERATORS/test.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TEST_DESCRIPTION="Test systemd generators"
|
||||||
|
|
||||||
|
# shellcheck source=test/test-functions
|
||||||
|
. "${TEST_BASE_DIR:?}/test-functions"
|
||||||
|
|
||||||
|
do_test "$@"
|
61
test/units/generator-utils.sh
Normal file
61
test/units/generator-utils.sh
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
|
||||||
|
link_endswith() {
|
||||||
|
[[ -h "${1:?}" && "$(readlink "${1:?}")" =~ ${2:?}$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
link_eq() {
|
||||||
|
[[ -h "${1:?}" && "$(readlink "${1:?}")" == "${2:?}" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the value from a 'key=value' assignment
|
||||||
|
opt_get_arg() {
|
||||||
|
local arg
|
||||||
|
|
||||||
|
IFS="=" read -r _ arg <<< "${1:?}"
|
||||||
|
test -n "$arg"
|
||||||
|
echo "$arg"
|
||||||
|
}
|
||||||
|
|
||||||
|
in_initrd() {
|
||||||
|
[[ "${SYSTEMD_IN_INITRD:-0}" -ne 0 ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we're parsing host's fstab in initrd
|
||||||
|
in_initrd_host() {
|
||||||
|
in_initrd && [[ "${SYSTEMD_SYSROOT_FSTAB:-/dev/null}" != /dev/null ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
in_container() {
|
||||||
|
systemd-detect-virt -qc
|
||||||
|
}
|
||||||
|
|
||||||
|
# Filter out "unwanted" options, i.e. options that the fstab-generator doesn't
|
||||||
|
# propagate to the final mount unit
|
||||||
|
opt_filter_consumed() {(
|
||||||
|
set +x
|
||||||
|
local opt split_options filtered_options
|
||||||
|
|
||||||
|
IFS="," read -ra split_options <<< "${1:?}"
|
||||||
|
for opt in "${split_options[@]}"; do
|
||||||
|
if [[ "$opt" =~ ^x-systemd.device-timeout= ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
filtered_options+=("$opt")
|
||||||
|
done
|
||||||
|
|
||||||
|
IFS=","; printf "%s" "${filtered_options[*]}"
|
||||||
|
)}
|
||||||
|
|
||||||
|
# Run the given generator $1 with target directory $2 - clean the target
|
||||||
|
# directory beforehand
|
||||||
|
run_and_list() {
|
||||||
|
local generator="${1:?}"
|
||||||
|
local out_dir="${2:?}"
|
||||||
|
|
||||||
|
rm -fr "${out_dir:?}"/*
|
||||||
|
"$generator" "$out_dir"
|
||||||
|
ls -lR "$out_dir"
|
||||||
|
}
|
88
test/units/testsuite-74.modules-load.sh
Executable file
88
test/units/testsuite-74.modules-load.sh
Executable file
@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
MODULES_LOAD_BIN="/usr/lib/systemd/systemd-modules-load"
|
||||||
|
CONFIG_FILE="/run/modules-load.d/99-test.conf"
|
||||||
|
|
||||||
|
at_exit() {
|
||||||
|
rm -rfv "${CONFIG_FILE:?}"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap at_exit EXIT
|
||||||
|
|
||||||
|
if systemd-detect-virt -cq; then
|
||||||
|
echo "Running in a container, skipping the systemd-modules-load test..."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if we have required kernel modules
|
||||||
|
modprobe --all --resolve-alias loop dummy
|
||||||
|
|
||||||
|
mkdir -p /run/modules-load.d/
|
||||||
|
|
||||||
|
"$MODULES_LOAD_BIN"
|
||||||
|
"$MODULES_LOAD_BIN" --help
|
||||||
|
"$MODULES_LOAD_BIN" --version
|
||||||
|
|
||||||
|
# Explicit config file
|
||||||
|
modprobe -v --all --remove loop dummy
|
||||||
|
printf "loop\ndummy" >"$CONFIG_FILE"
|
||||||
|
"$MODULES_LOAD_BIN" "$CONFIG_FILE" |& tee /tmp/out.log
|
||||||
|
grep -E "Inserted module .*loop" /tmp/out.log
|
||||||
|
grep -E "Inserted module .*dummy" /tmp/out.log
|
||||||
|
|
||||||
|
# Implicit config file
|
||||||
|
modprobe -v --all --remove loop dummy
|
||||||
|
printf "loop\ndummy" >"$CONFIG_FILE"
|
||||||
|
"$MODULES_LOAD_BIN" |& tee /tmp/out.log
|
||||||
|
grep -E "Inserted module .*loop" /tmp/out.log
|
||||||
|
grep -E "Inserted module .*dummy" /tmp/out.log
|
||||||
|
|
||||||
|
# Valid & invalid data mixed together
|
||||||
|
modprobe -v --all --remove loop dummy
|
||||||
|
cat >"$CONFIG_FILE" <<EOF
|
||||||
|
|
||||||
|
loop
|
||||||
|
loop
|
||||||
|
loop
|
||||||
|
loop
|
||||||
|
dummy
|
||||||
|
\\n\n\n\\\\\\
|
||||||
|
|
||||||
|
loo!@@123##2455
|
||||||
|
# This is a comment
|
||||||
|
$(printf "%.0sx" {0..4096})
|
||||||
|
dummy
|
||||||
|
loop
|
||||||
|
foo-bar-baz
|
||||||
|
1
|
||||||
|
"
|
||||||
|
'
|
||||||
|
EOF
|
||||||
|
"$MODULES_LOAD_BIN" |& tee /tmp/out.log
|
||||||
|
grep -E "^Inserted module .*loop" /tmp/out.log
|
||||||
|
grep -E "^Inserted module .*dummy" /tmp/out.log
|
||||||
|
grep -E "^Failed to find module .*foo-bar-baz" /tmp/out.log
|
||||||
|
(! grep -E "This is a comment" /tmp/out.log)
|
||||||
|
# Each module should be loaded only once, even if specified multiple times
|
||||||
|
[[ "$(grep -Ec "^Inserted module" /tmp/out.log)" -eq 2 ]]
|
||||||
|
[[ "$(grep -Ec "^Failed to find module" /tmp/out.log)" -eq 7 ]]
|
||||||
|
|
||||||
|
# Command line arguments
|
||||||
|
modprobe -v --all --remove loop dummy
|
||||||
|
# Make sure we have no config files left over that might interfere with
|
||||||
|
# following tests
|
||||||
|
rm -fv "$CONFIG_FILE"
|
||||||
|
[[ -z "$(systemd-analyze cat-config modules-load.d)" ]]
|
||||||
|
CMDLINE="ro root= modules_load= modules_load=, / = modules_load=foo-bar-baz,dummy modules_load=loop,loop,loop"
|
||||||
|
SYSTEMD_PROC_CMDLINE="$CMDLINE" "$MODULES_LOAD_BIN" |& tee /tmp/out.log
|
||||||
|
grep -E "^Inserted module .*loop" /tmp/out.log
|
||||||
|
grep -E "^Inserted module .*dummy" /tmp/out.log
|
||||||
|
grep -E "^Failed to find module .*foo-bar-baz" /tmp/out.log
|
||||||
|
# Each module should be loaded only once, even if specified multiple times
|
||||||
|
[[ "$(grep -Ec "^Inserted module" /tmp/out.log)" -eq 2 ]]
|
||||||
|
|
||||||
|
(! "$MODULES_LOAD_BIN" --nope)
|
||||||
|
(! "$MODULES_LOAD_BIN" /foo/bar/baz)
|
105
test/units/testsuite-81.debug-generator.sh
Executable file
105
test/units/testsuite-81.debug-generator.sh
Executable file
@ -0,0 +1,105 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
# shellcheck disable=SC2235
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# shellcheck source=test/units/generator-utils.sh
|
||||||
|
. "$(dirname "$0")/generator-utils.sh"
|
||||||
|
|
||||||
|
GENERATOR_BIN="/usr/lib/systemd/system-generators/systemd-debug-generator"
|
||||||
|
OUT_DIR="$(mktemp -d /tmp/debug-generator.XXX)"
|
||||||
|
|
||||||
|
at_exit() {
|
||||||
|
rm -frv "${OUT_DIR:?}"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap at_exit EXIT
|
||||||
|
|
||||||
|
test -x "${GENERATOR_BIN:?}"
|
||||||
|
|
||||||
|
# Potential FIXME:
|
||||||
|
# - debug-generator should gracefully handle duplicated mask/wants
|
||||||
|
# - also, handle gracefully empty mask/wants
|
||||||
|
ARGS=(
|
||||||
|
"systemd.mask=masked-no-suffix"
|
||||||
|
"systemd.mask=masked.service"
|
||||||
|
"systemd.mask=masked.socket"
|
||||||
|
"systemd.wants=wanted-no-suffix"
|
||||||
|
"systemd.wants=wanted.service"
|
||||||
|
"systemd.wants=wanted.mount"
|
||||||
|
"rd.systemd.mask=masked-initrd.service"
|
||||||
|
"rd.systemd.wants=wanted-initrd.service"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Regular (non-initrd) scenario
|
||||||
|
#
|
||||||
|
: "debug-shell: regular"
|
||||||
|
CMDLINE="ro root=/ ${ARGS[*]} rd.systemd.debug_shell"
|
||||||
|
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_eq "$OUT_DIR/masked-no-suffix.service" /dev/null
|
||||||
|
link_eq "$OUT_DIR/masked.service" /dev/null
|
||||||
|
link_eq "$OUT_DIR/masked.socket" /dev/null
|
||||||
|
link_endswith "$OUT_DIR/default.target.wants/wanted-no-suffix.service" /lib/systemd/system/wanted-no-suffix.service
|
||||||
|
link_endswith "$OUT_DIR/default.target.wants/wanted.service" /lib/systemd/system/wanted.service
|
||||||
|
link_endswith "$OUT_DIR/default.target.wants/wanted.mount" /lib/systemd/system/wanted.mount
|
||||||
|
# Following stuff should be ignored, as it's prefixed with rd.
|
||||||
|
test ! -h "$OUT_DIR/masked-initrd.service"
|
||||||
|
test ! -h "$OUT_DIR/default.target.wants/wants-initrd.service"
|
||||||
|
test ! -h "$OUT_DIR/default.target.wants/debug-shell.service"
|
||||||
|
test ! -d "$OUT_DIR/initrd.target.wants"
|
||||||
|
|
||||||
|
# Let's re-run the generator with systemd.debug_shell that should be honored
|
||||||
|
: "debug-shell: regular + systemd.debug_shell"
|
||||||
|
CMDLINE="$CMDLINE systemd.debug_shell"
|
||||||
|
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_endswith "$OUT_DIR/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
|
||||||
|
|
||||||
|
# Same thing, but with custom tty
|
||||||
|
: "debug-shell: regular + systemd.debug_shell=/dev/tty666"
|
||||||
|
CMDLINE="$CMDLINE systemd.debug_shell=/dev/tty666"
|
||||||
|
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_endswith "$OUT_DIR/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
|
||||||
|
grep -F "/dev/tty666" "$OUT_DIR/debug-shell.service.d/50-tty.conf"
|
||||||
|
|
||||||
|
# Now override the default target via systemd.unit=
|
||||||
|
: "debug-shell: regular + systemd.unit="
|
||||||
|
CMDLINE="$CMDLINE systemd.unit=my-fancy.target"
|
||||||
|
SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_eq "$OUT_DIR/masked-no-suffix.service" /dev/null
|
||||||
|
link_eq "$OUT_DIR/masked.service" /dev/null
|
||||||
|
link_eq "$OUT_DIR/masked.socket" /dev/null
|
||||||
|
link_endswith "$OUT_DIR/my-fancy.target.wants/wanted-no-suffix.service" /lib/systemd/system/wanted-no-suffix.service
|
||||||
|
link_endswith "$OUT_DIR/my-fancy.target.wants/wanted.service" /lib/systemd/system/wanted.service
|
||||||
|
link_endswith "$OUT_DIR/my-fancy.target.wants/wanted.mount" /lib/systemd/system/wanted.mount
|
||||||
|
link_endswith "$OUT_DIR/my-fancy.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
|
||||||
|
test ! -d "$OUT_DIR/default.target.wants"
|
||||||
|
|
||||||
|
|
||||||
|
# Initrd scenario
|
||||||
|
: "debug-shell: initrd"
|
||||||
|
CMDLINE="ro root=/ ${ARGS[*]} systemd.debug_shell"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_eq "$OUT_DIR/masked-initrd.service" /dev/null
|
||||||
|
link_endswith "$OUT_DIR/initrd.target.wants/wanted-initrd.service" /lib/systemd/system/wanted-initrd.service
|
||||||
|
# The non-initrd stuff (i.e. without the rd. suffix) should be ignored in
|
||||||
|
# this case
|
||||||
|
test ! -h "$OUT_DIR/masked-no-suffix.service"
|
||||||
|
test ! -h "$OUT_DIR/masked.service"
|
||||||
|
test ! -h "$OUT_DIR/masked.socket"
|
||||||
|
test ! -h "$OUT_DIR/initrd.target.wants/debug-shell.service"
|
||||||
|
test ! -d "$OUT_DIR/default.target.wants"
|
||||||
|
|
||||||
|
# Again, but with rd.systemd.debug_shell
|
||||||
|
: "debug-shell: initrd + rd.systemd.debug_shell"
|
||||||
|
CMDLINE="$CMDLINE rd.systemd.debug_shell"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_endswith "$OUT_DIR/initrd.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
|
||||||
|
|
||||||
|
# Override the default target
|
||||||
|
: "debug-shell: initrd + rd.systemd.unit"
|
||||||
|
CMDLINE="$CMDLINE rd.systemd.unit=my-fancy-initrd.target"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
link_eq "$OUT_DIR/masked-initrd.service" /dev/null
|
||||||
|
link_endswith "$OUT_DIR/my-fancy-initrd.target.wants/wanted-initrd.service" /lib/systemd/system/wanted-initrd.service
|
||||||
|
test ! -d "$OUT_DIR/initrd.target.wants"
|
80
test/units/testsuite-81.environment-d-generator.sh
Executable file
80
test/units/testsuite-81.environment-d-generator.sh
Executable file
@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
# shellcheck disable=SC2235
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# shellcheck source=test/units/generator-utils.sh
|
||||||
|
. "$(dirname "$0")/generator-utils.sh"
|
||||||
|
|
||||||
|
GENERATOR_BIN="/usr/lib/systemd/user-environment-generators/30-systemd-environment-d-generator"
|
||||||
|
CONFIG_FILE="/run/environment.d/99-test.conf"
|
||||||
|
OUT_FILE="$(mktemp)"
|
||||||
|
|
||||||
|
at_exit() {
|
||||||
|
set +e
|
||||||
|
rm -frv "${CONFIG_FILE:?}" "${OUT_FILE:?}"
|
||||||
|
systemctl -M testuser@.host --user daemon-reload
|
||||||
|
}
|
||||||
|
|
||||||
|
trap at_exit EXIT
|
||||||
|
|
||||||
|
test -x "${GENERATOR_BIN:?}"
|
||||||
|
mkdir -p /run/environment.d/
|
||||||
|
|
||||||
|
cat >"$CONFIG_FILE" <<EOF
|
||||||
|
|
||||||
|
\t\n\t
|
||||||
|
3
|
||||||
|
=
|
||||||
|
=
|
||||||
|
INVALID
|
||||||
|
ALSO_INVALID=
|
||||||
|
EMPTY_INVALID=""
|
||||||
|
3_INVALID=foo
|
||||||
|
xxxx xx xxxxxx
|
||||||
|
# This is a comment
|
||||||
|
$(printf "%.0sx" {0..4096})=
|
||||||
|
SIMPLE=foo
|
||||||
|
REF=\$SIMPLE
|
||||||
|
ALSO_REF=\${SIMPLE}
|
||||||
|
DEFAULT="\${NONEXISTENT:-default value}"
|
||||||
|
ALTERNATE="\${SIMPLE:+alternate value}"
|
||||||
|
LIST=foo,bar,baz
|
||||||
|
SIMPLE=redefined
|
||||||
|
UNASSIGNED=\$FOO_BAR_BAZ
|
||||||
|
VERY_LONG="very $(printf "%.0sx" {0..4096})= long string"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Source env assignments from a file and check them - do this in a subshell
|
||||||
|
# to not pollute the test environment
|
||||||
|
check_environment() {(
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "${1:?}"
|
||||||
|
|
||||||
|
[[ "$SIMPLE" == "redefined" ]]
|
||||||
|
[[ "$REF" == "foo" ]]
|
||||||
|
[[ "$ALSO_REF" == "foo" ]]
|
||||||
|
[[ "$DEFAULT" == "default value" ]]
|
||||||
|
[[ "$ALTERNATE" == "alternate value" ]]
|
||||||
|
[[ "$LIST" == "foo,bar,baz" ]]
|
||||||
|
[[ "$VERY_LONG" =~ ^very\ ]]
|
||||||
|
[[ "$VERY_LONG" =~ \ long\ string$ ]]
|
||||||
|
[[ -z "$UNASSIGNED" ]]
|
||||||
|
[[ ! -v INVALID ]]
|
||||||
|
[[ ! -v ALSO_INVALID ]]
|
||||||
|
[[ ! -v EMPTY_INVALID ]]
|
||||||
|
[[ ! -v 3_INVALID ]]
|
||||||
|
)}
|
||||||
|
|
||||||
|
# Check the output by directly calling the generator
|
||||||
|
"$GENERATOR_BIN" | tee "$OUT_FILE"
|
||||||
|
check_environment "$OUT_FILE"
|
||||||
|
: >"$OUT_FILE"
|
||||||
|
|
||||||
|
# Check if the generator is correctly called in a user session
|
||||||
|
systemctl -M testuser@.host --user daemon-reload
|
||||||
|
systemctl -M testuser@.host --user show-environment | tee "$OUT_FILE"
|
||||||
|
check_environment "$OUT_FILE"
|
||||||
|
|
||||||
|
(! "$GENERATOR_BIN" foo)
|
360
test/units/testsuite-81.fstab-generator.sh
Executable file
360
test/units/testsuite-81.fstab-generator.sh
Executable file
@ -0,0 +1,360 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
# shellcheck disable=SC2235,SC2233
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# shellcheck source=test/units/generator-utils.sh
|
||||||
|
. "$(dirname "$0")/generator-utils.sh"
|
||||||
|
|
||||||
|
export SYSTEMD_LOG_LEVEL=debug
|
||||||
|
|
||||||
|
GENERATOR_BIN="/usr/lib/systemd/system-generators/systemd-fstab-generator"
|
||||||
|
NETWORK_FS_RX="^(afs|ceph|cifs|gfs|gfs2|ncp|ncpfs|nfs|nfs4|ocfs2|orangefs|pvfs2|smb3|smbfs|davfs|glusterfs|lustre|sshfs)$"
|
||||||
|
OUT_DIR="$(mktemp -d /tmp/fstab-generator.XXX)"
|
||||||
|
FSTAB="$(mktemp)"
|
||||||
|
|
||||||
|
at_exit() {
|
||||||
|
rm -fr "${OUT_DIR:?}" "${FSTAB:?}"
|
||||||
|
}
|
||||||
|
|
||||||
|
trap at_exit EXIT
|
||||||
|
|
||||||
|
test -x "${GENERATOR_BIN:?}"
|
||||||
|
|
||||||
|
FSTAB_GENERAL=(
|
||||||
|
# Valid entries
|
||||||
|
"/dev/test2 /nofail ext4 nofail 0 0"
|
||||||
|
"/dev/test3 /regular btrfs defaults 0 0"
|
||||||
|
"/dev/test4 /x-systemd.requires xfs x-systemd.requires=foo.service 0 0"
|
||||||
|
"/dev/test5 /x-systemd.before-after xfs x-systemd.before=foo.service,x-systemd.after=bar.mount 0 0"
|
||||||
|
"/dev/test6 /x-systemd.wanted-required-by xfs x-systemd.wanted-by=foo.service,x-systemd.required-by=bar.device 0 0"
|
||||||
|
"/dev/test7 /x-systemd.requires-mounts-for xfs x-systemd.requires-mounts-for=/foo/bar/baz 0 0"
|
||||||
|
"/dev/test8 /x-systemd.automount-idle-timeout vfat x-systemd.automount,x-systemd.idle-timeout=50s 0 0"
|
||||||
|
"/dev/test9 /x-systemd.makefs xfs x-systemd.makefs 0 0"
|
||||||
|
"/dev/test10 /x-systemd.growfs xfs x-systemd.growfs 0 0"
|
||||||
|
"/dev/test11 /_netdev ext4 defaults,_netdev 0 0"
|
||||||
|
"/dev/test12 /_rwonly ext4 x-systemd.rw-only 0 0"
|
||||||
|
"/dev/test13 /chaos1 zfs x-systemd.rw-only,x-systemd.requires=hello.service,x-systemd.after=my.device 0 0"
|
||||||
|
"/dev/test14 /chaos2 zfs x.systemd.wanted-by=foo.service,x-systemd.growfs,x-systemd.makefs 0 0"
|
||||||
|
"/dev/test15 /fstype/auto auto defaults 0 0"
|
||||||
|
"/dev/test16 /fsck/me ext4 defaults 0 1"
|
||||||
|
"/dev/test17 /also/fsck/me ext4 defaults,x-systemd.requires-mounts-for=/var/lib/foo 0 99"
|
||||||
|
"/dev/test18 /swap swap defaults 0 0"
|
||||||
|
"/dev/test19 /swap/makefs swap defaults,x-systemd.makefs 0 0"
|
||||||
|
"/dev/test20 /var xfs defaults,x-systemd.device-timeout=1h 0 0"
|
||||||
|
"/dev/test21 /usr ext4 defaults 0 1"
|
||||||
|
"/dev/test22 /initrd/mount ext2 defaults,x-systemd.rw-only,x-initrd.mount 0 1"
|
||||||
|
"/dev/test23 /initrd/mount/nofail ext3 defaults,nofail,x-initrd.mount 0 1"
|
||||||
|
"/dev/test24 /initrd/mount/deps ext4 x-initrd.mount,x-systemd.before=early.service,x-systemd.after=late.service 0 1"
|
||||||
|
|
||||||
|
# Incomplete, but valid entries
|
||||||
|
"/dev/incomplete1 /incomplete1"
|
||||||
|
"/dev/incomplete2 /incomplete2 ext4"
|
||||||
|
"/dev/incomplete3 /incomplete3 ext4 defaults"
|
||||||
|
"/dev/incomplete4 /incomplete4 ext4 defaults 0"
|
||||||
|
|
||||||
|
# Remote filesystems
|
||||||
|
"/dev/remote1 /nfs nfs bg 0 0"
|
||||||
|
"/dev/remote2 /nfs4 nfs4 bg 0 0"
|
||||||
|
"bar.tld:/store /remote/storage nfs ro,x-systemd.wanted-by=store.service 0 0"
|
||||||
|
"user@host.tld:/remote/dir /remote/top-secret sshfs rw,x-systemd.before=naughty.service 0 0"
|
||||||
|
"foo.tld:/hello /hello/world ceph defaults 0 0"
|
||||||
|
"//192.168.0.1/storage /cifs-storage cifs automount,nofail 0 0"
|
||||||
|
)
|
||||||
|
|
||||||
|
FSTAB_GENERAL_ROOT=(
|
||||||
|
# rootfs with bunch of options we should ignore and fsck enabled
|
||||||
|
"/dev/test1 / ext4 noauto,nofail,automount,x-systemd.wanted-by=foo,x-systemd.required-by=bar 0 1"
|
||||||
|
"${FSTAB_GENERAL[@]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
FSTAB_MINIMAL=(
|
||||||
|
"/dev/loop1 /foo/bar ext3 defaults 0 0"
|
||||||
|
)
|
||||||
|
|
||||||
|
FSTAB_DUPLICATE=(
|
||||||
|
"/dev/dup1 / ext4 defaults 0 1"
|
||||||
|
"/dev/dup2 / ext4 defaults,x-systemd.requires=foo.mount 0 2"
|
||||||
|
)
|
||||||
|
|
||||||
|
FSTAB_INVALID=(
|
||||||
|
# Ignored entries
|
||||||
|
"/dev/ignored1 /sys/fs/cgroup/foo ext4 defaults 0 0"
|
||||||
|
"/dev/ignored2 /sys/fs/selinux ext4 defaults 0 0"
|
||||||
|
"/dev/ignored3 /dev/console ext4 defaults 0 0"
|
||||||
|
"/dev/ignored4 /proc/kmsg ext4 defaults 0 0"
|
||||||
|
"/dev/ignored5 /proc/sys ext4 defaults 0 0"
|
||||||
|
"/dev/ignored6 /proc/sys/kernel/random/boot_id ext4 defaults 0 0"
|
||||||
|
"/dev/ignored7 /run/host ext4 defaults 0 0"
|
||||||
|
"/dev/ignored8 /run/host/foo ext4 defaults 0 0"
|
||||||
|
"/dev/ignored9 /autofs autofs defaults 0 0"
|
||||||
|
"/dev/invalid1 not-a-path ext4 defaults 0 0"
|
||||||
|
""
|
||||||
|
"/dev/invalid1"
|
||||||
|
" "
|
||||||
|
"\\"
|
||||||
|
"$"
|
||||||
|
)
|
||||||
|
|
||||||
|
check_fstab_mount_units() {
|
||||||
|
local what where fstype opts passno unit
|
||||||
|
local item opt split_options filtered_options supp service device arg
|
||||||
|
local array_name="${1:?}"
|
||||||
|
local out_dir="${2:?}"
|
||||||
|
# Get a reference to the array from its name
|
||||||
|
local -n fstab_entries="$array_name"
|
||||||
|
|
||||||
|
# Running the checks in a container is pretty much useless, since we don't
|
||||||
|
# generate any mounts, but don't skip the whole test to test the "skip"
|
||||||
|
# paths as well
|
||||||
|
in_container && return 0
|
||||||
|
|
||||||
|
for item in "${fstab_entries[@]}"; do
|
||||||
|
# Don't use a pipe here, as it would make the variables out of scope
|
||||||
|
read -r what where fstype opts _ passno <<< "$item"
|
||||||
|
|
||||||
|
# Skip non-initrd mounts in initrd
|
||||||
|
if in_initrd_host && ! [[ "$opts" =~ x-initrd.mount ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$fstype" == swap ]]; then
|
||||||
|
unit="$(systemd-escape --suffix=swap --path "${what:?}")"
|
||||||
|
cat "$out_dir/$unit"
|
||||||
|
|
||||||
|
grep -qE "^What=$what$" "$out_dir/$unit"
|
||||||
|
if [[ "$opts" != defaults ]]; then
|
||||||
|
grep -qE "^Options=$opts$" "$out_dir/$unit"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$opts" =~ x-systemd.makefs ]]; then
|
||||||
|
service="$(systemd-escape --template=systemd-mkswap@.service --path "$what")"
|
||||||
|
test -e "$out_dir/$service"
|
||||||
|
fi
|
||||||
|
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If we're parsing host's fstab in initrd, prefix all mount targets
|
||||||
|
# with /sysroot
|
||||||
|
in_initrd_host && where="/sysroot${where:?}"
|
||||||
|
unit="$(systemd-escape --suffix=mount --path "${where:?}")"
|
||||||
|
cat "$out_dir/$unit"
|
||||||
|
|
||||||
|
# Check the general stuff
|
||||||
|
grep -qE "^What=$what$" "$out_dir/$unit"
|
||||||
|
grep -qE "^Where=$where$" "$out_dir/$unit"
|
||||||
|
if [[ -n "$fstype" ]] && [[ "$fstype" != auto ]]; then
|
||||||
|
grep -qE "^Type=$fstype$" "$out_dir/$unit"
|
||||||
|
fi
|
||||||
|
if [[ -n "$opts" ]] && [[ "$opts" != defaults ]]; then
|
||||||
|
# Some options are not propagated to the generated unit
|
||||||
|
filtered_options="$(opt_filter_consumed "$opts")"
|
||||||
|
if [[ "${filtered_options[*]}" != defaults ]]; then
|
||||||
|
grep -qE "^Options=.*$filtered_options.*$" "$out_dir/$unit"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [[ "$opts" =~ (noauto|x-systemd.(wanted-by=|required-by=|automount)) ]]; then
|
||||||
|
# We don't create the Requires=/Wants= symlinks for noauto/automount mounts
|
||||||
|
# and for mounts that use x-systemd.wanted-by=/required-by=
|
||||||
|
if in_initrd_host; then
|
||||||
|
if [[ "$where" == / ]] || ! [[ "$opts" =~ nofail ]]; then
|
||||||
|
link_eq "$out_dir/initrd-fs.target.requires/$unit" "../$unit"
|
||||||
|
else
|
||||||
|
link_eq "$out_dir/initrd-fs.target.wants/$unit" "../$unit"
|
||||||
|
fi
|
||||||
|
elif [[ "$fstype" =~ $NETWORK_FS_RX || "$opts" =~ _netdev ]]; then
|
||||||
|
# Units with network filesystems should have a Requires= dependency
|
||||||
|
# on the remote-fs.target, unless they use nofail or are an nfs "bg"
|
||||||
|
# mounts, in which case the dependency is downgraded to Wants=
|
||||||
|
if [[ "$opts" =~ nofail ]] || [[ "$fstype" =~ ^(nfs|nfs4) && "$opts" =~ bg ]]; then
|
||||||
|
link_eq "$out_dir/remote-fs.target.wants/$unit" "../$unit"
|
||||||
|
else
|
||||||
|
link_eq "$out_dir/remote-fs.target.requires/$unit" "../$unit"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Similarly, local filesystems should have a Requires= dependency on
|
||||||
|
# the local-fs.target, unless they use nofail, in which case the
|
||||||
|
# dependency is downgraded to Wants=. Rootfs is a special case,
|
||||||
|
# since we always ignore nofail there
|
||||||
|
if [[ "$where" == / ]] || ! [[ "$opts" =~ nofail ]]; then
|
||||||
|
link_eq "$out_dir/local-fs.target.requires/$unit" "../$unit"
|
||||||
|
else
|
||||||
|
link_eq "$out_dir/local-fs.target.wants/$unit" "../$unit"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${passno:=0}" -ne 0 ]]; then
|
||||||
|
# Generate systemd-fsck@.service dependencies, if applicable
|
||||||
|
if in_initrd && [[ "$where" == / || "$where" == /usr ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$where" == / ]]; then
|
||||||
|
link_endswith "$out_dir/local-fs.target.wants/systemd-fsck-root.service" "/lib/systemd/system/systemd-fsck-root.service"
|
||||||
|
else
|
||||||
|
service="$(systemd-escape --template=systemd-fsck@.service --path "$what")"
|
||||||
|
grep -qE "^After=$service$" "$out_dir/$unit"
|
||||||
|
if [[ "$where" == /usr ]]; then
|
||||||
|
grep -qE "^Wants=$service$" "$out_dir/$unit"
|
||||||
|
else
|
||||||
|
grep -qE "^Requires=$service$" "$out_dir/$unit"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check various x-systemd options
|
||||||
|
#
|
||||||
|
# First, split them into an array to make splitting them even further
|
||||||
|
# easier
|
||||||
|
IFS="," read -ra split_options <<< "$opts"
|
||||||
|
# and process them one by one.
|
||||||
|
#
|
||||||
|
# Note: the "machinery" below might (and probably does) miss some
|
||||||
|
# combinations of supported options, so tread carefully
|
||||||
|
for opt in "${split_options[@]}"; do
|
||||||
|
if [[ "$opt" =~ ^x-systemd.requires= ]]; then
|
||||||
|
service="$(opt_get_arg "$opt")"
|
||||||
|
grep -qE "^Requires=$service$" "$out_dir/$unit"
|
||||||
|
grep -qE "^After=$service$" "$out_dir/$unit"
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.before= ]]; then
|
||||||
|
service="$(opt_get_arg "$opt")"
|
||||||
|
grep -qE "^Before=$service$" "$out_dir/$unit"
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.after= ]]; then
|
||||||
|
service="$(opt_get_arg "$opt")"
|
||||||
|
grep -qE "^After=$service$" "$out_dir/$unit"
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.wanted-by= ]]; then
|
||||||
|
service="$(opt_get_arg "$opt")"
|
||||||
|
if [[ "$where" == / ]]; then
|
||||||
|
# This option is ignored for rootfs mounts
|
||||||
|
(! link_eq "$out_dir/$service.wants/$unit" "../$unit")
|
||||||
|
else
|
||||||
|
link_eq "$out_dir/$service.wants/$unit" "../$unit"
|
||||||
|
fi
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.required-by= ]]; then
|
||||||
|
service="$(opt_get_arg "$opt")"
|
||||||
|
if [[ "$where" == / ]]; then
|
||||||
|
# This option is ignored for rootfs mounts
|
||||||
|
(! link_eq "$out_dir/$service.requires/$unit" "../$unit")
|
||||||
|
else
|
||||||
|
link_eq "$out_dir/$service.requires/$unit" "../$unit"
|
||||||
|
fi
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.requires-mounts-for= ]]; then
|
||||||
|
arg="$(opt_get_arg "$opt")"
|
||||||
|
grep -qE "^RequiresMountsFor=$arg$" "$out_dir/$unit"
|
||||||
|
elif [[ "$opt" == x-systemd.device-bound ]]; then
|
||||||
|
# This is implied for fstab mounts
|
||||||
|
:
|
||||||
|
elif [[ "$opt" == x-systemd.automount ]]; then
|
||||||
|
# The $unit should have an accompanying automount unit
|
||||||
|
supp="$(systemd-escape --suffix=automount --path "$where")"
|
||||||
|
test -e "$out_dir/$supp"
|
||||||
|
link_eq "$out_dir/local-fs.target.requires/$supp" "../$supp"
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.idle-timeout= ]]; then
|
||||||
|
# The timeout applies to the automount unit, not the original
|
||||||
|
# mount one
|
||||||
|
arg="$(opt_get_arg "$opt")"
|
||||||
|
supp="$(systemd-escape --suffix=automount --path "$where")"
|
||||||
|
grep -qE "^TimeoutIdleSec=$arg$" "$out_dir/$supp"
|
||||||
|
elif [[ "$opt" =~ ^x-systemd.device-timeout= ]]; then
|
||||||
|
arg="$(opt_get_arg "$opt")"
|
||||||
|
device="$(systemd-escape --suffix=device --path "$what")"
|
||||||
|
grep -qE "^JobRunningTimeoutSec=$arg$" "$out_dir/${device}.d/50-device-timeout.conf"
|
||||||
|
elif [[ "$opt" == x-systemd.makefs ]]; then
|
||||||
|
service="$(systemd-escape --template=systemd-makefs@.service --path "$what")"
|
||||||
|
test -e "$out_dir/$service"
|
||||||
|
link_eq "$out_dir/${unit}.requires/$service" "../$service"
|
||||||
|
elif [[ "$opt" == x-systemd.rw-only ]]; then
|
||||||
|
grep -qE "^ReadWriteOnly=yes$" "$out_dir/$unit"
|
||||||
|
elif [[ "$opt" == x-systemd.growfs ]]; then
|
||||||
|
service="$(systemd-escape --template=systemd-growfs@.service --path "$where")"
|
||||||
|
link_endswith "$out_dir/${unit}.wants/$service" "/lib/systemd/system/systemd-growfs@.service"
|
||||||
|
elif [[ "$opt" == bg ]] && [[ "$fstype" =~ ^(nfs|nfs4)$ ]]; then
|
||||||
|
# We "convert" nfs bg mounts to fg, so we can do the job-control
|
||||||
|
# ourselves
|
||||||
|
grep -qE "^Options=.*\bx-systemd.mount-timeout=infinity\b" "$out_dir/$unit"
|
||||||
|
grep -qE "^Options=.*\bfg\b.*" "$out_dir/$unit"
|
||||||
|
elif [[ "$opt" =~ ^x-systemd\. ]]; then
|
||||||
|
echo >&2 "Unhandled mount option: $opt"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# - kernel arguments
|
||||||
|
|
||||||
|
: "fstab-generator: regular"
|
||||||
|
printf "%s\n" "${FSTAB_GENERAL_ROOT[@]}" >"$FSTAB"
|
||||||
|
cat "$FSTAB"
|
||||||
|
SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
check_fstab_mount_units FSTAB_GENERAL_ROOT "$OUT_DIR"
|
||||||
|
|
||||||
|
# Skip the rest when running in a container, as it makes little sense to check
|
||||||
|
# initrd-related stuff there and fstab-generator might have a bit strange
|
||||||
|
# behavior during certain tests, like https://github.com/systemd/systemd/issues/27156
|
||||||
|
if in_container; then
|
||||||
|
echo "Running in a container, skipping the rest of the fstab-generator tests..."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# In this mode we treat the entries as "regular" ones
|
||||||
|
: "fstab-generator: initrd - initrd fstab"
|
||||||
|
printf "%s\n" "${FSTAB_GENERAL[@]}" >"$FSTAB"
|
||||||
|
cat "$FSTAB"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_SYSROOT_FSTAB=/dev/null run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_SYSROOT_FSTAB=/dev/null check_fstab_mount_units FSTAB_GENERAL "$OUT_DIR"
|
||||||
|
|
||||||
|
# In this mode we prefix the mount target with /sysroot and ignore all mounts
|
||||||
|
# that don't have the x-initrd.mount flag
|
||||||
|
: "fstab-generator: initrd - host fstab"
|
||||||
|
printf "%s\n" "${FSTAB_GENERAL_ROOT[@]}" >"$FSTAB"
|
||||||
|
cat "$FSTAB"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_GENERAL_ROOT "$OUT_DIR"
|
||||||
|
|
||||||
|
# Check the default stuff that we (almost) always create in initrd
|
||||||
|
: "fstab-generator: initrd default"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB=/dev/null SYSTEMD_SYSROOT_FSTAB=/dev/null run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
test -e "$OUT_DIR/sysroot.mount"
|
||||||
|
test -e "$OUT_DIR/systemd-fsck-root.service"
|
||||||
|
link_eq "$OUT_DIR/initrd-root-fs.target.requires/sysroot.mount" "../sysroot.mount"
|
||||||
|
link_eq "$OUT_DIR/initrd-root-fs.target.requires/sysroot.mount" "../sysroot.mount"
|
||||||
|
|
||||||
|
: "fstab-generator: run as systemd-sysroot-fstab-check in initrd"
|
||||||
|
ln -svf "$GENERATOR_BIN" /tmp/systemd-sysroot-fstab-check
|
||||||
|
(! /tmp/systemd-sysroot-fstab-check foo)
|
||||||
|
(! SYSTEMD_IN_INITRD=0 /tmp/systemd-sysroot-fstab-check)
|
||||||
|
printf "%s\n" "${FSTAB_GENERAL[@]}" >"$FSTAB"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_SYSROOT_FSTAB="$FSTAB" /tmp/systemd-sysroot-fstab-check
|
||||||
|
|
||||||
|
: "fstab-generator: duplicate"
|
||||||
|
printf "%s\n" "${FSTAB_DUPLICATE[@]}" >"$FSTAB"
|
||||||
|
cat "$FSTAB"
|
||||||
|
(! SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR")
|
||||||
|
|
||||||
|
: "fstab-generator: invalid"
|
||||||
|
printf "%s\n" "${FSTAB_INVALID[@]}" >"$FSTAB"
|
||||||
|
cat "$FSTAB"
|
||||||
|
# Don't care about the exit code here
|
||||||
|
SYSTEMD_FSTAB="$FSTAB" run_and_list "$GENERATOR_BIN" "$OUT_DIR" || :
|
||||||
|
# No mounts should get created here
|
||||||
|
[[ "$(find "$OUT_DIR" -name "*.mount" | wc -l)" -eq 0 ]]
|
||||||
|
|
||||||
|
: "fstab-generator: kernel args - fstab=0"
|
||||||
|
printf "%s\n" "${FSTAB_MINIMAL[@]}" >"$FSTAB"
|
||||||
|
SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
(! SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR")
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
(! SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR")
|
||||||
|
|
||||||
|
: "fstab-generator: kernel args - rd.fstab=0"
|
||||||
|
printf "%s\n" "${FSTAB_MINIMAL[@]}" >"$FSTAB"
|
||||||
|
SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="rd.fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR"
|
||||||
|
SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" SYSTEMD_PROC_CMDLINE="rd.fstab=0" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
|
||||||
|
(! SYSTEMD_IN_INITRD=1 SYSTEMD_FSTAB="$FSTAB" check_fstab_mount_units FSTAB_MINIMAL "$OUT_DIR")
|
8
test/units/testsuite-81.service
Normal file
8
test/units/testsuite-81.service
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
[Unit]
|
||||||
|
Description=TEST-81-GENERATORS
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=rm -f /failed /testok
|
||||||
|
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
|
||||||
|
Type=oneshot
|
16
test/units/testsuite-81.sh
Executable file
16
test/units/testsuite-81.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
set -eux
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
: >/failed
|
||||||
|
|
||||||
|
systemctl log-level debug
|
||||||
|
|
||||||
|
for script in "${0%.sh}".*.sh; do
|
||||||
|
echo "Running $script"
|
||||||
|
"./$script"
|
||||||
|
done
|
||||||
|
|
||||||
|
touch /testok
|
||||||
|
rm /failed
|
Loading…
x
Reference in New Issue
Block a user