core: add counter for soft-reboot iterations

Allow to query via D-Bus how many times the current booted system has
been soft rebooted
This commit is contained in:
Luca Boccassi 2024-03-27 00:30:45 +00:00
parent 7addfba9c4
commit 66f35161f6
6 changed files with 36 additions and 3 deletions

View 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>

View 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),

View 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);

View 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++) {

View 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) {

View file

@ -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"