X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=28eaa6a8475ebebcadf27c27f5ec7c4ac08e0490;hb=c7e4a7bece7a5c4484d229dd5e8ff01a5d49c62e;hp=1c6fef484e47c9113e1201e4d1f44666b00dcc0b;hpb=cc19881a694c26af2d941246f72221df7e76ee02;p=elogind.git diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 1c6fef484..28eaa6a84 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -137,23 +137,6 @@ static unsigned arg_lines = 10; static OutputMode arg_output = OUTPUT_SHORT; static bool arg_plain = false; -static const struct { - const char *verb; - const char *method; -} unit_actions[] = { - { "start", "StartUnit" }, - { "stop", "StopUnit" }, - { "condstop", "StopUnit" }, - { "reload", "ReloadUnit" }, - { "restart", "RestartUnit" }, - { "try-restart", "TryRestartUnit" }, - { "condrestart", "TryRestartUnit" }, - { "reload-or-restart", "ReloadOrRestartUnit" }, - { "reload-or-try-restart", "ReloadOrTryRestartUnit" }, - { "condreload", "ReloadOrTryRestartUnit" }, - { "force-reload", "ReloadOrTryRestartUnit" } -}; - static bool original_stdout_is_tty; static int daemon_reload(sd_bus *bus, char **args); @@ -1982,18 +1965,28 @@ static int set_default(sd_bus *bus, char **args) { r = 0; } else { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - r = sd_bus_call_method( + r = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "SetDefaultTarget", - &error, - &reply, - "sb", unit, true); + "SetDefaultTarget"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append(m, "sb", unit, 1); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to set default target: %s", bus_error_message(&error, -r)); return r; @@ -2160,6 +2153,7 @@ static int list_jobs(sd_bus *bus, char **args) { static int cancel_job(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; char **name; + int r = 0; assert(args); @@ -2167,31 +2161,43 @@ static int cancel_job(sd_bus *bus, char **args) { return daemon_reload(bus, args); STRV_FOREACH(name, args+1) { + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; uint32_t id; - int r; + int q; - r = safe_atou32(*name, &id); - if (r < 0) { - log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r)); - return r; + q = safe_atou32(*name, &id); + if (q < 0) { + log_error("Failed to parse job id \"%s\": %s", *name, strerror(-q)); + return q; } - r = sd_bus_call_method( + q = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "CancelJob", - &error, - NULL, - "u", id); - if (r < 0) { - log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r)); - return r; + "CancelJob"); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (q < 0) + return bus_log_create_error(1); + + q = sd_bus_message_append(m, "u", id); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_call(bus, m, 0, &error, NULL); + if (q < 0) { + log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q)); + if (r == 0) + r = q; } } - return 0; + return r; } static int need_daemon_reload(sd_bus *bus, const char *unit) { @@ -2350,18 +2356,18 @@ static int check_wait_response(WaitData *d) { else if (streq(d->result, "canceled")) log_error("Job for %s canceled.", strna(d->name)); else if (streq(d->result, "dependency")) - log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name)); + log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name)); else if (!streq(d->result, "done") && !streq(d->result, "skipped")) { if (d->name) { bool quotes; quotes = chars_intersect(d->name, SHELL_NEED_QUOTES); - log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xn\" for details.", + log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.", d->name, quotes ? "'" : "", d->name, quotes ? "'" : ""); } else - log_error("Job failed. See \"journalctl -xn\" for details."); + log_error("Job failed. See \"journalctl -xe\" for details."); } } @@ -2539,6 +2545,23 @@ static int check_triggering_units( return 0; } +static const struct { + const char *verb; + const char *method; +} unit_actions[] = { + { "start", "StartUnit" }, + { "stop", "StopUnit" }, + { "condstop", "StopUnit" }, + { "reload", "ReloadUnit" }, + { "restart", "RestartUnit" }, + { "try-restart", "TryRestartUnit" }, + { "condrestart", "TryRestartUnit" }, + { "reload-or-restart", "ReloadOrRestartUnit" }, + { "reload-or-try-restart", "ReloadOrTryRestartUnit" }, + { "condreload", "ReloadOrTryRestartUnit" }, + { "force-reload", "ReloadOrTryRestartUnit" } +}; + static const char *verb_to_method(const char *verb) { uint i; @@ -2567,7 +2590,7 @@ static int start_unit_one( sd_bus_error *error, Set *s) { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; const char *path; int r; @@ -2577,15 +2600,26 @@ static int start_unit_one( assert(error); log_debug("Calling manager for %s on %s, %s", method, name, mode); - r = sd_bus_call_method( + + r = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - method, - error, - &reply, - "ss", name, mode); + method); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append(m, "ss", name, mode); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, error, &reply); if (r < 0) { const char *verb; @@ -2704,7 +2738,7 @@ static enum action verb_to_action(const char *verb) { static int start_unit(sd_bus *bus, char **args) { _cleanup_set_free_free_ Set *s = NULL; _cleanup_strv_free_ char **names = NULL; - const char *method, *mode, *one_name; + const char *method, *mode, *one_name, *suffix = NULL; char **name; int r = 0; @@ -2717,8 +2751,11 @@ static int start_unit(sd_bus *bus, char **args) { method = verb_to_method(args[0]); action = verb_to_action(args[0]); - mode = streq(args[0], "isolate") ? "isolate" : - action_table[action].mode ?: arg_job_mode; + if (streq(args[0], "isolate")) { + mode = "isolate"; + suffix = ".target"; + } else + mode = action_table[action].mode ?: arg_job_mode; one_name = action_table[action].target; } else { @@ -2734,7 +2771,7 @@ static int start_unit(sd_bus *bus, char **args) { if (one_name) names = strv_new(one_name, NULL); else { - r = expand_names(bus, args + 1, NULL, &names); + r = expand_names(bus, args + 1, suffix, &names); if (r < 0) log_error("Failed to expand names: %s", strerror(-r)); } @@ -2824,7 +2861,7 @@ static int reboot_with_logind(sd_bus *bus, enum action a) { method, &error, NULL, - "b", true); + "b", arg_ask_password); if (r < 0) log_error("Failed to execute operation: %s", bus_error_message(&error, r)); @@ -3047,18 +3084,29 @@ static int kill_unit(sd_bus *bus, char **args) { log_error("Failed to expand names: %s", strerror(-r)); STRV_FOREACH(name, names) { - q = sd_bus_call_method( + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + + q = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "KillUnit", - &error, - NULL, - "ssi", *names, arg_kill_who, arg_signal); + "KillUnit"); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_call(bus, m, 0, &error, NULL); if (q < 0) { - log_error("Failed to kill unit %s: %s", - *names, bus_error_message(&error, r)); + log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -3409,7 +3457,7 @@ static void print_status_info( if (i->main_pid > 0 || i->control_pid > 0) { if (i->main_pid > 0) { - printf(" Main PID: %u", (unsigned) i->main_pid); + printf(" Main PID: "PID_FMT, i->main_pid); if (i->running) { _cleanup_free_ char *comm = NULL; @@ -3440,7 +3488,7 @@ static void print_status_info( if (i->control_pid > 0) { _cleanup_free_ char *c = NULL; - printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid); + printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid); get_process_comm(i->control_pid, &c); if (c) @@ -3828,7 +3876,7 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte return bus_log_parse_error(r); if (u > 0) - printf("%s=%u\n", name, (unsigned) u); + printf("%s=%"PRIu32"\n", name, u); else if (arg_all) printf("%s=\n", name); @@ -3999,14 +4047,14 @@ static int print_property(const char *name, sd_bus_message *m, const char *conte tt = strv_join(info.argv, " "); - printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n", + printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n", name, strna(info.path), strna(tt), 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, + info.pid, sigchld_code_to_string(info.code), info.status, info.code == CLD_EXITED ? "" : "/", @@ -4558,6 +4606,10 @@ static int set_property(sd_bus *bus, char **args) { if (r < 0) return bus_log_create_error(r); + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + n = unit_name_mangle(args[1], MANGLE_NOGLOB); if (!n) return log_oom(); @@ -4599,7 +4651,7 @@ static int set_property(sd_bus *bus, char **args) { static int snapshot(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; _cleanup_free_ char *n = NULL, *id = NULL; const char *path; int r; @@ -4611,15 +4663,25 @@ static int snapshot(sd_bus *bus, char **args) { if (!n) return log_oom(); - r = sd_bus_call_method( + r = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "CreateSnapshot", - &error, - &reply, - "sb", n, false); + "CreateSnapshot"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append(m, "sb", n, false); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to create snapshot: %s", bus_error_message(&error, r)); return r; @@ -4652,7 +4714,7 @@ static int delete_snapshot(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_strv_free_ char **names = NULL; char **name; - int r, q; + int r; assert(args); @@ -4661,18 +4723,30 @@ static int delete_snapshot(sd_bus *bus, char **args) { log_error("Failed to expand names: %s", strerror(-r)); STRV_FOREACH(name, names) { - q = sd_bus_call_method( + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + int q; + + q = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "RemoveSnapshot", - &error, - NULL, - "s", *name); + "RemoveSnapshot"); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_append(m, "s", *name); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_call(bus, m, 0, &error, NULL); if (q < 0) { - log_error("Failed to remove snapshot %s: %s", - *name, bus_error_message(&error, r)); + log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -4683,6 +4757,7 @@ static int delete_snapshot(sd_bus *bus, char **args) { static int daemon_reload(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; const char *method; int r; @@ -4706,16 +4781,21 @@ static int daemon_reload(sd_bus *bus, char **args) { /* "daemon-reload" */ "Reload"; } - r = sd_bus_call_method( + r = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - method, - &error, - NULL, - NULL); + method); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + r = sd_bus_call(bus, m, 0, &error, NULL); if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL) /* There's always a fallback possible for * legacy actions. */ @@ -4744,18 +4824,29 @@ static int reset_failed(sd_bus *bus, char **args) { log_error("Failed to expand names: %s", strerror(-r)); STRV_FOREACH(name, names) { - q = sd_bus_call_method( + _cleanup_bus_message_unref_ sd_bus_message *m = NULL; + + q = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "ResetFailedUnit", - &error, - NULL, - "s", *name); + "ResetFailedUnit"); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_message_append(m, "s", *name); + if (q < 0) + return bus_log_create_error(q); + + q = sd_bus_call(bus, m, 0, &error, NULL); if (q < 0) { - log_error("Failed to reset failed state of unit %s: %s", - *name, bus_error_message(&error, r)); + log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q)); if (r == 0) r = q; } @@ -4886,6 +4977,10 @@ static int set_environment(sd_bus *bus, char **args) { if (r < 0) return bus_log_create_error(r); + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + r = sd_bus_message_append_strv(m, args + 1); if (r < 0) return bus_log_create_error(r); @@ -4917,6 +5012,10 @@ static int import_environment(sd_bus *bus, char **args) { if (r < 0) return bus_log_create_error(r); + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + if (strv_isempty(args + 1)) r = sd_bus_message_append_strv(m, environ); else { @@ -5228,6 +5327,10 @@ static int enable_unit(sd_bus *bus, char **args) { if (r < 0) return bus_log_create_error(r); + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + r = sd_bus_message_append_strv(m, names); if (r < 0) return bus_log_create_error(r); @@ -5288,6 +5391,92 @@ finish: return r; } +static int add_dependency(sd_bus *bus, char **args) { + _cleanup_strv_free_ char **names = NULL; + _cleanup_free_ char *target = NULL; + const char *verb = args[0]; + UnitDependency dep; + int r = 0; + + if (!args[1]) + return 0; + + target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target"); + if (!target) + return log_oom(); + + r = mangle_names(args+2, &names); + if (r < 0) + return r; + + if (streq(verb, "add-wants")) + dep = UNIT_WANTS; + else if (streq(verb, "add-requires")) + dep = UNIT_REQUIRES; + else + assert_not_reached("Unknown verb"); + + if (!bus || avoid_bus()) { + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + + r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes); + + if (r < 0) { + log_error("Can't add dependency: %s", strerror(-r)); + return r; + } + + if (!arg_quiet) + dump_unit_file_changes(changes, n_changes); + + unit_file_changes_free(changes, n_changes); + + } else { + _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + + r = sd_bus_message_new_method_call( + bus, + &m, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "AddDependencyUnitFiles"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append_strv(m, names); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, &reply); + if (r < 0) { + log_error("Failed to execute operation: %s", bus_error_message(&error, r)); + return r; + } + + r = deserialize_and_dump_unit_file_changes(reply); + if (r < 0) + return r; + + if (!arg_no_reload) + r = daemon_reload(bus, args); + else + r = 0; + } + + return r; +} + static int preset_all(sd_bus *bus, char **args) { UnitFileChange *changes = NULL; unsigned n_changes = 0; @@ -5307,21 +5496,33 @@ static int preset_all(sd_bus *bus, char **args) { r = 0; } else { - _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - r = sd_bus_call_method( + r = sd_bus_message_new_method_call( bus, + &m, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", - "PresetAllUnitFiles", - &error, - &reply, + "PresetAllUnitFiles"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append( + m, "sbb", unit_file_preset_mode_to_string(arg_preset_mode), arg_runtime, arg_force); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_call(bus, m, 0, &error, &reply); if (r < 0) { log_error("Failed to execute operation: %s", bus_error_message(&error, r)); return r; @@ -5533,6 +5734,10 @@ static void systemctl_help(void) { " unmask NAME... Unmask one or more units\n" " link PATH... Link one or more units files into\n" " the search path\n" + " add-wants TARGET NAME... Add 'Wants' dependency for the target\n" + " on specified one or more units\n" + " add-requires TARGET NAME... Add 'Requires' dependency for the target\n" + " on specified one or more units\n" " get-default Get the name of the default target\n" " set-default NAME Set the default target\n\n" "Machine Commands:\n" @@ -6543,6 +6748,8 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "get-default", EQUAL, 1, get_default, NOBUS }, { "set-property", MORE, 3, set_property }, { "is-system-running", EQUAL, 1, is_system_running }, + { "add-wants", MORE, 3, add_dependency, NOBUS }, + { "add-requires", MORE, 3, add_dependency, NOBUS }, {} }, *verb = verbs;