]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: clean up check_triggering_units
authorMike Yuan <me@yhndnzj.com>
Tue, 26 Sep 2023 14:26:07 +0000 (22:26 +0800)
committerMike Yuan <me@yhndnzj.com>
Wed, 27 Sep 2023 21:24:51 +0000 (05:24 +0800)
Preparation for #311

src/systemctl/systemctl-start-unit.c
src/systemctl/systemctl-util.c
src/systemctl/systemctl-util.h

index 551e6f6768599be1d780b53ef048d4c421e1a26f..bec2249c8249ee54eb74388b9f15226c7b3f1fbe 100644 (file)
@@ -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) {
index 10df0087b4450babb79ff81812458a074bdcaf7e..2498725d3f4e593f616729ffdae0283e984c5c15 100644 (file)
@@ -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;
index 344075722adc27597cd3a50fa1a6097866bea8a2..7bddef07ef440fed4b7019d0ae45d0ca1bf46e5f 100644 (file)
@@ -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);