X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=e587cfbfae552e0b10fc1d33be62e29ee0d043d8;hp=f65bd2faa00f5d879a2e5cb5eab4a58911e9ed4c;hb=c74f17d96cccd4cc998fd037cb92046930188c91;hpb=256425cc10d74c13602527eb86b4ba0938964565 diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index f65bd2faa..e587cfbfa 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -65,6 +65,7 @@ #include "path-util.h" static const char *arg_type = NULL; +static const char *arg_load_state = NULL; static char **arg_property = NULL; static bool arg_all = false; static const char *arg_job_mode = "replace"; @@ -85,7 +86,6 @@ static bool arg_failed = false; static bool arg_runtime = false; static char **arg_wall = NULL; static const char *arg_kill_who = NULL; -static const char *arg_kill_mode = NULL; static int arg_signal = SIGTERM; static const char *arg_root = NULL; static usec_t arg_when = 0; @@ -337,7 +337,9 @@ static bool output_show_unit(const struct unit_info *u) { return (!arg_type || ((dot = strrchr(u->id, '.')) && streq(dot+1, arg_type))) && - (arg_all || !(streq(u->active_state, "inactive") || u->following[0]) || u->job_id > 0); + (!arg_load_state || streq(u->load_state, arg_load_state)) && + (arg_all || !(streq(u->active_state, "inactive") + || u->following[0]) || u->job_id > 0); } static void output_units_list(const struct unit_info *unit_infos, unsigned c) { @@ -1123,6 +1125,8 @@ static int load_unit(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { DBusMessage *reply; + bool b; + char *n; if (!(m = dbus_message_new_method_call( "org.freedesktop.systemd1", @@ -1134,15 +1138,19 @@ static int load_unit(DBusConnection *bus, char **args) { goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -1266,22 +1274,29 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { *interface = "org.freedesktop.systemd1.Unit", *property = "NeedDaemonReload", *path; + char *n; + bool k; /* We ignore all errors here, since this is used to show a warning only */ - if (!(m = dbus_message_new_method_call( + m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "GetUnit"))) + "GetUnit"); + if (!m) goto finish; - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &unit, - DBUS_TYPE_INVALID)) + n = unit_name_mangle(unit); + k = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? (const char**) &n : &unit, + DBUS_TYPE_INVALID); + free(n); + if (!k) goto finish; - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL))) + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL); + if (!reply) goto finish; if (!dbus_message_get_args(reply, NULL, @@ -1290,11 +1305,12 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { goto finish; dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - path, - "org.freedesktop.DBus.Properties", - "Get"))) + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"); + if (!m) goto finish; if (!dbus_message_append_args(m, @@ -1305,7 +1321,8 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) { } dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL))) + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, NULL); + if (!reply) goto finish; if (!dbus_message_iter_init(reply, &iter) || @@ -1500,6 +1517,220 @@ finish: return r; } +static int check_one_unit(DBusConnection *bus, char *name, bool quiet) { + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + DBusMessageIter iter, sub; + const char + *interface = "org.freedesktop.systemd1.Unit", + *property = "ActiveState"; + const char *path = NULL; + const char *state; + int r = 3; /* According to LSB: "program is not running" */ + char *n; + bool b; + + assert(bus); + assert(name); + + dbus_error_init(&error); + + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + n = unit_name_mangle(name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : &name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + /* Hmm, cannot figure out anything about this unit... */ + if (!quiet) + puts("unknown"); + + goto finish; + } + + 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; + } + + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.DBus.Properties", + "Get"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + r = -ENOMEM; + goto finish; + } + + dbus_message_unref(reply); + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_recurse(&iter, &sub); + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply."); + r = -EIO; + goto finish; + } + + dbus_message_iter_get_basic(&sub, &state); + + if (!quiet) + puts(state); + + if (streq(state, "active") || streq(state, "reloading")) + r = 0; + +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + return r; +} + +static void check_triggering_units( + DBusConnection *bus, + const char *unit_name) { + + DBusError error; + DBusMessage *m = NULL, *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; + bool print_warning_label = true; + + dbus_error_init(&error); + + n = unit_name_mangle(unit_name); + unit_path = unit_dbus_path_from_name(n ? n : unit_name); + free(n); + if (!unit_path) { + log_error("Could not allocate dbus path."); + goto finish; + } + + m = dbus_message_new_method_call("org.freedesktop.systemd1", + unit_path, + "org.freedesktop.DBus.Properties", + "Get"); + if (!m) { + log_error("Could not allocate message."); + goto finish; + } + + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &triggered_by_property, + DBUS_TYPE_INVALID)) { + log_error("Could not append arguments to message."); + goto finish; + } + + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { + log_error("Failed to issue method call: %s", bus_error_message(&error)); + goto finish; + } + + if (!dbus_message_iter_init(reply, &iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + goto finish; + + } + + dbus_message_iter_recurse(&iter, &sub); + dbus_message_iter_recurse(&sub, &iter); + sub = iter; + + while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) { + int r; + + if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + log_error("Failed to parse reply: %s", bus_error_message(&error)); + goto finish; + } + + dbus_message_iter_get_basic(&sub, &service_trigger); + + r = check_one_unit(bus, service_trigger, true); + if (r < 0) + goto finish; + if (r == 0) { + if (print_warning_label) { + log_warning("Warning: Stopping %s, but it can still be activated by:", unit_name); + print_warning_label = false; + } + log_warning(" %s", service_trigger); + } + + dbus_message_iter_next(&sub); + } +finish: + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + dbus_error_free(&error); + + free(unit_path); +} + static int start_unit_one( DBusConnection *bus, const char *method, @@ -1511,6 +1742,8 @@ static int start_unit_one( DBusMessage *m = NULL, *reply = NULL; const char *path; int r; + char *n; + bool b; assert(bus); assert(method); @@ -1519,26 +1752,31 @@ static int start_unit_one( assert(error); assert(arg_no_block || s); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - method))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &mode, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? (const char **) &n : &name, + DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error); + if (!reply) { if (arg_action != ACTION_SYSTEMCTL && error_is_no_service(error)) { /* There's always a fallback possible for @@ -1580,6 +1818,11 @@ static int start_unit_one( } } + /* 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: @@ -1865,126 +2108,20 @@ static int start_special(DBusConnection *bus, char **args) { } static int check_unit(DBusConnection *bus, char **args) { - DBusMessage *m = NULL, *reply = NULL; - const char - *interface = "org.freedesktop.systemd1.Unit", - *property = "ActiveState"; - int r = 3; /* According to LSB: "program is not running" */ - DBusError error; char **name; + int r = 3; /* According to LSB: "program is not running" */ assert(bus); assert(args); - dbus_error_init(&error); - STRV_FOREACH(name, args+1) { - const char *path = NULL; - const char *state; - DBusMessageIter iter, sub; - - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnit"))) { - log_error("Could not allocate message."); - r = -ENOMEM; - goto finish; - } - - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { - log_error("Could not append arguments to message."); - r = -ENOMEM; - goto finish; - } - - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { - - /* Hmm, cannot figure out anything about this unit... */ - if (!arg_quiet) - puts("unknown"); - - dbus_error_free(&error); - dbus_message_unref(m); - m = NULL; - continue; - } - - 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; - } - - dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - path, - "org.freedesktop.DBus.Properties", - "Get"))) { - log_error("Could not allocate message."); - r = -ENOMEM; - goto finish; - } - - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &interface, - DBUS_TYPE_STRING, &property, - DBUS_TYPE_INVALID)) { - log_error("Could not append arguments to message."); - r = -ENOMEM; - goto finish; - } - - dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { - log_error("Failed to issue method call: %s", bus_error_message(&error)); - r = -EIO; - goto finish; - } - - if (!dbus_message_iter_init(reply, &iter) || - dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { - log_error("Failed to parse reply."); - r = -EIO; - goto finish; - } - - dbus_message_iter_recurse(&iter, &sub); - - if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { - log_error("Failed to parse reply."); - r = -EIO; - goto finish; - } - - dbus_message_iter_get_basic(&sub, &state); - - if (!arg_quiet) - puts(state); - - if (streq(state, "active") || streq(state, "reloading")) + int state = check_one_unit(bus, *name, arg_quiet); + if (state < 0) + return state; + if (state == 0) r = 0; - - dbus_message_unref(m); - dbus_message_unref(reply); - m = reply = NULL; } -finish: - if (m) - dbus_message_unref(m); - - if (reply) - dbus_message_unref(reply); - - dbus_error_free(&error); - return r; } @@ -2002,34 +2139,37 @@ static int kill_unit(DBusConnection *bus, char **args) { if (!arg_kill_who) arg_kill_who = "all"; - if (!arg_kill_mode) - arg_kill_mode = streq(arg_kill_who, "all") ? "control-group" : "process"; - STRV_FOREACH(name, args+1) { DBusMessage *reply; + char *n; + bool b; - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "KillUnit"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "KillUnit"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_STRING, &arg_kill_who, - DBUS_TYPE_STRING, &arg_kill_mode, - DBUS_TYPE_INT32, &arg_signal, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); dbus_error_free(&error); r = -EIO; @@ -2447,8 +2587,13 @@ static void print_status_info(UnitStatusInfo *i) { } if (i->id && arg_transport != TRANSPORT_SSH) { + int flags = (arg_lines*OUTPUT_SHOW_ALL | + arg_follow*OUTPUT_FOLLOW | + !arg_quiet*OUTPUT_WARN_CUTOFF); printf("\n"); - show_journal_by_unit(i->id, arg_output, 0, i->inactive_exit_timestamp_monotonic, arg_lines, arg_all, arg_follow); + show_journal_by_unit(i->id, arg_output, 0, + i->inactive_exit_timestamp_monotonic, + arg_lines, flags); } if (i->need_daemon_reload) @@ -2458,7 +2603,7 @@ static void print_status_info(UnitStatusInfo *i) { arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); } -static void man_status_info(UnitStatusInfo *i) { +static void show_unit_help(UnitStatusInfo *i) { char **p; assert(i); @@ -2521,7 +2666,7 @@ static void man_status_info(UnitStatusInfo *i) { wait_for_terminate(pid, NULL); } else - log_info("Can't show %s.", *p); + log_info("Can't show: %s", *p); } } @@ -3020,8 +3165,8 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo r = 0; if (!show_properties) { - if (streq(verb, "man")) - man_status_info(&info); + if (streq(verb, "help")) + show_unit_help(&info); else print_status_info(&info); } @@ -3131,17 +3276,16 @@ static int show(DBusConnection *bus, char **args) { uint32_t id; if (safe_atou32(*name, &id) < 0) { - + char *p, *n; /* Interpret as unit name */ - char *e, *p; - e = bus_path_escape(*name); - if (!e) - return -ENOMEM; - p = strappend("/org/freedesktop/systemd1/unit/", e); - free(e); - if (!p) + n = unit_name_mangle(*name); + p = unit_dbus_path_from_name(n ? n : *name); + free(n); + if (!p) { + log_error("Out of memory"); return -ENOMEM; + } r = show_one(args[0], bus, p, show_properties, &new_line); free(p); @@ -3154,8 +3298,10 @@ static int show(DBusConnection *bus, char **args) { /* Interpret as job id */ char *p; - if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) + if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0) { + log_error("Out of memory"); return -ENOMEM; + } r = show_one(args[0], bus, p, show_properties, &new_line); free(p); @@ -3235,14 +3381,17 @@ static int snapshot(DBusConnection *bus, char **args) { const char *interface = "org.freedesktop.systemd1.Unit", *property = "Id"; + char *n; + bool b; dbus_error_init(&error); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "CreateSnapshot"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "CreateSnapshot"); + if (!m) { log_error("Could not allocate message."); return -ENOMEM; } @@ -3250,16 +3399,20 @@ static int snapshot(DBusConnection *bus, char **args) { if (strv_length(args) > 1) name = args[1]; - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_BOOLEAN, &cleanup, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? (const char**) &n : &name, + DBUS_TYPE_BOOLEAN, &cleanup, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3274,11 +3427,12 @@ static int snapshot(DBusConnection *bus, char **args) { } dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( + m = dbus_message_new_method_call( "org.freedesktop.systemd1", path, "org.freedesktop.DBus.Properties", - "Get"))) { + "Get"); + if (!m) { log_error("Could not allocate message."); return -ENOMEM; } @@ -3293,7 +3447,8 @@ static int snapshot(DBusConnection *bus, char **args) { } dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3345,26 +3500,33 @@ static int delete_snapshot(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { const char *path = NULL; + char *n; + bool b; - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnit"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnit"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3379,18 +3541,20 @@ static int delete_snapshot(DBusConnection *bus, char **args) { } dbus_message_unref(m); - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - path, - "org.freedesktop.systemd1.Snapshot", - "Remove"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Snapshot", + "Remove"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } dbus_message_unref(reply); - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3501,26 +3665,33 @@ static int reset_failed(DBusConnection *bus, char **args) { STRV_FOREACH(name, args+1) { DBusMessage *reply; + char *n; + bool b; - if (!(m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "ResetFailedUnit"))) { + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "ResetFailedUnit"); + if (!m) { log_error("Could not allocate message."); r = -ENOMEM; goto finish; } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, name, - DBUS_TYPE_INVALID)) { + n = unit_name_mangle(*name); + b = dbus_message_append_args(m, + DBUS_TYPE_STRING, n ? &n : name, + DBUS_TYPE_INVALID); + free(n); + if (!b) { log_error("Could not append arguments to message."); r = -ENOMEM; goto finish; } - if (!(reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error))) { + reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error); + if (!reply) { log_error("Failed to issue method call: %s", bus_error_message(&error)); r = -EIO; goto finish; @@ -3753,7 +3924,7 @@ finish: static int enable_sysv_units(char **args) { int r = 0; -#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_MEEGO) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA)) +#if defined (HAVE_SYSV_COMPAT) && (defined(TARGET_FEDORA) || defined(TARGET_MANDRIVA) || defined(TARGET_SUSE) || defined(TARGET_ALTLINUX) || defined(TARGET_MAGEIA)) const char *verb = args[0]; unsigned f = 1, t = 1; LookupPaths paths; @@ -4108,7 +4279,7 @@ static int enable_unit(DBusConnection *bus, char **args) { } if (carries_install_info == 0) - log_warning("Warning: unit files do not carry install information. No operation executed."); + log_warning("The unit files have no [Install] section. They are not meant to be enabled using systemctl."); finish: if (m) @@ -4284,7 +4455,7 @@ static int systemctl_help(void) { " status [NAME...|PID...] Show runtime status of one or more units\n" " show [NAME...|JOB...] Show properties of one or more\n" " units/jobs or the manager\n" - " man [NAME...|PID...] Show manual for one or more units\n" + " help [NAME...|PID...] Show manual for one or more units\n" " reset-failed [NAME...] Reset failed state for all, one, or more\n" " units\n" " load [NAME...] Load one or more units\n\n" @@ -4417,7 +4588,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_ROOT, ARG_FULL, ARG_NO_RELOAD, - ARG_KILL_MODE, ARG_KILL_WHO, ARG_NO_ASK_PASSWORD, ARG_FAILED, @@ -4449,7 +4619,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "root", required_argument, NULL, ARG_ROOT }, { "force", no_argument, NULL, ARG_FORCE }, { "no-reload", no_argument, NULL, ARG_NO_RELOAD }, - { "kill-mode", required_argument, NULL, ARG_KILL_MODE }, /* undocumented on purpose */ { "kill-who", required_argument, NULL, ARG_KILL_WHO }, { "signal", required_argument, NULL, 's' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, @@ -4482,9 +4651,17 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return 0; case 't': - arg_type = optarg; - break; - + if (unit_type_from_string(optarg) >= 0) { + arg_type = optarg; + break; + } + if (unit_load_state_from_string(optarg) >= 0) { + arg_load_state = optarg; + break; + } + log_error("Unkown unit type or load state '%s'.", + optarg); + return -EINVAL; case 'p': { char **l; @@ -4587,10 +4764,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_kill_who = optarg; break; - case ARG_KILL_MODE: - arg_kill_mode = optarg; - break; - case 's': if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) { log_error("Failed to parse signal string %s.", optarg); @@ -4634,7 +4807,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -4727,7 +4900,7 @@ static int halt_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -4864,7 +5037,7 @@ static int shutdown_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -4940,7 +5113,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -4965,7 +5138,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { break; if (i >= ELEMENTSOF(table)) { - log_error("Unknown command %s.", argv[optind]); + log_error("Unknown command '%s'.", argv[optind]); return -EINVAL; } @@ -5003,7 +5176,7 @@ static int runlevel_parse_argv(int argc, char *argv[]) { return -EINVAL; default: - log_error("Unknown option code %c", c); + log_error("Unknown option code '%c'.", c); return -EINVAL; } } @@ -5248,7 +5421,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "check", MORE, 2, check_unit }, { "show", MORE, 1, show }, { "status", MORE, 2, show }, - { "man", MORE, 2, show }, + { "help", MORE, 2, show }, { "dump", EQUAL, 1, dump }, { "dot", EQUAL, 1, dot }, { "snapshot", LESS, 2, snapshot }, @@ -5293,9 +5466,10 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError /* Special rule: no arguments means "list-units" */ i = 0; else { - if (streq(argv[optind], "help")) { - systemctl_help(); - return 0; + if (streq(argv[optind], "help") && !argv[optind+1]) { + log_error("This command expects one or more " + "unit names. Did you mean --help?"); + return -EINVAL; } for (i = 0; i < ELEMENTSOF(verbs); i++) @@ -5303,7 +5477,7 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError break; if (i >= ELEMENTSOF(verbs)) { - log_error("Unknown operation %s", argv[optind]); + log_error("Unknown operation '%s'.", argv[optind]); return -EINVAL; } }