X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=96a0d0578ee2459f153dcd9c99a518d409b00e54;hb=947127ff6230b44623afec3e6aacc85f54168db2;hp=b11fee515cc67c4d8fcb3675d16369b563eea5a9;hpb=cdc06ed7b6120c1049305fa7033f228ee9d86043;p=elogind.git diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index b11fee515..96a0d0578 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -101,6 +101,7 @@ static bool arg_recursive = false; static int arg_force = 0; static bool arg_ask_password = true; static bool arg_runtime = false; +static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL; static char **arg_wall = NULL; static const char *arg_kill_who = NULL; static int arg_signal = SIGTERM; @@ -455,7 +456,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) { } if (circle_len > 0) - printf("%s%s%s", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle); + printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle); printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s", on_active, id_len, id, off_active, @@ -1927,9 +1928,9 @@ static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_cha for (i = 0; i < n_changes; i++) { if (changes[i].type == UNIT_FILE_SYMLINK) - log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path); + log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source); else - log_info("rm '%s'", changes[i].path); + log_info("Removed symlink %s.", changes[i].path); } } @@ -1944,9 +1945,9 @@ static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) { while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) { if (!arg_quiet) { if (streq(type, "symlink")) - log_info("ln -s '%s' '%s'", source, path); + log_info("Created symlink from %s to %s.", path, source); else - log_info("rm '%s'", path); + log_info("Removed symlink %s.", path); } } if (r < 0) @@ -3169,6 +3170,7 @@ typedef struct UnitStatusInfo { const char *status_text; const char *pid_file; bool running:1; + int status_errno; usec_t start_timestamp; usec_t exit_timestamp; @@ -3440,6 +3442,8 @@ static void print_status_info( if (i->status_text) printf(" Status: \"%s\"\n", i->status_text); + if (i->status_errno > 0) + printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno)); if (i->control_group && (i->main_pid > 0 || i->control_pid > 0 || @@ -3660,6 +3664,8 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo * i->exit_code = (int) j; else if (streq(name, "ExecMainStatus")) i->exit_status = (int) j; + else if (streq(name, "StatusErrno")) + i->status_errno = (int) j; break; } @@ -5209,7 +5215,7 @@ static int enable_unit(sd_bus *bus, char **args) { } else if (streq(verb, "link")) r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes); else if (streq(verb, "preset")) { - r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes); + r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes); carries_install_info = r; } else if (streq(verb, "mask")) r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes); @@ -5231,7 +5237,7 @@ static int enable_unit(sd_bus *bus, char **args) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; int expect_carries_install_info = false; - bool send_force = true; + bool send_force = true, send_preset_mode = false; const char *method; if (streq(verb, "enable")) { @@ -5246,7 +5252,13 @@ static int enable_unit(sd_bus *bus, char **args) { } else if (streq(verb, "link")) method = "LinkUnitFiles"; else if (streq(verb, "preset")) { - method = "PresetUnitFiles"; + + if (arg_preset_mode != UNIT_FILE_PRESET_FULL) { + method = "PresetUnitFilesWithMode"; + send_preset_mode = true; + } else + method = "PresetUnitFiles"; + expect_carries_install_info = true; } else if (streq(verb, "mask")) method = "MaskUnitFiles"; @@ -5270,6 +5282,12 @@ static int enable_unit(sd_bus *bus, char **args) { if (r < 0) return bus_log_create_error(r); + if (send_preset_mode) { + r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode)); + if (r < 0) + return bus_log_create_error(r); + } + r = sd_bus_message_append(m, "b", arg_runtime); if (r < 0) return bus_log_create_error(r); @@ -5320,6 +5338,61 @@ finish: return r; } +static int preset_all(sd_bus *bus, char **args) { + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + int r; + + if (!bus || avoid_bus()) { + + r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes); + if (r < 0) { + log_error("Operation failed: %s", strerror(-r)); + goto finish; + } + + if (!arg_quiet) + dump_unit_file_changes(changes, n_changes); + + r = 0; + + } else { + _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "PresetAllUnitFiles", + &error, + &reply, + "sbb", + unit_file_preset_mode_to_string(arg_preset_mode), + arg_runtime, + arg_force); + 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; + } + +finish: + unit_file_changes_free(changes, n_changes); + + return r; +} + static int unit_is_enabled(sd_bus *bus, char **args) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; @@ -5394,6 +5467,30 @@ static int unit_is_enabled(sd_bus *bus, char **args) { return !enabled; } +static int is_system_running(sd_bus *bus, char **args) { + _cleanup_free_ char *state = NULL; + int r; + + r = sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "SystemState", + NULL, + &state); + if (r < 0) { + if (!arg_quiet) + puts("unknown"); + return 0; + } + + if (!arg_quiet) + puts(state); + + return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE; +} + static int systemctl_help(void) { pager_open_if_enabled(); @@ -5437,6 +5534,8 @@ static int systemctl_help(void) { " --runtime Enable unit files only temporarily until next reboot\n" " -f --force When enabling unit files, override existing symlinks\n" " When shutting down, execute action immediately\n" + " --preset-mode= Specifies whether fully apply presets, or only enable,\n" + " or only disable\n" " --root=PATH Enable unit files in the specified root directory\n" " -n --lines=INTEGER Number of journal entries to show\n" " -o --output=STRING Change journal output mode (short, short-monotonic,\n" @@ -5477,6 +5576,8 @@ static int systemctl_help(void) { " reenable NAME... Reenable one or more unit files\n" " preset NAME... Enable/disable one or more unit files\n" " based on preset configuration\n" + " preset-all Enable/disable all unit files based on\n" + " preset configuration\n" " is-enabled NAME... Check whether unit files are enabled\n\n" " mask NAME... Mask one or more units\n" " unmask NAME... Unmask one or more units\n" @@ -5501,6 +5602,7 @@ static int systemctl_help(void) { " daemon-reload Reload systemd manager configuration\n" " daemon-reexec Reexecute systemd manager\n\n" "System Commands:\n" + " is-system-running Check whether system is fully running\n" " default Enter system default mode\n" " rescue Enter system rescue mode\n" " emergency Enter system emergency mode\n" @@ -5625,7 +5727,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_FORCE, ARG_PLAIN, ARG_STATE, - ARG_JOB_MODE + ARG_JOB_MODE, + ARG_PRESET_MODE, }; static const struct option options[] = { @@ -5667,6 +5770,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "plain", no_argument, NULL, ARG_PLAIN }, { "state", required_argument, NULL, ARG_STATE }, { "recursive", no_argument, NULL, 'r' }, + { "preset-mode", required_argument, NULL, ARG_PRESET_MODE }, {} }; @@ -5932,6 +6036,16 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_recursive = true; break; + case ARG_PRESET_MODE: + + arg_preset_mode = unit_file_preset_mode_from_string(optarg); + if (arg_preset_mode < 0) { + log_error("Failed to parse preset mode: %s.", optarg); + return -EINVAL; + } + + break; + case '?': return -EINVAL; @@ -6483,6 +6597,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "is-enabled", MORE, 2, unit_is_enabled, NOBUS }, { "reenable", MORE, 2, enable_unit, NOBUS }, { "preset", MORE, 2, enable_unit, NOBUS }, + { "preset-all", EQUAL, 1, preset_all, NOBUS }, { "mask", MORE, 2, enable_unit, NOBUS }, { "unmask", MORE, 2, enable_unit, NOBUS }, { "link", MORE, 2, enable_unit, NOBUS }, @@ -6491,6 +6606,7 @@ static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) { { "set-default", EQUAL, 2, set_default, NOBUS }, { "get-default", EQUAL, 1, get_default, NOBUS }, { "set-property", MORE, 3, set_property }, + { "is-system-running", EQUAL, 1, is_system_running }, {} }, *verb = verbs;