chiark / gitweb /
build-sys: bump release
[elogind.git] / src / systemctl.c
index 53b6b47b6129662848fa121dd1bf85431df01597..bdb294ede02a1c0b8bed0652ae392e0bf03a4a8b 100644 (file)
 #include "strv.h"
 #include "dbus-common.h"
 #include "cgroup-show.h"
+#include "cgroup-util.h"
 #include "list.h"
 
 static const char *arg_type = NULL;
 static const char *arg_property = NULL;
 static bool arg_all = false;
-static bool arg_replace = false;
+static bool arg_fail = false;
 static bool arg_session = false;
 static bool arg_no_block = false;
 static bool arg_immediate = false;
@@ -719,7 +720,7 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) {
                 [ACTION_RUNLEVEL4] = SPECIAL_RUNLEVEL4_TARGET,
                 [ACTION_RUNLEVEL5] = SPECIAL_RUNLEVEL5_TARGET,
                 [ACTION_RESCUE] = SPECIAL_RESCUE_TARGET,
-                [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_SERVICE,
+                [ACTION_EMERGENCY] = SPECIAL_EMERGENCY_TARGET,
                 [ACTION_DEFAULT] = SPECIAL_DEFAULT_TARGET
         };
 
@@ -732,17 +733,20 @@ static int start_unit(DBusConnection *bus, char **args, unsigned n) {
 
         if (arg_action == ACTION_SYSTEMCTL) {
                 method =
-                        streq(args[0], "stop")    ? "StopUnit" :
-                        streq(args[0], "reload")  ? "ReloadUnit" :
-                        streq(args[0], "restart") ? "RestartUnit" :
-                                                    "StartUnit";
+                        streq(args[0], "stop")                  ? "StopUnit" :
+                        streq(args[0], "reload")                ? "ReloadUnit" :
+                        streq(args[0], "restart")               ? "RestartUnit" :
+                        streq(args[0], "try-restart")           ? "TryRestartUnit" :
+                        streq(args[0], "reload-or-restart")     ? "ReloadOrRestartUnit" :
+                        streq(args[0], "reload-or-try-restart") ? "ReloadOrTryRestartUnit" :
+                                                                  "StartUnit";
 
                 mode =
                         (streq(args[0], "isolate") ||
                          streq(args[0], "rescue")  ||
                          streq(args[0], "emergency")) ? "isolate" :
-                                          arg_replace ? "replace" :
-                                                        "fail";
+                                             arg_fail ? "fail" :
+                                                        "replace";
 
                 one_name = table[verb_to_action(args[0])];
 
@@ -793,12 +797,17 @@ finish:
 }
 
 static int start_special(DBusConnection *bus, char **args, unsigned n) {
+        int r;
+
         assert(bus);
         assert(args);
 
-        warn_wall(verb_to_action(args[0]));
+        r = start_unit(bus, args, n);
+
+        if (r >= 0)
+                warn_wall(verb_to_action(args[0]));
 
-        return start_unit(bus, args, n);
+        return r;
 }
 
 static int check_unit(DBusConnection *bus, char **args, unsigned n) {
@@ -927,6 +936,8 @@ typedef struct ExecStatusInfo {
         char *path;
         char **argv;
 
+        bool ignore;
+
         usec_t start_timestamp;
         usec_t exit_timestamp;
         pid_t pid;
@@ -951,6 +962,7 @@ static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i)
         unsigned n;
         uint32_t pid;
         int32_t code, status;
+        dbus_bool_t ignore;
 
         assert(i);
         assert(i);
@@ -996,6 +1008,7 @@ static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i)
         }
 
         if (!dbus_message_iter_next(&sub2) ||
+            bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &ignore, true) < 0 ||
             bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &start_timestamp, true) < 0 ||
             bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT64, &exit_timestamp, true) < 0 ||
             bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_UINT32, &pid, true) < 0 ||
@@ -1003,6 +1016,7 @@ static int exec_status_info_deserialize(DBusMessageIter *sub, ExecStatusInfo *i)
             bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &status, false) < 0)
                 return -EIO;
 
