chiark / gitweb /
systemctl: make sure daemon-reload returns success
[elogind.git] / src / systemctl / systemctl.c
index 7a2431986dfd8b650d754e1c37f434d28927acae..df4bd2147cb328b1987b22c2a181fbb2f175d0cf 100644 (file)
@@ -135,7 +135,7 @@ static OutputMode arg_output = OUTPUT_SHORT;
 static bool arg_plain = false;
 
 static int daemon_reload(sd_bus *bus, char **args);
-static void halt_now(enum action a);
+static int halt_now(enum action a);
 
 static void pager_open_if_enabled(void) {
 
@@ -532,7 +532,7 @@ static int get_triggered_units(
 static int get_listening(
                 sd_bus *bus,
                 const char* unit_path,
-                char*** listen,
+                char*** listening,
                 unsigned *c) {
 
         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
@@ -560,11 +560,11 @@ static int get_listening(
 
         while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
 
-                r = strv_extend(listen, type);
+                r = strv_extend(listening, type);
                 if (r < 0)
                         return log_oom();
 
-                r = strv_extend(listen, path);
+                r = strv_extend(listening, path);
                 if (r < 0)
                         return log_oom();
 
@@ -687,7 +687,7 @@ static int list_sockets(sd_bus *bus, char **args) {
         cu = (unsigned) r;
 
         for (u = unit_infos; u < unit_infos + cu; u++) {
-                _cleanup_strv_free_ char **listen = NULL, **triggered = NULL;
+                _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
                 unsigned c = 0, i;
 
                 if (!output_show_unit(u))
@@ -700,7 +700,7 @@ static int list_sockets(sd_bus *bus, char **args) {
                 if (r < 0)
                         goto cleanup;
 
-                r = get_listening(bus, u->unit_path, &listen, &c);
+                r = get_listening(bus, u->unit_path, &listening, &c);
                 if (r < 0)
                         goto cleanup;
 
@@ -712,16 +712,16 @@ static int list_sockets(sd_bus *bus, char **args) {
                 for (i = 0; i < c; i++)
                         socket_infos[cs + i] = (struct socket_info) {
                                 .id = u->id,
-                                .type = listen[i*2],
-                                .path = listen[i*2 + 1],
+                                .type = listening[i*2],
+                                .path = listening[i*2 + 1],
                                 .triggered = triggered,
                                 .own_triggered = i==0,
                         };
 
                 /* from this point on we will cleanup those socket_infos */
                 cs += c;
-                free(listen);
-                listen = triggered = NULL; /* avoid cleanup */
+                free(listening);
+                listening = triggered = NULL; /* avoid cleanup */
         }
 
         qsort_safe(socket_infos, cs, sizeof(struct socket_info),
@@ -1204,7 +1204,11 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n) {
 
         pager_open_if_enabled();
 
-        id_len = unit_len = type_len = state_len = 0;
+        id_len = sizeof("JOB")-1;
+        unit_len = sizeof("UNIT")-1;
+        type_len = sizeof("TYPE")-1;
+        state_len = sizeof("STATE")-1;
+
         for (j = jobs; j < jobs + n; j++) {
                 uint32_t id = j->id;
                 assert(j->name && j->type && j->state);
@@ -1936,11 +1940,11 @@ static int check_inhibitors(sd_bus *bus, enum action a) {
                 /* If logind is not around, then there are no inhibitors... */
                 return 0;
 
-        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "ssssuu");
+        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
         if (r < 0)
                 return bus_log_parse_error(r);
 
-        while ((r = sd_bus_message_read(reply, "ssssuu", &what, &who, &why, &mode, &uid, &pid)) > 0) {
+        while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
                 _cleanup_free_ char *comm = NULL, *user = NULL;
                 _cleanup_strv_free_ char **sv = NULL;
 
@@ -2029,7 +2033,7 @@ static int start_special(sd_bus *bus, char **args) {
             (a == ACTION_HALT ||
              a == ACTION_POWEROFF ||
              a == ACTION_REBOOT))
-                halt_now(a);
+                return halt_now(a);
 
         if (arg_force >= 1 &&
             (a == ACTION_HALT ||
@@ -2913,8 +2917,11 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte
         /* This is a low-level property printer, see
          * print_status_info() for the nicer output */
 
-        if (arg_properties && !strv_find(arg_properties, name))
-                return 0;
+        if (arg_properties && !strv_find(arg_properties, name)) {
+                /* skip what we didn't read */
+                r = sd_bus_message_skip(m, contents);
+                return r;
+        }
 
         switch (contents[0]) {
 
@@ -3755,7 +3762,7 @@ static int daemon_reload(sd_bus *bus, char **args) {
         else if (r < 0)
                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
 
-        return r;
+        return r < 0 ? r : 0;
 }
 
 static int reset_failed(sd_bus *bus, char **args) {
@@ -5354,7 +5361,7 @@ static int talk_initctl(void) {
         return 1;
 }
 
-static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
+static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
 
         static const struct {
                 const char* verb;
@@ -5505,14 +5512,14 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
                 if (((!streq(verbs[i].verb, "reboot") &&
                       !streq(verbs[i].verb, "halt") &&
                       !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
-                        log_error("Failed to get D-Bus connection: %s", strerror (-r));
+                        log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
                         return -EIO;
                 }
 
         } else {
 
                 if (!bus && !avoid_bus()) {
-                        log_error("Failed to get D-Bus connection: %s", strerror (-r));
+                        log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
                         return -EIO;
                 }
         }
@@ -5605,11 +5612,9 @@ done:
         return 0;
 }
 
-static _noreturn_ void halt_now(enum action a) {
-
-        _cleanup_free_ char *param = NULL;
+static int halt_now(enum action a) {
 
-       /* Make sure C-A-D is handled by the kernel from this
+/* Make sure C-A-D is handled by the kernel from this
          * point on... */
         reboot(RB_ENABLE_CAD);
 
@@ -5618,30 +5623,30 @@ static _noreturn_ void halt_now(enum action a) {
         case ACTION_HALT:
                 log_info("Halting.");
                 reboot(RB_HALT_SYSTEM);
-                break;
+                return -errno;
 
         case ACTION_POWEROFF:
                 log_info("Powering off.");
                 reboot(RB_POWER_OFF);
-                break;
+                return -errno;
 
-        case ACTION_REBOOT:
+        case ACTION_REBOOT: {
+                _cleanup_free_ char *param = NULL;
 
-                if (read_one_line_file(REBOOT_PARAM_FILE, &param) == 0) {
-                        log_info("Rebooting with arg '%s'.", param);
+                if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
+                        log_info("Rebooting with argument '%s'.", param);
                         syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                                 LINUX_REBOOT_CMD_RESTART2, param);
-                } else {
-                        log_info("Rebooting.");
-                        reboot(RB_AUTOBOOT);
                 }
-                break;
 
-        default:
-                assert_not_reached("Unknown halt action.");
+                log_info("Rebooting.");
+                reboot(RB_AUTOBOOT);
+                return -errno;
         }
 
-        assert_not_reached("Uh? This shouldn't happen.");
+        default:
+                assert_not_reached("Unknown action.");
+        }
 }
 
 static int halt_main(sd_bus *bus) {
@@ -5713,9 +5718,10 @@ static int halt_main(sd_bus *bus) {
         if (arg_dry)
                 return 0;
 
-        halt_now(arg_action);
-        /* We should never reach this. */
-        return -ENOSYS;
+        r = halt_now(arg_action);
+        log_error("Failed to reboot: %s", strerror(-r));
+
+        return r;
 }
 
 static int runlevel_main(void) {
@@ -5764,13 +5770,11 @@ int main(int argc, char*argv[]) {
                 goto finish;
         }
 
-        if (!avoid_bus()) {
-                r = bus_open_transport(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
-                if (r < 0) {
-                        log_error("Failed to create bus connection: %s", strerror(-r));
-                        goto finish;
-                }
-        }
+        if (!avoid_bus())
+                r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
+
+        /* systemctl_main() will print an error message for the bus
+         * connection, but only if it needs to */
 
         switch (arg_action) {