chiark / gitweb /
udev: allow firmware requests to bypass the dependency tracking
[elogind.git] / src / systemctl / systemctl.c
index 17a8497dccd7174c3a15aa32068c7c6b3a986a29..a4290c4754939d9f4fa0419b2dad2a847b88c795 100644 (file)
@@ -63,6 +63,7 @@
 #include "install.h"
 #include "logs-show.h"
 #include "path-util.h"
+#include "socket-util.h"
 
 static const char *arg_type = NULL;
 static const char *arg_load_state = NULL;
@@ -185,6 +186,14 @@ static void polkit_agent_open_if_enabled(void) {
 }
 #endif
 
+static const char *ansi_highlight(bool b) {
+
+        if (!on_tty())
+                return "";
+
+        return b ? ANSI_HIGHLIGHT_ON : ANSI_HIGHLIGHT_OFF;
+}
+
 static const char *ansi_highlight_red(bool b) {
 
         if (!on_tty())
@@ -371,15 +380,6 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
         } else
                 id_len = max_id_len;
 
-        if (!arg_no_legend) {
-                printf("%-*s %-6s %-*s %-*s %-*s ", id_len, "UNIT", "LOAD",
-                       active_len, "ACTIVE", sub_len, "SUB", job_len, "JOB");
-                if (!arg_full && arg_no_pager)
-                        printf("%.*s\n", desc_len, "DESCRIPTION");
-                else
-                        printf("%s\n", "DESCRIPTION");
-        }
-
         for (u = unit_infos; u < unit_infos + c; u++) {
                 char *e;
                 const char *on_loaded, *off_loaded;
@@ -388,6 +388,15 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
                 if (!output_show_unit(u))
                         continue;
 
+                if (!n_shown && !arg_no_legend) {
+                        printf("%-*s %-6s %-*s %-*s %-*s ", id_len, "UNIT", "LOAD",
+                               active_len, "ACTIVE", sub_len, "SUB", job_len, "JOB");
+                        if (!arg_full && arg_no_pager)
+                                printf("%.*s\n", desc_len, "DESCRIPTION");
+                        else
+                                printf("%s\n", "DESCRIPTION");
+                }
+
                 n_shown++;
 
                 if (streq(u->load_state, "error")) {
@@ -419,17 +428,28 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
         }
 
         if (!arg_no_legend) {
-                printf("\nLOAD   = Reflects whether the unit definition was properly loaded.\n"
-                       "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
-                       "SUB    = The low-level unit activation state, values depend on unit type.\n"
-                       "JOB    = Pending job for the unit.\n");
+                const char *on, *off;
+
+                if (n_shown) {
+                        printf("\nLOAD   = Reflects whether the unit definition was properly loaded.\n"
+                               "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
+                               "SUB    = The low-level unit activation state, values depend on unit type.\n"
+                               "JOB    = Pending job for the unit.\n\n");
+                        on = ansi_highlight(true);
+                        off = ansi_highlight(false);
+                } else {
+                        on = ansi_highlight_red(true);
+                        off = ansi_highlight_red(false);
+                }
 
                 if (arg_all)
-                        printf("\n%u loaded units listed.\n"
-                               "To show all installed unit files use 'systemctl list-unit-files'.\n", n_shown);
+                        printf("%s%u loaded units listed.%s\n"
+                               "To show all installed unit files use 'systemctl list-unit-files'.\n",
+                               on, n_shown, off);
                 else
-                        printf("\n%u loaded units listed. Pass --all to see loaded but inactive units, too.\n"
-                               "To show all installed unit files use 'systemctl list-unit-files'.\n", n_shown);
+                        printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
+                               "To show all installed unit files use 'systemctl list-unit-files'.\n",
+                               on, n_shown, off);
         }
 }
 
@@ -1321,7 +1341,10 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) {
                         return -ECONNREFUSED;
                 }
 
-                if (!arg_quiet && d.result) {
+                if (!d.result)
+                        goto free_name;
+
+                if (!arg_quiet) {
                         if (streq(d.result, "timeout"))
                                 log_error("Job for %s timed out.", strna(d.name));
                         else if (streq(d.result, "canceled"))
@@ -1342,11 +1365,12 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) {
                 free(d.result);
                 d.result = NULL;
 
+        free_name:
                 free(d.name);
                 d.name = NULL;
         }
 
-        /* This is slightly dirty, since we don't undo the filter registration. */
+        dbus_connection_remove_filter(bus, wait_filter, &d);
         return r;
 }
 
