@@ -393,8 +393,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) {
|
||||
|
||||
@@ -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,
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user