X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl.c;h=cb59fd6db2a35f750c969a426b5291c9583528ea;hb=ce3fd7e72a1b101002617bd410031e65d290f56f;hp=175159d68fb42fc87380d72263d198bc9f3eadeb;hpb=6fdae8a6a40d6a3b5f77516abaee23b3eab002f6;p=elogind.git diff --git a/src/systemctl.c b/src/systemctl.c index 175159d68..cb59fd6db 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -35,6 +35,8 @@ #include #include +#include + #include "log.h" #include "util.h" #include "macro.h" @@ -49,7 +51,6 @@ #include "list.h" #include "path-lookup.h" #include "conf-parser.h" -#include "sd-daemon.h" #include "shutdownd.h" #include "exit-status.h" #include "bus-errors.h" @@ -58,6 +59,7 @@ #include "pager.h" #include "spawn-agent.h" #include "install.h" +#include "logs-show.h" static const char *arg_type = NULL; static char **arg_property = NULL; @@ -117,6 +119,9 @@ static enum transport { TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; static const char *arg_host = NULL; +static bool arg_follow = false; +static unsigned arg_lines = 10; +static OutputMode arg_output = OUTPUT_SHORT; static bool private_bus = false; @@ -161,12 +166,12 @@ static void agent_open_if_enabled(void) { agent_open(); } -static const char *ansi_highlight(bool b) { +static const char *ansi_highlight_red(bool b) { if (!on_tty()) return ""; - return b ? ANSI_HIGHLIGHT_ON : ANSI_HIGHLIGHT_OFF; + return b ? ANSI_HIGHLIGHT_RED_ON : ANSI_HIGHLIGHT_OFF; } static const char *ansi_highlight_green(bool b) { @@ -377,16 +382,15 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) { n_shown++; - if (!streq(u->load_state, "loaded") && - !streq(u->load_state, "banned")) { - on_loaded = ansi_highlight(true); - off_loaded = ansi_highlight(false); + if (streq(u->load_state, "error")) { + on_loaded = ansi_highlight_red(true); + off_loaded = ansi_highlight_red(false); } else on_loaded = off_loaded = ""; if (streq(u->active_state, "failed")) { - on_active = ansi_highlight(true); - off_active = ansi_highlight(false); + on_active = ansi_highlight_red(true); + off_active = ansi_highlight_red(false); } else on_active = off_active = ""; @@ -589,8 +593,8 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) { if (u->state == UNIT_FILE_MASKED || u->state == UNIT_FILE_MASKED_RUNTIME || u->state == UNIT_FILE_DISABLED) { - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); } else if (u->state == UNIT_FILE_ENABLED) { on = ansi_highlight_green(true); off = ansi_highlight_green(false); @@ -622,8 +626,6 @@ static int list_unit_files(DBusConnection *bus, char **args) { dbus_error_init(&error); - assert(bus); - pager_open_if_enabled(); if (avoid_bus()) { @@ -659,6 +661,8 @@ static int list_unit_files(DBusConnection *bus, char **args) { hashmap_free(h); } else { + assert(bus); + m = dbus_message_new_method_call( "org.freedesktop.systemd1", "/org/freedesktop/systemd1", @@ -2001,6 +2005,7 @@ typedef struct UnitStatusInfo { const char *load_error; usec_t inactive_exit_timestamp; + usec_t inactive_exit_timestamp_monotonic; usec_t active_enter_timestamp; usec_t active_exit_timestamp; usec_t inactive_enter_timestamp; @@ -2063,10 +2068,9 @@ static void print_status_info(UnitStatusInfo *i) { if (i->following) printf("\t Follow: unit currently follows state of %s\n", i->following); - if (streq_ptr(i->load_state, "failed") || - streq_ptr(i->load_state, "banned")) { - on = ansi_highlight(true); - off = ansi_highlight(false); + if (streq_ptr(i->load_state, "error")) { + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); } else on = off = ""; @@ -2082,8 +2086,8 @@ static void print_status_info(UnitStatusInfo *i) { ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state; if (streq_ptr(i->active_state, "failed")) { - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) { on = ansi_highlight_green(true); off = ansi_highlight_green(false); @@ -2159,8 +2163,8 @@ static void print_status_info(UnitStatusInfo *i) { good = is_clean_exit(p->code, p->status); if (!good) { - on = ansi_highlight(true); - off = ansi_highlight(false); + on = ansi_highlight_red(true); + off = ansi_highlight_red(false); } else on = off = ""; @@ -2201,7 +2205,7 @@ static void print_status_info(UnitStatusInfo *i) { if (i->running) { char *t = NULL; - get_process_name(i->main_pid, &t); + get_process_comm(i->main_pid, &t); if (t) { printf(" (%s)", t); free(t); @@ -2235,7 +2239,7 @@ static void print_status_info(UnitStatusInfo *i) { printf(" Control: %u", (unsigned) i->control_pid); - get_process_name(i->control_pid, &t); + get_process_comm(i->control_pid, &t); if (t) { printf(" (%s)", t); free(t); @@ -2263,10 +2267,15 @@ static void print_status_info(UnitStatusInfo *i) { } } + if (i->id && arg_transport != TRANSPORT_SSH) { + printf("\n"); + show_journal_by_unit(i->id, arg_output, NULL, 0, i->inactive_exit_timestamp_monotonic, arg_lines, arg_all, arg_follow); + } + if (i->need_daemon_reload) printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %s daemon-reload' recommended.\n", - ansi_highlight(true), - ansi_highlight(false), + ansi_highlight_red(true), + ansi_highlight_red(false), arg_scope == UNIT_FILE_SYSTEM ? "--system" : "--user"); } @@ -2387,6 +2396,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->inactive_enter_timestamp = (usec_t) u; else if (streq(name, "InactiveExitTimestamp")) i->inactive_exit_timestamp = (usec_t) u; + else if (streq(name, "InactiveExitTimestampMonotonic")) + i->inactive_exit_timestamp_monotonic = (usec_t) u; else if (streq(name, "ActiveExitTimestamp")) i->active_exit_timestamp = (usec_t) u; else if (streq(name, "ConditionTimestamp")) @@ -3677,11 +3688,13 @@ static int enable_unit(DBusConnection *bus, char **args) { goto finish; } - 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); - else - log_info("rm '%s'", changes[i].path); + if (!arg_quiet) { + 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); + else + log_info("rm '%s'", changes[i].path); + } } } else { @@ -3797,10 +3810,12 @@ static int enable_unit(DBusConnection *bus, char **args) { goto finish; } - if (streq(type, "symlink")) - log_info("ln -s '%s' '%s'", source, path); - else - log_info("rm '%s'", path); + if (!arg_quiet) { + if (streq(type, "symlink")) + log_info("ln -s '%s' '%s'", source, path); + else + log_info("rm '%s'", path); + } dbus_message_iter_next(&sub); } @@ -3965,7 +3980,11 @@ static int systemctl_help(void) { " -f --force When enabling unit files, override existing symlinks\n" " When shutting down, execute action immediately\n" " --root=PATH Enable unit files in the specified root directory\n" - " --runtime Enable unit files only temporarily until next reboot\n\n" + " --runtime Enable unit files only temporarily until next reboot\n" + " -n --lines=INTEGER Journal entries to show\n" + " --follow Follow journal\n" + " -o --output=STRING Change journal output mode (short, short-monotonic,\n" + " verbose, export, json, cat)\n\n" "Unit Commands:\n" " list-units List loaded units\n" " start [NAME...] Start (activate) one or more units\n" @@ -4116,7 +4135,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { ARG_KILL_WHO, ARG_NO_ASK_PASSWORD, ARG_FAILED, - ARG_RUNTIME + ARG_RUNTIME, + ARG_FOLLOW }; static const struct option options[] = { @@ -4149,6 +4169,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) { { "host", required_argument, NULL, 'H' }, { "privileged",no_argument, NULL, 'P' }, { "runtime", no_argument, NULL, ARG_RUNTIME }, + { "lines", required_argument, NULL, 'n' }, + { "follow", no_argument, NULL, ARG_FOLLOW }, + { "output", required_argument, NULL, 'o' }, { NULL, 0, NULL, 0 } }; @@ -4160,7 +4183,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { /* Only when running as systemctl we ask for passwords */ arg_ask_password = true; - while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:P", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "ht:p:aqfs:H:Pn:o:", options, NULL)) >= 0) { switch (c) { @@ -4298,6 +4321,25 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_runtime = true; break; + case 'n': + if (safe_atou(optarg, &arg_lines) < 0) { + log_error("Failed to parse lines '%s'", optarg); + return -EINVAL; + } + break; + + case ARG_FOLLOW: + arg_follow = true; + break; + + case 'o': + arg_output = output_mode_from_string(optarg); + if (arg_output < 0) { + log_error("Unknown output '%s'.", optarg); + return -EINVAL; + } + break; + case '?': return -EINVAL; @@ -5000,7 +5042,8 @@ static int systemctl_main(DBusConnection *bus, int argc, char *argv[], DBusError * enable/disable */ if (!streq(verbs[i].verb, "enable") && !streq(verbs[i].verb, "disable") && - !streq(verbs[i].verb, "is-enable") && + !streq(verbs[i].verb, "is-enabled") && + !streq(verbs[i].verb, "list-unit-files") && !streq(verbs[i].verb, "reenable") && !streq(verbs[i].verb, "preset") && !streq(verbs[i].verb, "mask") && @@ -5156,7 +5199,7 @@ static int halt_main(DBusConnection *bus) { if (!arg_no_wtmp) { if (sd_booted() > 0) log_debug("Not writing utmp record, assuming that systemd-update-utmp is used."); - else if ((r = utmp_put_shutdown(0)) < 0) + else if ((r = utmp_put_shutdown()) < 0) log_warning("Failed to write utmp record: %s", strerror(-r)); }