Merge pull request #27891 from mrc0mmand/more-tests-again

test: improve systemd-pstore tests & add a couple of tests for systemd-run
This commit is contained in:
Frantisek Sumsal
2023-06-02 10:05:17 +02:00
committed by GitHub
7 changed files with 292 additions and 56 deletions
+1 -1
View File
@@ -364,7 +364,7 @@ static int bus_socket_set_transient_property(
return r;
while ((r = sd_bus_message_read(message, "(ss)", &t, &a)) > 0) {
_cleanup_free_ SocketPort *p = NULL;
_cleanup_(socket_port_freep) SocketPort *p = NULL;
p = new(SocketPort, 1);
if (!p)
+1 -1
View File
@@ -30,7 +30,7 @@ int bus_property_get_triggered_unit(
return sd_bus_message_append(reply, "s", trigger ? trigger->id : NULL);
}
BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%04o");
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
static inline bool valid_user_group_name_or_id_relaxed(const char *u) {
+14 -7
View File
@@ -120,6 +120,19 @@ static void socket_cleanup_fd_list(SocketPort *p) {
p->n_auxiliary_fds = 0;
}
SocketPort *socket_port_free(SocketPort *p) {
if (!p)
return NULL;
sd_event_source_unref(p->event_source);
socket_cleanup_fd_list(p);
safe_close(p->fd);
free(p->path);
return mfree(p);
}
void socket_free_ports(Socket *s) {
SocketPort *p;
@@ -127,13 +140,7 @@ void socket_free_ports(Socket *s) {
while ((p = s->ports)) {
LIST_REMOVE(port, s->ports, p);
sd_event_source_unref(p->event_source);
socket_cleanup_fd_list(p);
safe_close(p->fd);
free(p->path);
free(p);
socket_port_free(p);
}
}
+3
View File
@@ -172,6 +172,9 @@ int socket_collect_fds(Socket *s, int **fds);
/* Called from the service code when a per-connection service ended */
void socket_connection_unref(Socket *s);
SocketPort *socket_port_free(SocketPort *p);
DEFINE_TRIVIAL_CLEANUP_FUNC(SocketPort*, socket_port_free);
void socket_free_ports(Socket *s);
int socket_load_service_unit(Socket *s, int cfd, Unit **ret);
+1 -1
View File
@@ -2668,7 +2668,7 @@ inst_binary() {
# nsswitch.conf uses [SUCCESS=merge] (like on Arch Linux)
# delv, dig - pull in nss_resolve if `resolve` is in nsswitch.conf
# tar - called by machinectl in TEST-25
bin_rx='/(chown|delv|dig|getent|login|ls|mkfs\.[a-z0-9]+|mksquashfs|mkswap|setfacl|setpriv|stat|su|tar|useradd|userdel)$'
bin_rx='/(chown|delv|dig|getent|id|login|ls|mkfs\.[a-z0-9]+|mksquashfs|mkswap|setfacl|setpriv|stat|su|tar|useradd|userdel)$'
if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ $bin_rx ]]; then
wrap_binary=1
fi
+72 -46
View File
@@ -10,8 +10,8 @@ if systemd-detect-virt -cq; then
exit 0
fi
DUMMY_DMESG_1="$(mktemp)"
cat >"$DUMMY_DMESG_1" <<\EOF
DUMMY_DMESG_0="$(mktemp)"
cat >"$DUMMY_DMESG_0" <<\EOF
6,17159,5340096332127,-;usb 1-4: USB disconnect, device number 124
6,17160,5340109662397,-;input: WH-1000XM3 (AVRCP) as /devices/virtual/input/input293
6,17161,5343126458360,-;loop0: detected capacity change from 0 to 3145728
@@ -28,8 +28,8 @@ cat >"$DUMMY_DMESG_1" <<\EOF
6,17172,5343158701120,-; loop0: p1 p2
EOF
DUMMY_DMESG_2="$(mktemp)"
cat >"$DUMMY_DMESG_2" <<\EOF
DUMMY_DMESG_1="$(mktemp)"
cat >"$DUMMY_DMESG_1" <<\EOF
Nechť již hříšné saxofony ďáblů rozezvučí síň úděsnými tóny waltzu, tanga a quickstepu.
Příliš žluťoučký kůň úpěl ďábelské ódy.
Zvlášť zákeřný učeň s ďolíčky běží podél zóny úlů.
@@ -108,7 +108,7 @@ prepare_pstore_config() {
rm -fr /sys/fs/pstore/* /var/lib/systemd/pstore/*
mkdir -p /run/systemd/pstore.conf.d
cat >"/run/systemd/pstore.conf.d/99-test.conf" <<EOF
cat >/run/systemd/pstore.conf.d/99-test.conf <<EOF
[PStore]
Storage=$storage
Unlink=$unlink
@@ -121,7 +121,7 @@ EOF
start_pstore() {
rm -f /tmp/journal.cursor
journalctl -q -n 0 --cursor-file=/tmp/journal.cursor
systemctl start systemd-pstore
systemctl restart systemd-pstore
journalctl --sync
}
@@ -130,12 +130,21 @@ start_pstore() {
PSTORE_DIR="$(mktemp -d)"
mount --bind "${PSTORE_DIR:?}" "/sys/fs/pstore"
# Disable the start limit since we're going to restart the systemd-pstore
# service quite a lot in a short time span
mkdir -p /run/systemd/system/systemd-pstore.service.d
cat >/run/systemd/system/systemd-pstore.service.d/99-StartLimitInterval.conf <<EOF
[Unit]
StartLimitInterval=0
EOF
systemctl daemon-reload
# systemd-pstore is a no-op with Storage=none
for unlink in yes no; do
: "Backend: N/A; Storage: none; Unlink: $unlink"
timestamp="$(random_efi_timestamp)"
prepare_pstore_config "none" "$unlink"
prepare_efi_logs "$DUMMY_DMESG_1" "$timestamp"
prepare_efi_logs "$DUMMY_DMESG_0" "$timestamp"
old_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$old_count" ]]
@@ -144,78 +153,95 @@ for unlink in yes no; do
: "Backend: EFI; Storage: external; Unlink: $unlink"
timestamp="$(random_efi_timestamp)"
prepare_pstore_config "external" "$unlink"
prepare_efi_logs "$DUMMY_DMESG_1" "$timestamp"
prepare_efi_logs "$DUMMY_DMESG_0" "$timestamp"
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]]
# We always log to journal
diff "$DUMMY_DMESG_1" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
filename="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp" "$(file_size "$DUMMY_DMESG_1")")"
diff "$DUMMY_DMESG_1" "$filename"
diff "$DUMMY_DMESG_0" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
filename="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp" "$(file_size "$DUMMY_DMESG_0")")"
diff "$DUMMY_DMESG_0" "$filename"
: "Backend: EFI; Storage: external; Unlink: $unlink; multiple dmesg files"
timestamp_1="$(random_efi_timestamp)"
timestamp_2="$((timestamp_1 + 1))"
timestamps=()
timestamp="$(random_efi_timestamp)"
prepare_pstore_config "external" "$unlink"
prepare_efi_logs "$DUMMY_DMESG_1" "$timestamp_1"
prepare_efi_logs "$DUMMY_DMESG_2" "$timestamp_2"
# Add one "random" (non-dmesg) file as well
echo "hello world" >/sys/fs/pstore/foo.bar
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]]
filename_1="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp_1" "$(file_size "$DUMMY_DMESG_1")")"
diff "$DUMMY_DMESG_1" "$filename_1"
filename_2="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp_2" "$(file_size "$DUMMY_DMESG_2")")"
diff "$DUMMY_DMESG_2" "$filename_2"
grep "hello world" "/var/lib/systemd/pstore/foo.bar"
for i in {0..6}; do
timestamp="$((timestamp + (i * 10)))"
timestamps+=("$timestamp")
# Create a name reference to one of the $DUMMY_DMESG_X variables
dmesg="DUMMY_DMESG_$((i % 2))"
prepare_efi_logs "${!dmesg}" "$timestamp"
# Add one "random" (non-dmesg) file as well
echo "hello world" >/sys/fs/pstore/foo.bar
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]]
filename="$(printf "/var/lib/systemd/pstore/%s/%0.3d/dmesg.txt" "$timestamp" "$(file_size "${!dmesg}")")"
diff "${!dmesg}" "$filename"
grep "hello world" "/var/lib/systemd/pstore/foo.bar"
done
# Check that we kept all previous records as well
for timestamp in "${timestamps[@]}"; do
[[ -d "/var/lib/systemd/pstore/$timestamp" ]]
[[ "$(file_count "/var/lib/systemd/pstore/$timestamp/")" -gt 0 ]]
done
: "Backend: EFI; Storage: journal; Unlink: $unlink"
timestamp="$(random_efi_timestamp)"
prepare_pstore_config "journal" "$unlink"
prepare_efi_logs "$DUMMY_DMESG_1" "$timestamp"
prepare_efi_logs "$DUMMY_DMESG_0" "$timestamp"
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -eq 0 ]]
diff "$DUMMY_DMESG_1" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
diff "$DUMMY_DMESG_0" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
: "Backend: ERST; Storage: external; Unlink: $unlink"
prepare_pstore_config "external" "$unlink"
last_id="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)"
last_id="$(prepare_erst_logs "$DUMMY_DMESG_0" 0)"
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]]
# We always log to journal
diff "$DUMMY_DMESG_1" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
diff "$DUMMY_DMESG_0" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
filename="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id")"
diff "$DUMMY_DMESG_1" "$filename"
diff "$DUMMY_DMESG_0" "$filename"
: "Backend: ERST; Storage: external; Unlink: $unlink; multiple dmesg files"
last_ids=()
prepare_pstore_config "external" "$unlink"
last_id_1="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)"
last_id_2="$(prepare_erst_logs "$DUMMY_DMESG_2" "$((last_id_1 + 10))")"
# Add one "random" (non-dmesg) file as well
echo "hello world" >/sys/fs/pstore/foo.bar
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]]
filename_1="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id_1")"
diff "$DUMMY_DMESG_1" "$filename_1"
filename_2="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id_2")"
diff "$DUMMY_DMESG_2" "$filename_2"
grep "hello world" "/var/lib/systemd/pstore/foo.bar"
for i in {0..9}; do
# Create a name reference to one of the $DUMMY_DMESG_X variables
dmesg="DUMMY_DMESG_$((i % 2))"
last_id="$(prepare_erst_logs "${!dmesg}" "$((i * 100))")"
last_ids+=("$last_id")
# Add one "random" (non-dmesg) file as well
echo "hello world" >/sys/fs/pstore/foo.bar
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -ne 0 ]]
filename="$(printf "/var/lib/systemd/pstore/%0.16d/dmesg.txt" "$last_id")"
diff "${!dmesg}" "$filename"
grep "hello world" "/var/lib/systemd/pstore/foo.bar"
done
# Check that we kept all previous records as well
for last_id in "${last_ids[@]}"; do
directory="$(printf "/var/lib/systemd/pstore/%0.16d" "$last_id")"
[[ -d "$directory" ]]
[[ "$(file_count "$directory")" -gt 0 ]]
done
: "Backend: ERST; Storage: journal; Unlink: $unlink"
prepare_pstore_config "journal" "$unlink"
last_id="$(prepare_erst_logs "$DUMMY_DMESG_1" 0)"
last_id="$(prepare_erst_logs "$DUMMY_DMESG_0" 0)"
[[ "$unlink" == yes ]] && exp_count=0 || exp_count="$(file_count /sys/fs/pstore/)"
start_pstore
[[ "$(file_count /sys/fs/pstore)" -ge "$exp_count" ]]
[[ "$(file_count /var/lib/systemd/pstore/)" -eq 0 ]]
diff "$DUMMY_DMESG_1" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
diff "$DUMMY_DMESG_0" <(journalctl -o cat --output-fields=FILE --cursor-file=/tmp/journal.cursor | sed "/^$/d")
done
+200
View File
@@ -0,0 +1,200 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# shellcheck disable=SC2016
set -eux
set -o pipefail
# shellcheck source=test/units/util.sh
. "$(dirname "$0")"/util.sh
# FIXME(?):
# - empty ExecStart= is always inserted
# - weird results with systemd-run --property=ExecStart=false true
# - group settings for each section?
# - i.e systemd-run --remain-after-exit --on-clock-change
# --timer-property=After=systemd-journald.service true
# generates a unit that has two [Unit] and two [Timer] sections
systemd-run --help --no-pager
systemd-run --version
systemd-run --no-ask-password true
export PARENT_FOO=bar
touch /tmp/public-marker
: "Transient service (system daemon)"
systemd-run --wait --pipe \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --system \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice=foo.slice \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice-inherit \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.service$ ]]'
systemd-run --wait --pipe --slice-inherit --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.service$ ]]'
# We should not inherit caller's environment
systemd-run --wait --pipe bash -xec '[[ -z "$PARENT_FOO" ]]'
systemd-run --wait --pipe bash -xec '[[ "$PWD" == / ]]'
systemd-run --wait --pipe \
--working-directory="" \
--working-directory=/tmp \
bash -xec '[[ "$PWD" == /tmp ]]'
systemd-run --wait --pipe --same-dir bash -xec "[[ \"\$PWD\" == $PWD ]]"
systemd-run --wait --pipe \
--property=LimitCORE=1M:2M \
--property=LimitCORE=16M:32M \
--property=PrivateTmp=yes \
bash -xec '[[ "$(ulimit -c -S)" -eq 16384 && "$(ulimit -c -H)" -eq 32768 && ! -e /tmp/public-marker ]]'
systemd-run --wait --pipe \
--uid=testuser \
bash -xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == testuser ]]'
systemd-run --wait --pipe \
--gid=testuser \
bash -xec '[[ "$(id -nu)" == root && "$(id -ng)" == testuser ]]'
systemd-run --wait --pipe \
--uid=testuser \
--gid=root \
bash -xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == root ]]'
systemd-run --wait --pipe --expand-environment=no \
--nice=10 \
bash -xec 'read -r -a SELF_STAT </proc/self/stat && [[ "${SELF_STAT[18]}" -eq 10 ]]'
systemd-run --wait --pipe \
--setenv=ENV_HELLO="nope" \
--setenv=ENV_HELLO="env world" \
--setenv=EMPTY= \
--setenv=PARENT_FOO \
--property=Environment="ALSO_HELLO='also world'" \
bash -xec '[[ "$ENV_HELLO" == "env world" && -z "$EMPTY" && "$PARENT_FOO" == bar && "$ALSO_HELLO" == "also world" ]]'
UNIT="service-0-$RANDOM"
systemd-run --remain-after-exit --unit="$UNIT" \
--service-type=simple \
--service-type=oneshot \
true
systemctl cat "$UNIT"
grep -q "^Type=oneshot" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT"
(! systemctl cat "$UNIT")
: "Transient service (user daemon)"
systemd-run --wait --pipe --user --machine=testuser@ \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /user\.slice/.+/run-.+\.service$ ]]'
systemd-run --wait --pipe --user --machine=testuser@ \
bash -xec '[[ "$(id -nu)" == testuser && "$(id -ng)" == testuser ]]'
: "Transient scope (system daemon)"
systemd-run --scope \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
systemd-run --scope --system \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice=foo.slice \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /foo\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice-inherit \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/run-.+\.scope$ ]]'
systemd-run --scope --slice-inherit --slice=foo \
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.scope$ ]]'
# We should inherit caller's environment
systemd-run --scope bash -xec '[[ "$PARENT_FOO" == bar ]]'
: "Transient scope (user daemon)"
# FIXME: https://github.com/systemd/systemd/issues/27883
#systemd-run --scope --user --machine=testuser@ \
# bash -xec '[[ "$(</proc/self/cgroup)" =~ /user\.slice/run-.+\.scope$ ]]'
# We should inherit caller's environment
#systemd-run --scope --user --machine=testuser@ bash -xec '[[ "$PARENT_FOO" == bar ]]'
: "Transient timer unit"
UNIT="timer-0-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--timer-property=OnUnitInactiveSec=16h \
true
systemctl cat "$UNIT.service" "$UNIT.timer"
grep -q "^OnUnitInactiveSec=16h$" "/run/systemd/transient/$UNIT.timer"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT.timer" "$UNIT.service" || :
UNIT="timer-1-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--on-active=10 \
--on-active=30s \
--on-boot=1s \
--on-startup=2m \
--on-unit-active=3h20m \
--on-unit-inactive="5d 4m 32s" \
--on-calendar="mon,fri *-1/2-1,3 *:30:45" \
--on-clock-change \
--on-clock-change \
--on-timezone-change \
--timer-property=After=systemd-journald.service \
--description="Hello world" \
--description="My Fancy Timer" \
true
systemctl cat "$UNIT.service" "$UNIT.timer"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.service"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.timer"
grep -q "^Description=My Fancy Timer$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnActiveSec=10s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnActiveSec=30s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnBootSec=1s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnStartupSec=2min$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnUnitActiveSec=3h 20min$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnUnitInactiveSec=5d 4min 32s$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnCalendar=mon,fri \*\-1/2\-1,3 \*:30:45$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnClockChange=yes$" "/run/systemd/transient/$UNIT.timer"
grep -q "^OnTimezoneChange=yes$" "/run/systemd/transient/$UNIT.timer"
grep -q "^After=systemd-journald.service$" "/run/systemd/transient/$UNIT.timer"
grep -q "^Description=My Fancy Timer$" "/run/systemd/transient/$UNIT.service"
grep -q "^RemainAfterExit=yes$" "/run/systemd/transient/$UNIT.service"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
(! grep -q "^After=systemd-journald.service$" "/run/systemd/transient/$UNIT.service")
systemctl stop "$UNIT.timer" "$UNIT.service" || :
: "Transient path unit"
UNIT="path-0-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--path-property=PathExists=/tmp \
--path-property=PathExists=/tmp/foo \
--path-property=PathChanged=/root/bar \
true
systemctl cat "$UNIT.service" "$UNIT.path"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.service"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.path"
grep -q "^PathExists=/tmp$" "/run/systemd/transient/$UNIT.path"
grep -q "^PathExists=/tmp/foo$" "/run/systemd/transient/$UNIT.path"
grep -q "^PathChanged=/root/bar$" "/run/systemd/transient/$UNIT.path"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT.path" "$UNIT.service" || :
: "Transient socket unit"
UNIT="socket-0-$RANDOM"
systemd-run --remain-after-exit \
--unit="$UNIT" \
--socket-property=ListenFIFO=/tmp/socket.fifo \
--socket-property=SocketMode=0666 \
--socket-property=SocketMode=0644 \
true
systemctl cat "$UNIT.service" "$UNIT.socket"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.service"
systemd-analyze verify --recursive-errors=no "/run/systemd/transient/$UNIT.socket"
grep -q "^ListenFIFO=/tmp/socket.fifo$" "/run/systemd/transient/$UNIT.socket"
grep -q "^SocketMode=0666$" "/run/systemd/transient/$UNIT.socket"
grep -q "^SocketMode=0644$" "/run/systemd/transient/$UNIT.socket"
grep -qE "^ExecStart=.*/bin/true.*$" "/run/systemd/transient/$UNIT.service"
systemctl stop "$UNIT.socket" "$UNIT.service" || :
(! systemd-run)
(! systemd-run "")
(! systemd-run --wait --pipe --slice=foo.service true)
for opt in nice on-{active,boot,calendar,startup,unit-active,unit-inactive} property service-type setenv; do
(! systemd-run "--$opt=" true)
(! systemd-run "--$opt=''" true)
done