diff options
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 173 |
1 files changed, 108 insertions, 65 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index c75d12c136..3407d93c80 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -152,7 +152,7 @@ static bool arg_now = false; static int daemon_reload(int argc, char *argv[], void* userdata); static int halt_now(enum action a); -static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet); +static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state); static bool original_stdout_is_tty; @@ -200,14 +200,6 @@ static void release_busses(void) { busses[w] = sd_bus_flush_close_unref(busses[w]); } -static void pager_open_if_enabled(void) { - - if (arg_no_pager) - return; - - pager_open(false); -} - static void ask_password_agent_open_if_enabled(void) { /* Open the password agent as a child process if necessary */ @@ -348,6 +340,11 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) { if (arg_all) return true; + if (!strv_isempty(arg_states)) + return true; + + /* By default show all units except the ones in inactive + * state and with no pending job */ if (u->job_id > 0) return true; @@ -678,7 +675,7 @@ static int list_units(int argc, char *argv[], void *userdata) { sd_bus *bus; int r; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -890,7 +887,7 @@ static int list_sockets(int argc, char *argv[], void *userdata) { int r = 0, n; sd_bus *bus; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -1197,7 +1194,7 @@ static int list_timers(int argc, char *argv[], void *userdata) { sd_bus *bus; int r = 0; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -1365,7 +1362,7 @@ static int list_unit_files(int argc, char *argv[], void *userdata) { char *path; int r; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); if (install_client_side()) { Hashmap *h; @@ -1436,7 +1433,7 @@ static int list_unit_files(int argc, char *argv[], void *userdata) { }; if (output_show_unit_file(&units[c], strv_skip(argv, 1))) - c ++; + c++; } if (r < 0) @@ -1484,7 +1481,7 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH)); } - if (arg_full){ + if (arg_full) { printf("%s\n", name); return 0; } @@ -1638,11 +1635,27 @@ static int list_dependencies_one( if (arg_plain) printf(" "); else { - int state; + UnitActiveState active_state = _UNIT_ACTIVE_STATE_INVALID; const char *on; - state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true); - on = state > 0 ? ansi_highlight_green() : ansi_highlight_red(); + (void) get_state_one_unit(bus, *c, &active_state); + switch (active_state) { + case UNIT_ACTIVE: + case UNIT_RELOADING: + case UNIT_ACTIVATING: + on = ansi_highlight_green(); + break; + + case UNIT_INACTIVE: + case UNIT_DEACTIVATING: + on = ansi_normal(); + break; + + default: + on = ansi_highlight_red(); + break; + } + printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_normal()); } @@ -1679,7 +1692,7 @@ static int list_dependencies(int argc, char *argv[], void *userdata) { } else u = SPECIAL_DEFAULT_TARGET; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -1883,13 +1896,13 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n) printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state); if (m->is_host) - printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n", + printf("%-*s (host) %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n", (int) (namelen - (sizeof(" (host)")-1)), strna(m->name), on_state, statelen, strna(m->state), off_state, on_failed, failedlen, m->n_failed_units, off_failed, jobslen, m->n_jobs); else - printf("%-*s %s%-*s%s %s%*u%s %*u\n", + printf("%-*s %s%-*s%s %s%*" PRIu32 "%s %*" PRIu32 "\n", namelen, strna(m->name), on_state, statelen, strna(m->state), off_state, on_failed, failedlen, m->n_failed_units, off_failed, @@ -1910,7 +1923,7 @@ static int list_machines(int argc, char *argv[], void *userdata) { return -EPERM; } - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -2067,7 +2080,7 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp return; } - pager_open_if_enabled(); + pager_open(arg_no_pager, false); id_len = strlen("JOB"); unit_len = strlen("UNIT"); @@ -2137,7 +2150,7 @@ static int list_jobs(int argc, char *argv[], void *userdata) { int r; bool skipped = false; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -2407,18 +2420,19 @@ static int unit_find_paths( return r; } -static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) { +static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_free_ char *buf = NULL; - const char *path, *state; + UnitActiveState state; + const char *path; int r; assert(name); + assert(active_state); /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it * isn't loaded. */ - r = sd_bus_call_method( bus, "org.freedesktop.systemd1", @@ -2434,7 +2448,7 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are * considered inactive. */ - state = "inactive"; + state = UNIT_INACTIVE; } else { r = sd_bus_message_read(reply, "o", &path); @@ -2452,13 +2466,15 @@ static int check_one_unit(sd_bus *bus, const char *name, const char *good_states if (r < 0) return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); - state = buf; + state = unit_active_state_from_string(buf); + if (state == _UNIT_ACTIVE_STATE_INVALID) { + log_error("Invalid unit state '%s' for: %s", buf, name); + return -EINVAL; + } } - if (!quiet) - puts(state); - - return nulstr_contains(good_states, state); + *active_state = state; + return 0; } static int check_triggering_units( @@ -2466,9 +2482,10 @@ static int check_triggering_units( const char *name) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL; + _cleanup_free_ char *path = NULL, *n = NULL, *load_state = NULL; _cleanup_strv_free_ char **triggered_by = NULL; bool print_warning_label = true; + UnitActiveState active_state; char **i; int r; @@ -2487,11 +2504,11 @@ static int check_triggering_units( "org.freedesktop.systemd1.Unit", "LoadState", &error, - &state); + &load_state); if (r < 0) return log_error_errno(r, "Failed to get load state of %s: %s", n, bus_error_message(&error, r)); - if (streq(state, "masked")) + if (streq(load_state, "masked")) return 0; r = sd_bus_get_property_strv( @@ -2506,11 +2523,11 @@ static int check_triggering_units( return log_error_errno(r, "Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r)); STRV_FOREACH(i, triggered_by) { - r = check_one_unit(bus, *i, "active\0reloading\0", true); + r = get_state_one_unit(bus, *i, &active_state); if (r < 0) - return log_error_errno(r, "Failed to check unit: %m"); + return r; - if (r == 0) + if (!IN_SET(active_state, UNIT_ACTIVE, UNIT_RELOADING)) continue; if (print_warning_label) { @@ -2604,7 +2621,10 @@ static int start_unit_one( if (!sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) && !sd_bus_error_has_name(error, BUS_ERROR_UNIT_MASKED)) - log_error("See system logs and 'systemctl status %s' for details.", name); + log_error("See %s logs and 'systemctl%s status %s' for details.", + arg_scope == UNIT_FILE_SYSTEM ? "system" : "user", + arg_scope == UNIT_FILE_SYSTEM ? "" : " --user", + name); return r; } @@ -3171,11 +3191,12 @@ static int start_special(int argc, char *argv[], void *userdata) { return start_unit(argc, argv, userdata); } -static int check_unit_generic(int code, const char *good_states, char **args) { +static int check_unit_generic(int code, const UnitActiveState good_states[], int nb_states, char **args) { _cleanup_strv_free_ char **names = NULL; + UnitActiveState active_state; sd_bus *bus; char **name; - int r; + int r, i; bool found = false; r = acquire_bus(BUS_MANAGER, &bus); @@ -3187,13 +3208,16 @@ static int check_unit_generic(int code, const char *good_states, char **args) { return log_error_errno(r, "Failed to expand names: %m"); STRV_FOREACH(name, names) { - int state; + r = get_state_one_unit(bus, *name, &active_state); + if (r < 0) + return r; - state = check_one_unit(bus, *name, good_states, arg_quiet); - if (state < 0) - return state; - if (state > 0) - found = true; + if (!arg_quiet) + puts(unit_active_state_to_string(active_state)); + + for (i = 0; i < nb_states; ++i) + if (good_states[i] == active_state) + found = true; } /* use the given return code for the case that we won't find @@ -3202,12 +3226,14 @@ static int check_unit_generic(int code, const char *good_states, char **args) { } static int check_unit_active(int argc, char *argv[], void *userdata) { + const UnitActiveState states[] = { UNIT_ACTIVE, UNIT_RELOADING }; /* According to LSB: 3, "program is not running" */ - return check_unit_generic(3, "active\0reloading\0", strv_skip(argv, 1)); + return check_unit_generic(3, states, ELEMENTSOF(states), strv_skip(argv, 1)); } static int check_unit_failed(int argc, char *argv[], void *userdata) { - return check_unit_generic(1, "failed\0", strv_skip(argv, 1)); + const UnitActiveState states[] = { UNIT_FAILED }; + return check_unit_generic(1, states, ELEMENTSOF(states), strv_skip(argv, 1)); } static int kill_unit(int argc, char *argv[], void *userdata) { @@ -4559,7 +4585,7 @@ static int show_all( if (r < 0) return r; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); c = (unsigned) r; @@ -4611,8 +4637,8 @@ static int show_system_status(sd_bus *bus) { printf(" State: %s%s%s\n", on, strna(mi.state), off); - printf(" Jobs: %u queued\n", mi.n_jobs); - printf(" Failed: %u units\n", mi.n_failed_units); + printf(" Jobs: %" PRIu32 " queued\n", mi.n_jobs); + printf(" Failed: %" PRIu32 " units\n", mi.n_failed_units); printf(" Since: %s; %s\n", format_timestamp(since2, sizeof(since2), mi.timestamp), @@ -4654,7 +4680,7 @@ static int show(int argc, char *argv[], void *userdata) { return -EINVAL; } - pager_open_if_enabled(); + pager_open(arg_no_pager, false); if (show_status) /* Increase max number of open files to 16K if we can, we @@ -4672,7 +4698,7 @@ static int show(int argc, char *argv[], void *userdata) { if (show_status && argc <= 1) { - pager_open_if_enabled(); + pager_open(arg_no_pager, false); show_system_status(bus); new_line = true; @@ -4813,7 +4839,7 @@ static int cat(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to expand names: %m"); - pager_open_if_enabled(); + pager_open(arg_no_pager, false); STRV_FOREACH(name, names) { _cleanup_free_ char *fragment_path = NULL; @@ -5003,7 +5029,7 @@ static int show_environment(int argc, char *argv[], void *userdata) { sd_bus *bus; int r; - pager_open_if_enabled(); + pager_open(arg_no_pager, false); r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -6170,15 +6196,30 @@ static int edit(int argc, char *argv[], void *userdata) { r = daemon_reload(argc, argv, userdata); end: - STRV_FOREACH_PAIR(original, tmp, paths) + STRV_FOREACH_PAIR(original, tmp, paths) { (void) unlink(*tmp); + /* Removing empty dropin dirs */ + if (!arg_full) { + _cleanup_free_ char *dir; + + dir = dirname_malloc(*original); + if (!dir) + return log_oom(); + + /* no need to check if the dir is empty, rmdir + * does nothing if it is not the case. + */ + (void) rmdir(dir); + } + } + return r; } static void systemctl_help(void) { - pager_open_if_enabled(); + pager_open(arg_no_pager, false); printf("%s [OPTIONS...] {COMMAND} ...\n\n" "Query or send control commands to the systemd manager.\n\n" @@ -6550,7 +6591,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { } p = optarg; - for(;;) { + for (;;) { _cleanup_free_ char *type = NULL; r = extract_first_word(&p, &type, ",", 0); @@ -6600,7 +6641,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return log_oom(); } else { p = optarg; - for(;;) { + for (;;) { _cleanup_free_ char *prop = NULL; r = extract_first_word(&p, &prop, ",", 0); @@ -6710,11 +6751,11 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case ARG_FORCE: - arg_force ++; + arg_force++; break; case 'f': - arg_force ++; + arg_force++; break; case ARG_NO_RELOAD: @@ -6785,7 +6826,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { } p = optarg; - for(;;) { + for (;;) { _cleanup_free_ char *s = NULL; r = extract_first_word(&p, &s, ",", 0); @@ -7180,7 +7221,7 @@ static int telinit_parse_argv(int argc, char *argv[]) { arg_action = table[i].to; - optind ++; + optind++; return 1; } @@ -7271,6 +7312,7 @@ static int parse_argv(int argc, char *argv[]) { return systemctl_parse_argv(argc, argv); } +#ifdef HAVE_SYSV_COMPAT _pure_ static int action_to_runlevel(void) { static const char table[_ACTION_MAX] = { @@ -7288,6 +7330,7 @@ _pure_ static int action_to_runlevel(void) { return table[arg_action]; } +#endif static int talk_initctl(void) { #ifdef HAVE_SYSV_COMPAT |