@@ -1440,22 +1464,26 @@ static void check_triggering_units(
                 DBusConnection *bus,
                 const char *unit_name) {
 
-        DBusMessage *reply = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         DBusMessageIter iter, sub;
         char *service_trigger = NULL;
         const char *interface = "org.freedesktop.systemd1.Unit",
                    *triggered_by_property = "TriggeredBy";
 
-        char *unit_path = NULL, *n = NULL;
+        char _cleanup_free_ *unit_path = NULL, *n = NULL;
         bool print_warning_label = true;
         int r;
 
         n = unit_name_mangle(unit_name);
-        unit_path = unit_dbus_path_from_name(n ? n : unit_name);
-        free(n);
+        if (!n) {
+                log_oom();
+                return;
+        }
+
+        unit_path = unit_dbus_path_from_name(n);
         if (!unit_path) {
-                log_error("Could not allocate dbus path.");
-                goto finish;
+                log_oom();
+                return;
         }
 
         r = bus_method_call_with_reply (
@@ -1470,13 +1498,12 @@ static void check_triggering_units(
                         DBUS_TYPE_STRING, &triggered_by_property,
                         DBUS_TYPE_INVALID);
         if (r)
-                goto finish;
+                return;
 
         if (!dbus_message_iter_init(reply, &iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
                 log_error("Failed to parse reply.");
-                goto finish;
-
+                return;
         }
 
         dbus_message_iter_recurse(&iter, &sub);
@@ -1487,14 +1514,14 @@ static void check_triggering_units(
 
                 if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) {
                         log_error("Failed to parse reply.");
-                        goto finish;
+                        return;
                 }
 
                 dbus_message_iter_get_basic(&sub, &service_trigger);
 
                 r = check_one_unit(bus, service_trigger, true);
                 if (r < 0)
-                        goto finish;
+                        return;
                 if (r == 0) {
                         if (print_warning_label) {
                                 log_warning("Warning: Stopping %s, but it can still be activated by:", unit_name);
@@ -1505,11 +1532,6 @@ static void check_triggering_units(
 
                 dbus_message_iter_next(&sub);
         }
-finish:
-        if (reply)
-                dbus_message_unref(reply);
-
-        free(unit_path);
 }
 
 static int start_unit_one(
@@ -1520,7 +1542,7 @@ static int start_unit_one(
                 DBusError *error,
                 Set *s) {
 
-        DBusMessage *reply = NULL;
+        _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         const char *path;
         int r;
         _cleanup_free_ char *n, *p = NULL;
@@ -1553,15 +1575,14 @@ static int start_unit_one(
                 else
                         log_error("Failed to issue method call: %s", bus_error_message(error));
 
-                goto finish;
+                return r;
         }
 
         if (!dbus_message_get_args(reply, error,
                                    DBUS_TYPE_OBJECT_PATH, &path,
                                    DBUS_TYPE_INVALID)) {
                 log_error("Failed to parse reply: %s", bus_error_message(error));
-                r = -EIO;
-                goto finish;
+                return -EIO;
         }
 
         if (need_daemon_reload(bus, n))
@@ -1570,32 +1591,19 @@ static int start_unit_one(
 
         if (s) {
                 p = strdup(path);
-                if (!p) {
-                        r = log_oom();
-                        goto finish;
-                }
+                if (!p)
+                        return log_oom();
 
                 r = set_put(s, p);
                 if (r < 0) {
                         log_error("Failed to add path to set.");
-                        goto finish;
+                        return r;
                 }
 
                 p = NULL;
         }
 
-        /* When stopping a unit warn if it can still be triggered by
-         * another active unit (socket, path, timer) */
-        if (!arg_quiet && streq(method, "StopUnit"))
-                check_triggering_units(bus, name);
-
-        r = 0;
-
-finish:
-        if (reply)
-                dbus_message_unref(reply);
-
-        return r;
+        return 0;
 }
 
 static enum action verb_to_action(const char *verb) {
@@ -1729,6 +1737,16 @@ static int start_unit(DBusConnection *bus, char **args) {
                         ret = r;
                         goto finish;
                 }
+
+                /* When stopping units, warn if they can still be triggered by
+                 * another active unit (socket, path, timer) */
+                if (!arg_quiet && streq(method, "StopUnit")) {
+                        if (one_name)
+                                check_triggering_units(bus, one_name);
+                        else
+                                STRV_FOREACH(name, args+1)
+                                        check_triggering_units(bus, *name);
+                }
         }
 
 finish:
@@ -2280,9 +2298,13 @@ static void print_status_info(UnitStatusInfo *i) {
                         on_tty() * OUTPUT_COLOR;
 
                 printf("\n");
-                show_journal_by_unit(i->id, arg_output, 0,
+                show_journal_by_unit(stdout,
+                                     i->id,
+                                     arg_output,
+                                     0,
                                      i->inactive_exit_timestamp_monotonic,
-                                     arg_lines, flags);
+                                     arg_lines,
+                                     flags);
         }
 
         if (i->need_daemon_reload)
@@ -3410,7 +3432,7 @@ static int enable_sysv_units(char **args) {
          * afterwards only the native units remain */
 
         zero(paths);
-        r = lookup_paths_init(&paths, MANAGER_SYSTEM, false, NULL, NULL, NULL);
+        r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
         if (r < 0)
                 return r;