diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 1f30f65bf7..b148a0ee39 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -560,6 +560,8 @@ node /org/freedesktop/systemd1 {
readonly i DefaultOOMScoreAdjust = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s CtrlAltDelBurstAction = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly u SoftRebootsCount = ...;
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
@@ -1251,6 +1253,8 @@ node /org/freedesktop/systemd1 {
+
+
@@ -1787,6 +1791,9 @@ node /org/freedesktop/systemd1 {
UnitPath encodes the currently active unit file search path. It is an array of
file system paths encoded as strings.
+ SoftRebootsCount encodes how many soft-reboots were successfully completed
+ since the last full boot.
+
Virtualization contains a short ID string describing the virtualization
technology the system runs in. On bare-metal hardware this is the empty string. Otherwise, it contains
an identifier such as kvm, vmware and so on. For a full list of
@@ -11993,8 +12000,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
SoftReboot(), and
DumpUnitFileDescriptorStore() were added in version 254.
StartAuxiliaryScope(),
- SoftRebootStartTimestamp and
- SoftRebootStartTimestampMonotonic were added in version 256.
+ SoftRebootStartTimestamp,
+ SoftRebootStartTimestampMonotonic and
+ SoftRebootsCount were added in version 256.
Unit Objects
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index e7ad850d35..bba466b900 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -3140,6 +3140,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, defaults.oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultOOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CtrlAltDelBurstAction", "s", bus_property_get_emergency_action, offsetof(Manager, cad_burst_action), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("SoftRebootsCount", "u", bus_property_get_unsigned, offsetof(Manager, soft_reboots_count), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD_WITH_ARGS("GetUnit",
SD_BUS_ARGS("s", name),
diff --git a/src/core/main.c b/src/core/main.c
index b086122a8c..1aeab10ddb 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -3192,6 +3192,11 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ /* If we got a SoftRebootStart timestamp during deserialization, then we are in a new soft-reboot
+ * iteration, so bump the counter now before starting units, so that they can reliably read it. */
+ if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_SOFTREBOOT_START]))
+ m->soft_reboots_count++;
+
/* This will close all file descriptors that were opened, but not claimed by any unit. */
fds = fdset_free(fds);
arg_serialization = safe_fclose(arg_serialization);
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
index 3af6723e5f..284f4987a2 100644
--- a/src/core/manager-serialize.c
+++ b/src/core/manager-serialize.c
@@ -109,6 +109,8 @@ int manager_serialize(
(void) serialize_usec(f, "pretimeout-watchdog-overridden", m->watchdog_overridden[WATCHDOG_PRETIMEOUT]);
(void) serialize_item(f, "pretimeout-watchdog-governor-overridden", m->watchdog_pretimeout_governor_overridden);
+ (void) serialize_item_format(f, "soft-reboots-count", "%u", m->soft_reboots_count);
+
for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
_cleanup_free_ char *joined = NULL;
@@ -517,7 +519,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
(void) varlink_server_deserialize_one(m->varlink_server, val, fds);
} else if ((val = startswith(l, "dump-ratelimit=")))
deserialize_ratelimit(&m->dump_ratelimit, "dump-ratelimit", val);
- else {
+ else if ((val = startswith(l, "soft-reboots-count="))) {
+ unsigned n;
+
+ if (safe_atou(val, &n) < 0)
+ log_notice("Failed to parse soft reboots counter '%s', ignoring.", val);
+ else
+ m->soft_reboots_count = n;
+ } else {
ManagerTimestamp q;
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
diff --git a/src/core/manager.h b/src/core/manager.h
index c1782ea5f7..0e2531a4a7 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -504,6 +504,8 @@ struct Manager {
/* Pin the systemd-executor binary, so that it never changes until re-exec, ensuring we don't have
* serialization/deserialization compatibility issues during upgrades. */
int executor_fd;
+
+ unsigned soft_reboots_count;
};
static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
diff --git a/test/units/testsuite-82.sh b/test/units/testsuite-82.sh
index 224cd75c7f..8ff69c90e4 100755
--- a/test/units/testsuite-82.sh
+++ b/test/units/testsuite-82.sh
@@ -27,6 +27,8 @@ if [ -f /run/testsuite82.touch3 ]; then
echo "This is the fourth boot!"
systemd-notify --status="Fourth Boot"
+ test "$(busctl -j get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager SoftRebootsCount | jq -r '.data')" -eq 3
+
rm /run/testsuite82.touch3
mount
rmdir /original-root /run/nextroot
@@ -52,6 +54,8 @@ elif [ -f /run/testsuite82.touch2 ]; then
echo "This is the third boot!"
systemd-notify --status="Third Boot"
+ test "$(busctl -j get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager SoftRebootsCount | jq -r '.data')" -eq 2
+
rm /run/testsuite82.touch2
# Check that the fdstore entry still exists
@@ -95,6 +99,8 @@ elif [ -f /run/testsuite82.touch ]; then
echo "This is the second boot!"
systemd-notify --status="Second Boot"
+ test "$(busctl -j get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager SoftRebootsCount | jq -r '.data')" -eq 1
+
# Clean up what we created earlier
rm /run/testsuite82.touch
@@ -151,6 +157,8 @@ else
# This is the first boot
systemd-notify --status="First Boot"
+ test "$(busctl -j get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager SoftRebootsCount | jq -r '.data')" -eq 0
+
# Let's upload an fd to the fdstore, so that we can verify fdstore passing works correctly
T="/dev/shm/fdstore.$RANDOM"
echo "wuffwuff" >"$T"