mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
core: expose transactions with ordering cycle
Closes #3829
Alternative to #35417
I don't think the individual "WasOnDependencyCycle" attrs on units
are particularly helpful and comprehensible, as it's really about
the dep relationship between them. And as discussed, the dependency
cycle is not something persistent, rather local to the currently
loaded set of units and shall be reset with daemon-reload (see also
https://github.com/systemd/systemd/issues/35642#issuecomment-2591296586).
Hence, let's report system state as degraded and point users to
the involved transactions when ordering cycles are encountered instead.
Combined with log messages added in 6912eb315f
it should achieve the goal of making ordering cycles more observable,
while avoiding all sorts of subtle bookkeeping in the service manager.
The degraded state can be reset via the existing ResetFailed() manager-wide
method.
This commit is contained in:
@@ -413,6 +413,8 @@ node /org/freedesktop/systemd1 {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly u NFailedJobs = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly at TransactionsWithOrderingCycle = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly d Progress = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly as Environment = ['...', ...];
|
||||
@@ -1103,6 +1105,8 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFailedJobs"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="TransactionsWithOrderingCycle"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Progress"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
|
||||
@@ -1809,6 +1813,9 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<para><varname>NFailedJobs</varname> encodes how many jobs have ever failed in total.</para>
|
||||
|
||||
<para><varname>TransactionsWithOrderingCycle</varname> encodes IDs of transactions that encountered
|
||||
ordering cycle.</para>
|
||||
|
||||
<para><varname>Progress</varname> encodes boot progress as a floating point value between 0.0 and
|
||||
1.0. This value begins at 0.0 at early-boot and ends at 1.0 when boot is finished and is based on the
|
||||
number of executed and queued jobs. After startup, this field is always 1.0 indicating a finished
|
||||
@@ -12465,6 +12472,7 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<para><varname>DefaultRestrictSUIDSGID</varname>,
|
||||
<function>RemoveSubgroupFromUnit()</function>, and
|
||||
<function>KillUnitSubgroup()</function> were added in version 258.</para>
|
||||
<para><varname>TransactionsWithOrderingCycle</varname> was added in version 259.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Unit Objects</title>
|
||||
|
||||
@@ -225,8 +225,8 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago
|
||||
|
||||
<listitem>
|
||||
<para>Check whether any of the specified units is in the "failed" state. If no unit is specified,
|
||||
check whether there are any failed units, which corresponds to the <literal>degraded</literal> state
|
||||
returned by <command>is-system-running</command>. Returns an exit code <constant>0</constant>
|
||||
check whether there are any failed units or ordering cycles, which corresponds to the <literal>degraded</literal>
|
||||
state returned by <command>is-system-running</command>. Returns an exit code <constant>0</constant>
|
||||
if at least one has failed, non-zero otherwise. Unless <option>--quiet</option> is specified, this
|
||||
will also print the current unit or system state to standard output.</para>
|
||||
|
||||
|
||||
@@ -455,6 +455,35 @@ static int property_get_oom_score_adjust(
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
}
|
||||
|
||||
static int property_get_transactions_with_cycle(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "t");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
uint64_t *id;
|
||||
SET_FOREACH(id, m->transactions_with_cycle) {
|
||||
r = sd_bus_message_append_basic(reply, 't', id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
|
||||
Unit *u;
|
||||
int r;
|
||||
@@ -2870,6 +2899,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("NJobs", "u", property_get_hashmap_size, offsetof(Manager, jobs), 0),
|
||||
SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
|
||||
SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
|
||||
SD_BUS_PROPERTY("TransactionsWithOrderingCycle", "at", property_get_transactions_with_cycle, 0, 0),
|
||||
SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
|
||||
SD_BUS_PROPERTY("Environment", "as", property_get_environment, 0, 0),
|
||||
SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
@@ -3675,6 +3675,8 @@ void manager_reset_failed(Manager *m) {
|
||||
|
||||
HASHMAP_FOREACH(u, m->units)
|
||||
unit_reset_failed(u);
|
||||
|
||||
m->transactions_with_cycle = set_free(m->transactions_with_cycle);
|
||||
}
|
||||
|
||||
bool manager_unit_inactive_or_pending(Manager *m, const char *name) {
|
||||
@@ -4623,8 +4625,8 @@ ManagerState manager_state(Manager *m) {
|
||||
return MANAGER_MAINTENANCE;
|
||||
}
|
||||
|
||||
/* Are there any failed units? If so, we are in degraded mode */
|
||||
if (!set_isempty(m->failed_units))
|
||||
/* Are there any failed units or ordering cycles? If so, we are in degraded mode */
|
||||
if (!set_isempty(m->failed_units) || !set_isempty(m->transactions_with_cycle))
|
||||
return MANAGER_DEGRADED;
|
||||
|
||||
return MANAGER_RUNNING;
|
||||
|
||||
@@ -112,6 +112,24 @@ static int manager_context_build_json(sd_json_variant **ret, const char *name, v
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("ControlGroup", m->cgroup_root));
|
||||
}
|
||||
|
||||
static int transactions_with_cycle_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
const Set *ids = userdata;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
uint64_t *id;
|
||||
SET_FOREACH(id, ids) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_UNSIGNED(*id));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int manager_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
dual_timestamp watchdog_last_ping;
|
||||
@@ -154,6 +172,7 @@ static int manager_runtime_build_json(sd_json_variant **ret, const char *name, v
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("NJobs", hashmap_size(m->jobs)),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("NInstalledJobs", m->n_installed_jobs),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("NFailedJobs", m->n_failed_jobs),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("TransactionsWithOrderingCycle", transactions_with_cycle_build_json, m->transactions_with_cycle),
|
||||
SD_JSON_BUILD_PAIR_REAL("Progress", manager_get_progress(m)),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("WatchdogLastPingTimestamp", watchdog_get_last_ping_as_dual_timestamp(&watchdog_last_ping)),
|
||||
SD_JSON_BUILD_PAIR_STRING("SystemState", manager_state_to_string(manager_state(m))),
|
||||
|
||||
@@ -155,6 +155,8 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(NInstalledJobs, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The total amount of failed jobs"),
|
||||
SD_VARLINK_DEFINE_FIELD(NFailedJobs, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("IDs of transactions that encountered ordering cycle"),
|
||||
SD_VARLINK_DEFINE_FIELD(TransactionsWithOrderingCycle, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Boot progress as a floating point value between 0.0 and 1.0"),
|
||||
SD_VARLINK_DEFINE_FIELD(Progress, SD_VARLINK_FLOAT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the hardware watchdog was last pinged"),
|
||||
|
||||
Reference in New Issue
Block a user