systemctl: Support --timestamp for otherwise named properties

`systemctl show`'s `--timestamp` flag is supposed to reformat all
timestamp-based properties. However, the logic for detecting these
properties was incomplete and only checked if the name ended in
Timestamp.

Expand the check to explicitly include some non-"timestamp" named
properties that really are timestamps.

Fixes: https://github.com/systemd/systemd/issues/39282
This commit is contained in:
Chris Down
2025-11-06 07:45:06 +09:00
committed by Yu Watanabe
parent bea3b300bc
commit 8ab6925c5e
4 changed files with 65 additions and 7 deletions
+9 -6
View File
@@ -16,6 +16,14 @@
#include "strv.h"
#include "time-util.h"
bool bus_property_is_timestamp(const char *name) {
assert(name);
/* Trust me, this naming convention is ironclad. Except for these three. Okay four. Well... */
return endswith(name, "Timestamp") ||
STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec");
}
int bus_print_property_value(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *value) {
assert(name);
@@ -104,12 +112,7 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
if (r < 0)
return r;
/* Yes, heuristics! But we can change this check
* should it turn out to not be sufficient */
if (endswith(name, "Timestamp") ||
STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec", "TimeUSec", "RTCTimeUSec"))
if (bus_property_is_timestamp(name))
bus_print_property_value(name, expected_value, flags, FORMAT_TIMESTAMP(u));
/* Managed OOM pressure default implies "unset" and use the default set in oomd.conf. Without
+2
View File
@@ -10,6 +10,8 @@ typedef enum BusPrintPropertyFlags {
typedef int (*bus_message_print_t) (const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags);
bool bus_property_is_timestamp(const char *name);
int bus_print_property_value(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *value);
int bus_print_property_valuef(const char *name, const char *expected_value, BusPrintPropertyFlags flags, const char *fmt, ...) _printf_(4,5);
int bus_message_print_all_properties(sd_bus_message *m, bus_message_print_t func, char **filter, BusPrintPropertyFlags flags, Set **found_properties);
+1 -1
View File
@@ -1215,7 +1215,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
break;
case SD_BUS_TYPE_UINT64:
if (endswith(name, "Timestamp")) {
if (bus_property_is_timestamp(name)) {
uint64_t timestamp;
r = sd_bus_message_read_basic(m, bus_type, &timestamp);
+53
View File
@@ -287,6 +287,59 @@ for value in pretty us µs utc us+utc µs+utc; do
systemctl show -P KernelTimestamp --timestamp="$value"
done
# --timestamp with timer properties (issue #39282)
TIMER1="timestamp-test1-$RANDOM.timer"
SERVICE1="${TIMER1%.timer}.service"
cat >"/run/systemd/system/$SERVICE1" <<EOF
[Service]
Type=oneshot
ExecStart=true
EOF
cat >"/run/systemd/system/$TIMER1" <<EOF
[Timer]
OnCalendar=*-*-* 00:00:00
EOF
systemctl daemon-reload
systemctl start "$TIMER1"
output=$(systemctl show -P NextElapseUSecRealtime --timestamp=unix "$TIMER1")
if [[ ! "$output" =~ ^@[0-9]+$ ]]; then
echo "NextElapseUSecRealtime: expected @<number> with --timestamp=unix, got: $output" >&2
exit 1
fi
systemctl stop "$TIMER1"
rm -f "/run/systemd/system/$TIMER1" "/run/systemd/system/$SERVICE1"
TIMER2="timestamp-test2-$RANDOM.timer"
SERVICE2="${TIMER2%.timer}.service"
cat >"/run/systemd/system/$SERVICE2" <<EOF
[Service]
Type=oneshot
ExecStart=true
EOF
cat >"/run/systemd/system/$TIMER2" <<EOF
[Timer]
OnActiveSec=100ms
EOF
systemctl daemon-reload
systemctl start "$TIMER2"
sleep 0.5
output=$(systemctl show -P LastTriggerUSec --timestamp=unix "$TIMER2")
if [[ ! "$output" =~ ^@[0-9]+$ ]]; then
echo "LastTriggerUSec: expected @<number> with --timestamp=unix, got: $output" >&2
exit 1
fi
systemctl stop "$TIMER2"
rm -f "/run/systemd/system/$TIMER2" "/run/systemd/system/$SERVICE2"
systemctl daemon-reload
# set-default/get-default
test_get_set_default() {
target="$(systemctl get-default "$@")"