chiark / gitweb /
systemctl: don't actually reboot/poweroff/halt if only a wtmp update is requested
[elogind.git] / src / systemctl.c
index 5c91c325cd2d5ae8b5012248dbb163f35ad7f117..01deafe2a13b1d0edc3bcfe8633343ccc1eab471 100644 (file)
@@ -42,6 +42,7 @@
 #include "initreq.h"
 #include "strv.h"
 #include "dbus-common.h"
+#include "cgroup-show.h"
 
 static const char *arg_type = NULL;
 static const char *arg_property = NULL;
@@ -75,6 +76,8 @@ enum action {
         _ACTION_MAX
 } arg_action = ACTION_SYSTEMCTL;
 
+static bool private_bus = false;
+
 static bool error_is_no_service(DBusError *error) {
 
         assert(error);
@@ -107,31 +110,6 @@ static int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *da
         return 0;
 }
 
-static int columns(void) {
-        static int parsed_columns = 0;
-        const char *e;
-
-        if (parsed_columns > 0)
-                return parsed_columns;
-
-        if ((e = getenv("COLUMNS")))
-                parsed_columns = atoi(e);
-
-        if (parsed_columns <= 0) {
-                struct winsize ws;
-                zero(ws);
-
-                if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) >= 0)
-                        parsed_columns = ws.ws_col;
-        }
-
-        if (parsed_columns <= 0)
-                parsed_columns = 80;
-
-        return parsed_columns;
-
-}
-
 static void warn_wall(enum action action) {
         static const char *table[_ACTION_MAX] = {
                 [ACTION_HALT]      = "The system is going down for system halt NOW!",
@@ -237,20 +215,26 @@ static int list_units(DBusConnection *bus, char **args, unsigned n) {
 
                         int a = 0, b = 0;
 
+                        if (streq(active_state, "maintenance"))
+                                fputs(ANSI_HIGHLIGHT_ON, stdout);
+
                         printf("%-45s %-6s %-12s %-12s%n", id, load_state, active_state, sub_state, &a);
 
                         if (job_id != 0)
                                 printf(" %-15s%n", job_type, &b);
                         else
-                                b = 1 + 16;
+                                b = 1 + 15;
 
                         if (a + b + 2 < columns()) {
                                 if (job_id == 0)
                                         printf("                ");
 
-                                printf("%.*s", columns() - a - b - 2, description);
+                                printf(" %.*s", columns() - a - b - 2, description);
                         }
 
+                        if (streq(active_state, "maintenance"))
+                                fputs(ANSI_HIGHLIGHT_OFF, stdout);
+
                         fputs("\n", stdout);
                         k++;
                 }
@@ -521,10 +505,10 @@ static DBusHandlerResult wait_filter(DBusConnection *connection, DBusMessage *me
 
         dbus_error_init(&error);
 
-        /* log_debug("Got D-Bus request: %s.%s() on %s", */
-        /*           dbus_message_get_interface(message), */
-        /*           dbus_message_get_member(message), */
-        /*           dbus_message_get_path(message)); */
+        log_debug("Got D-Bus request: %s.%s() on %s",
+                  dbus_message_get_interface(message),
+                  dbus_message_get_member(message),
+                  dbus_message_get_path(message));
 
         if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
                 log_error("Warning! D-Bus connection terminated.");
@@ -561,6 +545,9 @@ static int enable_wait_for_jobs(DBusConnection *bus) {
 
         assert(bus);
 
+        if (private_bus)
+                return 0;
+
         dbus_error_init(&error);
         dbus_bus_add_match(bus,
                            "type='signal',"
@@ -935,53 +922,6 @@ finish:
         return r;
 }
 
-static void show_cgroup(const char *name) {
-        char *fn;
-        FILE *f;
-        pid_t last = 0;
-
-        if (!startswith(name, "name=systemd:"))
-                return;
-
-        if (asprintf(&fn, "/cgroup/systemd/%s/tasks", name + 13) < 0)
-                return;
-
-        f = fopen(fn, "r");
-        free(fn);
-
-        if (!f)
-                return;
-
-        while (!feof(f)) {
-                unsigned long ul;
-
-                if (fscanf(f, "%lu", &ul) != 1)
-                        break;
-
-                if (ul <= 0)
-                        continue;
-
-                if (last > 0) {
-                        char *t = NULL;
-                        get_process_cmdline(last, 60, &t);
-                        printf("\t\t  \342\224\234 %lu %s\n", (unsigned long) last, strna(t));
-                        free(t);
-                } else
-                        printf("\t\t  \342\224\202\n");
-
-                last = (pid_t) ul;
-        }
-
-        if (last > 0) {
-                char *t = NULL;
-                get_process_cmdline(last, 60, &t);
-                printf("\t\t  \342\224\224 %lu %s\n", (unsigned long) last, strna(t));
-                free(t);
-        }
-
-        fclose(f);
-}
-
 typedef struct UnitStatusInfo {
         const char *id;
         const char *load_state;
@@ -1103,8 +1043,16 @@ static void print_status_info(UnitStatusInfo *i) {
         }
 
         if (i->default_control_group) {
+                unsigned c;
+
                 printf("\t  CGroup: %s\n", i->default_control_group);
-                show_cgroup(i->default_control_group);
+
+                if ((c = columns()) > 18)
+                        c -= 18;
+                else
+                        c = 0;
+
+                show_cgroup_recursive(i->default_control_group, "\t\t  ", c);
         }
 }
 
@@ -1720,10 +1668,10 @@ static DBusHandlerResult monitor_filter(DBusConnection *connection, DBusMessage
 
         dbus_error_init(&error);
 
-        /* log_debug("Got D-Bus request: %s.%s() on %s", */
-        /*           dbus_message_get_interface(message), */
-        /*           dbus_message_get_member(message), */
-        /*           dbus_message_get_path(message)); */
+        log_debug("Got D-Bus request: %s.%s() on %s",
+                  dbus_message_get_interface(message),
+                  dbus_message_get_member(message),
+                  dbus_message_get_path(message));
 
         if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
                 log_error("Warning! D-Bus connection terminated.");
@@ -1849,43 +1797,45 @@ static int monitor(DBusConnection *bus, char **args, unsigned n) {
 
         dbus_error_init(&error);
 
-        dbus_bus_add_match(bus,
-                           "type='signal',"
-                           "sender='org.freedesktop.systemd1',"
-                           "interface='org.freedesktop.systemd1.Manager',"
-                           "path='/org/freedesktop/systemd1'",
-                           &error);
+        if (!private_bus) {
+                dbus_bus_add_match(bus,
+                                   "type='signal',"
+                                   "sender='org.freedesktop.systemd1',"
+                                   "interface='org.freedesktop.systemd1.Manager',"
+                                   "path='/org/freedesktop/systemd1'",
+                                   &error);
 
-        if (dbus_error_is_set(&error)) {
-                log_error("Failed to add match: %s", error.message);
-                r = -EIO;
-                goto finish;
-        }
+                if (dbus_error_is_set(&error)) {
+                        log_error("Failed to add match: %s", error.message);
+                        r = -EIO;
+                        goto finish;
+                }
 
-        dbus_bus_add_match(bus,
-                           "type='signal',"
-                           "sender='org.freedesktop.systemd1',"
-                           "interface='org.freedesktop.systemd1.Unit',"
-                           "member='Changed'",
-                           &error);
+                dbus_bus_add_match(bus,
+                                   "type='signal',"
+                                   "sender='org.freedesktop.systemd1',"
+                                   "interface='org.freedesktop.systemd1.Unit',"
+                                   "member='Changed'",
+                                   &error);
 
-        if (dbus_error_is_set(&error)) {
-                log_error("Failed to add match: %s", error.message);
-                r = -EIO;
-                goto finish;
-        }
+                if (dbus_error_is_set(&error)) {
+                        log_error("Failed to add match: %s", error.message);
+                        r = -EIO;
+                        goto finish;
+                }
 
-        dbus_bus_add_match(bus,
-                           "type='signal',"
-                           "sender='org.freedesktop.systemd1',"
-                           "interface='org.freedesktop.systemd1.Job',"
-                           "member='Changed'",
-                           &error);
+                dbus_bus_add_match(bus,
+                                   "type='signal',"
+                                   "sender='org.freedesktop.systemd1',"
+                                   "interface='org.freedesktop.systemd1.Job',"
+                                   "member='Changed'",
+                                   &error);
 
-        if (dbus_error_is_set(&error)) {
-                log_error("Failed to add match: %s", error.message);
-                r = -EIO;
-                goto finish;
+                if (dbus_error_is_set(&error)) {
+                        log_error("Failed to add match: %s", error.message);
+                        r = -EIO;
+                        goto finish;
+                }
         }
 
         if (!dbus_connection_add_filter(bus, monitor_filter, NULL, NULL)) {
@@ -3094,7 +3044,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) {
                 { "reboot",            EQUAL, 1, start_special   },
                 { "default",           EQUAL, 1, start_special   },
                 { "rescue",            EQUAL, 1, start_special   },
-                { "emergency",         EQUAL, 1, start_special   },
+                { "emergency",         EQUAL, 1, start_special   }
         };
 
         int left;
@@ -3206,7 +3156,7 @@ static int start_with_fallback(DBusConnection *bus) {
 static int halt_main(DBusConnection *bus) {
         int r;
 
-        if (!arg_immediate)
+        if (!arg_dry && !arg_immediate)
                 return start_with_fallback(bus);
 
         if (!arg_no_wtmp)
@@ -3286,7 +3236,7 @@ int main(int argc, char*argv[]) {
                 goto finish;
         }
 
-        bus_connect(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &error);
+        bus_connect(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &bus, &private_bus, &error);
 
         switch (arg_action) {