+        i->ignore = ignore;
         i->start_timestamp = (usec_t) start_timestamp;
         i->exit_timestamp = (usec_t) exit_timestamp;
         i->pid = (pid_t) pid;
@@ -1098,9 +1112,6 @@ static void print_status_info(UnitStatusInfo *i) {
         else if (i->what)
                 printf("\t    What: %s\n", i->what);
 
-        if (i->status_text)
-                printf("\t  Status: \"%s\"\n", i->status_text);
-
         if (i->accept)
                 printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
 
@@ -1173,6 +1184,9 @@ static void print_status_info(UnitStatusInfo *i) {
                 printf("\n");
         }
 
+        if (i->status_text)
+                printf("\t  Status: \"%s\"\n", i->status_text);
+
         if (i->default_control_group) {
                 unsigned c;
 
@@ -1183,7 +1197,7 @@ static void print_status_info(UnitStatusInfo *i) {
                 else
                         c = 0;
 
-                show_cgroup_recursive(i->default_control_group, "\t\t  ", c);
+                show_cgroup_by_path(i->default_control_group, "\t\t  ", c);
         }
 }
 
@@ -1525,10 +1539,11 @@ static int print_property(const char *name, DBusMessageIter *iter) {
 
                                         t = strv_join(info.argv, " ");
 
-                                        printf("%s={ path=%s ; argv[]=%s start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
+                                        printf("%s={ path=%s ; argv[]=%s ; ignore=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
                                                name,
                                                strna(info.path),
                                                strna(t),
+                                               yes_no(info.ignore),
                                                strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
                                                strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
                                                (unsigned) info. pid,
@@ -2485,7 +2500,8 @@ static int systemctl_help(void) {
                "  -t --type=TYPE     List only units of a particular type\n"
                "  -p --property=NAME Show only properties by this name\n"
                "  -a --all           Show all units/properties, including dead/empty ones\n"
-               "     --replace       When installing a new job, replace existing conflicting ones\n"
+               "     --fail          When installing a new job, fail if conflicting jobs are\n"
+               "                     pending\n"
                "     --system        Connect to system bus\n"
                "     --session       Connect to session bus\n"
                "  -q --quiet         Suppress output\n"
@@ -2495,12 +2511,18 @@ static int systemctl_help(void) {
                "  list-units                      List units\n"
                "  start [NAME...]                 Start one or more units\n"
                "  stop [NAME...]                  Stop one or more units\n"
-               "  restart [NAME...]               Restart one or more units\n"
                "  reload [NAME...]                Reload one or more units\n"
+               "  restart [NAME...]               Start or restart one or more units\n"
+               "  try-restart [NAME...]           Restart one or more units if active\n"
+               "  reload-or-restart [NAME...]     Reload one or more units is possible,\n"
+               "                                  otherwise start or restart\n"
+               "  reload-or-try-restart [NAME...] Reload one or more units is possible,\n"
+               "                                  otherwise restart if active\n"
                "  isolate [NAME]                  Start one unit and stop all others\n"
-               "  check [NAME...]                 Check whether any of the passed units are active\n"
+               "  check [NAME...]                 Check whether units are active\n"
                "  status [NAME...]                Show status of one or more units\n"
-               "  show [NAME...|JOB...]           Show properties of one or more units/jobs/manager\n"
+               "  show [NAME...|JOB...]           Show properties of one or more\n"
+               "                                  units/jobs/manager\n"
                "  load [NAME...]                  Load one or more units\n"
                "  list-jobs                       List jobs\n"
                "  cancel [JOB...]                 Cancel one or more jobs\n"
@@ -2518,9 +2540,9 @@ static int systemctl_help(void) {
                "  halt                            Shut down and halt the system\n"
                "  poweroff                        Shut down and power-off the system\n"
                "  reboot                          Shut down and reboot the system\n"
-               "  default                         Enter default mode\n"
-               "  rescue                          Enter rescue mode\n"
-               "  emergency                       Enter emergency mode\n",
+               "  rescue                          Enter system rescue mode\n"
+               "  emergency                       Enter system emergency mode\n"
+               "  default                         Enter system default mode\n",
                program_invocation_short_name);
 
         return 0;
@@ -2594,7 +2616,7 @@ static int runlevel_help(void) {
 static int systemctl_parse_argv(int argc, char *argv[]) {
 
         enum {
-                ARG_REPLACE = 0x100,
+                ARG_FAIL = 0x100,
                 ARG_SESSION,
                 ARG_SYSTEM,
                 ARG_NO_BLOCK,
@@ -2606,7 +2628,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "type",      required_argument, NULL, 't'          },
                 { "property",  required_argument, NULL, 'p'          },
                 { "all",       no_argument,       NULL, 'a'          },
-                { "replace",   no_argument,       NULL, ARG_REPLACE  },
+                { "fail",      no_argument,       NULL, ARG_FAIL     },
                 { "session",   no_argument,       NULL, ARG_SESSION  },
                 { "system",    no_argument,       NULL, ARG_SYSTEM   },
                 { "no-block",  no_argument,       NULL, ARG_NO_BLOCK },
@@ -2645,8 +2667,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_all = true;
                         break;
 
-                case ARG_REPLACE:
-                        arg_replace = true;
+                case ARG_FAIL:
+                        arg_fail = true;
                         break;
 
                 case ARG_SESSION:
@@ -3051,7 +3073,7 @@ static int talk_upstart(void) {
         if (utmp_get_runlevel(&previous, NULL) < 0)
                 previous = 'N';
 
-        if (!(bus = dbus_connection_open("unix:abstract=/com/ubuntu/upstart", &error))) {
+        if (!(bus = dbus_connection_open_private("unix:abstract=/com/ubuntu/upstart", &error))) {
                 if (dbus_error_has_name(&error, DBUS_ERROR_NO_SERVER)) {
                         r = 0;
                         goto finish;
@@ -3115,8 +3137,10 @@ finish:
         if (reply)
                 dbus_message_unref(reply);
 
-        if (bus)
+        if (bus) {
+                dbus_connection_close(bus);
                 dbus_connection_unref(bus);
+        }
 
         dbus_error_free(&error);
 
@@ -3179,6 +3203,9 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[]) {
                 { "stop",              MORE,  2, start_unit      },
                 { "reload",            MORE,  2, start_unit      },
                 { "restart",           MORE,  2, start_unit      },
+                { "try-restart",       MORE,  2, start_unit      },
+                { "reload-or-restart", MORE,  2, start_unit      },
+                { "reload-or-try-restart", MORE, 2, start_unit   },
                 { "isolate",           EQUAL, 2, start_unit      },
                 { "check",             MORE,  2, check_unit      },
                 { "show",              MORE,  1, show            },
@@ -3285,26 +3312,29 @@ static int reload_with_fallback(DBusConnection *bus) {
 static int start_with_fallback(DBusConnection *bus) {
         int r;
 
-        warn_wall(arg_action);
 
         if (bus) {
                 /* First, try systemd via D-Bus. */
                 if ((r = start_unit(bus, NULL, 0)) > 0)
-                        return 0;
+                        goto done;
 
                 /* Hmm, talking to systemd via D-Bus didn't work. Then
                  * let's try to talk to Upstart via D-Bus. */
                 if ((r = talk_upstart()) > 0)
-                        return 0;
+                        goto done;
         }
 
         /* Nothing else worked, so let's try
          * /dev/initctl */
         if ((r = talk_initctl()) != 0)
-                return 0;
+                goto done;
 
         log_error("Failed to talk to init daemon.");
         return -EIO;
+
+done:
+        warn_wall(arg_action);
+        return 0;
 }
 
 static int halt_main(DBusConnection *bus) {
@@ -3439,8 +3469,10 @@ int main(int argc, char*argv[]) {
 
 finish:
 
-        if (bus)
+        if (bus) {
+                dbus_connection_close(bus);
                 dbus_connection_unref(bus);
+        }
 
         dbus_error_free(&error);