diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 48e6419130..09a3a9502b 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -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) diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c index 461f6aafb2..e891cef1ef 100644 --- a/src/core/dbus-util.c +++ b/src/core/dbus-util.c @@ -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) { diff --git a/src/core/socket.c b/src/core/socket.c index 7c596182c2..f8fe62c919 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -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); } } diff --git a/src/core/socket.h b/src/core/socket.h index 308a072756..191d27f46d 100644 --- a/src/core/socket.h +++ b/src/core/socket.h @@ -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); diff --git a/test/test-functions b/test/test-functions index 073777a0eb..2502177908 100644 --- a/test/test-functions +++ b/test/test-functions @@ -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 diff --git a/test/units/testsuite-74.pstore.sh b/test/units/testsuite-74.pstore.sh index b8bf5534a1..1b475a3f2a 100755 --- a/test/units/testsuite-74.pstore.sh +++ b/test/units/testsuite-74.pstore.sh @@ -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" </run/systemd/pstore.conf.d/99-test.conf </run/systemd/system/systemd-pstore.service.d/99-StartLimitInterval.conf </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 diff --git a/test/units/testsuite-74.run.sh b/test/units/testsuite-74.run.sh new file mode 100755 index 0000000000..33a8e1ebd2 --- /dev/null +++ b/test/units/testsuite-74.run.sh @@ -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 '[[ "$(