Skip to content

Commit

Permalink
systemctl: clean up check_triggering_units
Browse files Browse the repository at this point in the history
Preparation for #311

(cherry picked from commit 002db03)
  • Loading branch information
YHNdnzj authored and bluca committed Nov 9, 2023
1 parent 589afac commit 2132a23
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/systemctl/systemctl-start-unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ int verb_start(int argc, char *argv[], void *userdata) {
/* When stopping units, warn if they can still be triggered by
* another active unit (socket, path, timer) */
if (!arg_quiet)
STRV_FOREACH(name, stopped_units)
(void) check_triggering_units(bus, *name);
STRV_FOREACH(unit, stopped_units)
warn_triggering_units(bus, *unit, "Stopping", /* ignore_masked = */ true);
}

if (arg_wait) {
Expand Down
71 changes: 52 additions & 19 deletions src/systemctl/systemctl-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,26 +315,33 @@ int expand_unit_names(sd_bus *bus, char **names, const char* suffix, char ***ret
return 0;
}

int check_triggering_units(sd_bus *bus, const char *unit) {
int get_active_triggering_units(sd_bus *bus, const char *unit, bool ignore_masked, char ***ret) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *n = NULL, *dbus_path = NULL, *load_state = NULL;
_cleanup_strv_free_ char **triggered_by = NULL;
_cleanup_strv_free_ char **triggered_by = NULL, **active = NULL;
_cleanup_free_ char *name = NULL, *dbus_path = NULL;
int r;

r = unit_name_mangle(unit, 0, &n);
if (r < 0)
return log_error_errno(r, "Failed to mangle unit name: %m");
assert(bus);
assert(unit);
assert(ret);

r = unit_load_state(bus, n, &load_state);
r = unit_name_mangle(unit, 0, &name);
if (r < 0)
return r;

if (streq(load_state, "masked"))
return 0;
if (ignore_masked) {
r = unit_is_masked(bus, name);
if (r < 0)
return r;
if (r > 0) {
*ret = NULL;
return 0;
}
}

dbus_path = unit_dbus_path_from_name(n);
dbus_path = unit_dbus_path_from_name(name);
if (!dbus_path)
return log_oom();
return -ENOMEM;

r = sd_bus_get_property_strv(
bus,
Expand All @@ -345,9 +352,9 @@ int check_triggering_units(sd_bus *bus, const char *unit) {
&error,
&triggered_by);
if (r < 0)
return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
return log_debug_errno(r, "Failed to get TriggeredBy property of unit '%s': %s",
name, bus_error_message(&error, r));

bool first = true;
STRV_FOREACH(i, triggered_by) {
UnitActiveState active_state;

Expand All @@ -358,17 +365,43 @@ int check_triggering_units(sd_bus *bus, const char *unit) {
if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING))
continue;

if (first) {
log_warning("Warning: Stopping %s, but it can still be activated by:", n);
first = false;
}

log_warning(" %s", *i);
r = strv_extend(&active, *i);
if (r < 0)
return r;
}

*ret = TAKE_PTR(active);
return 0;
}

void warn_triggering_units(sd_bus *bus, const char *unit, const char *operation, bool ignore_masked) {
_cleanup_strv_free_ char **triggered_by = NULL;
_cleanup_free_ char *joined = NULL;
int r;

assert(bus);
assert(unit);
assert(operation);

r = get_active_triggering_units(bus, unit, ignore_masked, &triggered_by);
if (r < 0) {
log_warning_errno(r,
"Failed to get triggering units for '%s', ignoring: %m", unit);
return;
}

if (strv_isempty(triggered_by))
return;

joined = strv_join(triggered_by, ", ");
if (!joined)
return (void) log_oom();

log_warning("%s '%s', but its triggering units are still active:\n"
"%s",
operation, unit, joined);
}

int need_daemon_reload(sd_bus *bus, const char *unit) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
const char *path;
Expand Down
3 changes: 2 additions & 1 deletion src/systemctl/systemctl-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ int get_sub_state_one_unit(sd_bus *bus, const char *unit, char **ret_sub_state);
int get_unit_list(sd_bus *bus, const char *machine, char **patterns, UnitInfo **unit_infos, int c, sd_bus_message **ret_reply);
int expand_unit_names(sd_bus *bus, char **names, const char* suffix, char ***ret, bool *ret_expanded);

int check_triggering_units(sd_bus *bus, const char *unit);
int get_active_triggering_units(sd_bus *bus, const char *unit, bool ignore_masked, char ***ret);
void warn_triggering_units(sd_bus *bus, const char *unit, const char *operation, bool ignore_masked);

int need_daemon_reload(sd_bus *bus, const char *unit);

Expand Down

0 comments on commit 2132a23

Please sign in to comment.