]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add counter for soft-reboot iterations 31980/head
authorLuca Boccassi <bluca@debian.org>
Wed, 27 Mar 2024 00:30:45 +0000 (00:30 +0000)
committerLuca Boccassi <bluca@debian.org>
Wed, 27 Mar 2024 01:27:35 +0000 (01:27 +0000)
Allow to query via D-Bus how many times the current booted system has
been soft rebooted

man/org.freedesktop.systemd1.xml
src/core/dbus-manager.c
src/core/main.c
src/core/manager-serialize.c
src/core/manager.h
test/units/testsuite-82.sh

index 1f30f65bf7cab1ec9abe9fe90b0d6266111714af..b148a0ee397ba1b9ab98460ec51a5daa7130c517 100644 (file)
@@ -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 {
 
     <variablelist class="dbus-property" generated="True" extra-ref="CtrlAltDelBurstAction"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="SoftRebootsCount"/>
+
     <!--End of Autogenerated section-->
 
     <refsect2>
@@ -1787,6 +1791,9 @@ node /org/freedesktop/systemd1 {
       <para><varname>UnitPath</varname> encodes the currently active unit file search path. It is an array of
       file system paths encoded as strings.</para>
 
+      <para><varname>SoftRebootsCount</varname> encodes how many soft-reboots were successfully completed
+      since the last full boot.</para>
+
       <para><varname>Virtualization</varname> 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 <literal>kvm</literal>, <literal>vmware</literal> and so on. For a full list of
@@ -11993,8 +12000,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
       <function>SoftReboot()</function>, and
       <function>DumpUnitFileDescriptorStore()</function> were added in version 254.</para>
       <para><function>StartAuxiliaryScope()</function>,
-      <varname>SoftRebootStartTimestamp</varname> and
-      <varname>SoftRebootStartTimestampMonotonic</varname> were added in version 256.</para>
+      <varname>SoftRebootStartTimestamp</varname>,
+      <varname>SoftRebootStartTimestampMonotonic</varname> and
+      <varname>SoftRebootsCount</varname> were added in version 256.</para>
     </refsect2>
     <refsect2>
       <title>Unit Objects</title>
index e7ad850d35ac73f221f2f6ecaca6afae1d163774..bba466b90089b0427c573dd40914d509b0d1d0d5 100644 (file)
@@ -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),
index b086122a8c81cf23d5cab1563b89b437b33f83ae..1aeab10ddbc588eabf8f22a3282ebf55c54240c6 100644 (file)
@@ -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);
index 3af6723e5f640a8c860980053e22b61415e3fb79..284f4987a284309e02b5a01c0b5ade00153947ef 100644 (file)
@@ -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++) {
index c1782ea5f74ea2871f36d9ec51d6ff82212d0677..0e2531a4a7d9007666f6bfb58e05d671cecc0853 100644 (file)
@@ -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) {
index 224cd75c7fead009a23de405f186dd1b90d8eade..8ff69c90e4d08cf2cb048fb1d53185d18ad393f1 100755 (executable)
@@ -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"