diff options
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | man/systemd.xml | 17 | ||||
-rw-r--r-- | src/core/job.c | 9 | ||||
-rw-r--r-- | src/core/main.c | 6 | ||||
-rw-r--r-- | src/core/manager.c | 53 | ||||
-rw-r--r-- | src/core/manager.h | 5 | ||||
-rw-r--r-- | src/core/show-status.c | 1 | ||||
-rw-r--r-- | src/core/show-status.h | 12 | ||||
-rw-r--r-- | src/core/transaction.c | 4 | ||||
-rw-r--r-- | src/core/unit.c | 4 | ||||
-rw-r--r-- | src/core/unit.h | 3 |
11 files changed, 68 insertions, 49 deletions
@@ -677,9 +677,6 @@ Features: * merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share.... -* systemd.show_status= should probably have a mode where only failed - units are shown. - * add systemd.abort_on_kill or some other such flag to send SIGABRT instead of SIGKILL (throughout the codebase, not only PID1) diff --git a/man/systemd.xml b/man/systemd.xml index 3cad8141db..28bf49e131 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -798,15 +798,14 @@ <varlistentry> <term><varname>systemd.show_status</varname></term> - <listitem><para>Takes a boolean argument or the constant - <constant>auto</constant>. Can be also specified without an argument, with - the same effect as a positive boolean. If enabled, the systemd manager (PID - 1) shows terse service status updates on the console during bootup. - <constant>auto</constant> behaves like <option>false</option> until a unit - fails or there is a significant delay in boot. Defaults to enabled, unless - <option>quiet</option> is passed as kernel command line option, in which case - it defaults to <constant>auto</constant>. If specified overrides the system - manager configuration file option <option>ShowStatus=</option>, see + <listitem><para>Takes a boolean argument or the constants <constant>error</constant> and + <constant>auto</constant>. Can be also specified without an argument, with the same effect as a + positive boolean. If enabled, the systemd manager (PID 1) shows terse service status updates on the + console during bootup. With <constant>error</constant>, only messages about failures are shown, but + boot is otherwise quiet. <constant>auto</constant> behaves like <option>false</option> until there is + a significant delay in boot. Defaults to enabled, unless <option>quiet</option> is passed as kernel + command line option, in which case it defaults to <constant>error</constant>. If specified overrides + the system manager configuration file option <option>ShowStatus=</option>, see <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. </para></listitem> </varlistentry> diff --git a/src/core/job.c b/src/core/job.c index 5982404cf0..c45171cea7 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -572,7 +572,7 @@ static void job_print_begin_status_message(Unit *u, JobType t) { format = job_get_begin_status_message_format(u, t); DISABLE_WARNING_FORMAT_NONLITERAL; - unit_status_printf(u, "", format); + unit_status_printf(u, STATUS_TYPE_NORMAL, "", format); REENABLE_WARNING; } @@ -861,11 +861,10 @@ static void job_print_done_status_message(Unit *u, JobType t, JobResult result) else status = job_print_done_status_messages[result].word; - if (result != JOB_DONE) - manager_flip_auto_status(u->manager, true); - DISABLE_WARNING_FORMAT_NONLITERAL; - unit_status_printf(u, status, format); + unit_status_printf(u, + result == JOB_DONE ? STATUS_TYPE_NORMAL : STATUS_TYPE_NOTICE, + status, format); REENABLE_WARNING; if (t == JOB_START && result == JOB_FAILED) { diff --git a/src/core/main.c b/src/core/main.c index 23a8ada1ec..3baecc5f00 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -494,7 +494,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat } else if (streq(key, "quiet") && !value) { if (arg_show_status == _SHOW_STATUS_INVALID) - arg_show_status = SHOW_STATUS_AUTO; + arg_show_status = SHOW_STATUS_ERROR; } else if (streq(key, "debug") && !value) { @@ -711,7 +711,7 @@ static void set_manager_settings(Manager *m) { m->kexec_watchdog = arg_kexec_watchdog; m->cad_burst_action = arg_cad_burst_action; - manager_set_show_status(m, arg_show_status); + manager_set_show_status(m, arg_show_status, "commandline"); m->status_unit_format = arg_status_unit_format; } @@ -1254,7 +1254,7 @@ static int status_welcome(void) { _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL; int r; - if (IN_SET(arg_show_status, SHOW_STATUS_NO, SHOW_STATUS_AUTO)) + if (!show_status_on(arg_show_status)) return 0; r = parse_os_release(NULL, diff --git a/src/core/manager.c b/src/core/manager.c index a5290eba0c..6f8065bb08 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -85,7 +85,8 @@ #define CGROUPS_AGENT_RCVBUF_SIZE (8*1024*1024) /* Initial delay and the interval for printing status messages about running jobs */ -#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC) +#define JOBS_IN_PROGRESS_WAIT_USEC (2*USEC_PER_SEC) +#define JOBS_IN_PROGRESS_QUIET_WAIT_USEC (25*USEC_PER_SEC) #define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3) #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3 @@ -109,6 +110,12 @@ static int manager_dispatch_timezone_change(sd_event_source *source, const struc static int manager_run_environment_generators(Manager *m); static int manager_run_generators(Manager *m); +static usec_t manager_watch_jobs_next_time(Manager *m) { + return usec_add(now(CLOCK_MONOTONIC), + show_status_on(m->show_status) ? JOBS_IN_PROGRESS_WAIT_USEC : + JOBS_IN_PROGRESS_QUIET_WAIT_USEC); +} + static void manager_watch_jobs_in_progress(Manager *m) { usec_t next; int r; @@ -124,7 +131,7 @@ static void manager_watch_jobs_in_progress(Manager *m) { if (m->jobs_in_progress_event_source) return; - next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC; + next = manager_watch_jobs_next_time(m); r = sd_event_add_time( m->event, &m->jobs_in_progress_event_source, @@ -173,15 +180,15 @@ static void draw_cylon(char buffer[], size_t buflen, unsigned width, unsigned po } } -void manager_flip_auto_status(Manager *m, bool enable) { +void manager_flip_auto_status(Manager *m, bool enable, const char *reason) { assert(m); if (enable) { if (m->show_status == SHOW_STATUS_AUTO) - manager_set_show_status(m, SHOW_STATUS_TEMPORARY); + manager_set_show_status(m, SHOW_STATUS_TEMPORARY, reason); } else { if (m->show_status == SHOW_STATUS_TEMPORARY) - manager_set_show_status(m, SHOW_STATUS_AUTO); + manager_set_show_status(m, SHOW_STATUS_AUTO, reason); } } @@ -198,7 +205,7 @@ static void manager_print_jobs_in_progress(Manager *m) { assert(m); assert(m->n_running_jobs > 0); - manager_flip_auto_status(m, true); + manager_flip_auto_status(m, true, "delay"); print_nr = (m->jobs_in_progress_iteration / JOBS_IN_PROGRESS_PERIOD_DIVISOR) % m->n_running_jobs; @@ -2736,11 +2743,11 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t switch (sfsi.ssi_signo - SIGRTMIN) { case 20: - manager_set_show_status(m, SHOW_STATUS_YES); + manager_set_show_status(m, SHOW_STATUS_YES, "signal"); break; case 21: - manager_set_show_status(m, SHOW_STATUS_NO); + manager_set_show_status(m, SHOW_STATUS_NO, "signal"); break; case 22: @@ -3402,7 +3409,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { if (s < 0) log_notice("Failed to parse show-status flag '%s', ignoring.", val); else - manager_set_show_status(m, s); + manager_set_show_status(m, s, "deserialization"); } else if ((val = startswith(l, "log-level-override="))) { int level; @@ -3773,12 +3780,12 @@ void manager_check_finished(Manager *m) { if (hashmap_size(m->jobs) > 0) { if (m->jobs_in_progress_event_source) /* Ignore any failure, this is only for feedback */ - (void) sd_event_source_set_time(m->jobs_in_progress_event_source, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC); - + (void) sd_event_source_set_time(m->jobs_in_progress_event_source, + manager_watch_jobs_next_time(m)); return; } - manager_flip_auto_status(m, false); + manager_flip_auto_status(m, false, "boot finished"); /* Notify Type=idle units that we are done now */ manager_close_idle_pipe(m); @@ -4076,19 +4083,24 @@ void manager_recheck_journal(Manager *m) { log_open(); } -void manager_set_show_status(Manager *m, ShowStatus mode) { +void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) { assert(m); - assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY)); + assert(mode >= 0 && mode < _SHOW_STATUS_MAX); if (!MANAGER_IS_SYSTEM(m)) return; - if (m->show_status != mode) - log_debug("%s showing of status.", - mode == SHOW_STATUS_NO ? "Disabling" : "Enabling"); + if (mode == m->show_status) + return; + + bool enabled = IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES); + log_debug("%s (%s) showing of status (%s).", + enabled ? "Enabling" : "Disabling", + strna(show_status_to_string(mode)), + reason); m->show_status = mode; - if (IN_SET(mode, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES)) + if (enabled) (void) touch("/run/systemd/show-status"); else (void) unlink("/run/systemd/show-status"); @@ -4110,7 +4122,10 @@ static bool manager_get_show_status(Manager *m, StatusType type) { if (type != STATUS_TYPE_EMERGENCY && manager_check_ask_password(m) > 0) return false; - return IN_SET(m->show_status, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES); + if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO) + return true; + + return show_status_on(m->show_status); } const char *manager_get_confirm_spawn(Manager *m) { diff --git a/src/core/manager.h b/src/core/manager.h index 67f9af5fc6..10c34f9543 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -56,6 +56,7 @@ typedef enum ManagerObjective { typedef enum StatusType { STATUS_TYPE_EPHEMERAL, STATUS_TYPE_NORMAL, + STATUS_TYPE_NOTICE, STATUS_TYPE_EMERGENCY, } StatusType; @@ -505,11 +506,11 @@ void disable_printk_ratelimit(void); void manager_recheck_dbus(Manager *m); void manager_recheck_journal(Manager *m); -void manager_set_show_status(Manager *m, ShowStatus mode); +void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason); void manager_set_first_boot(Manager *m, bool b); void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5); -void manager_flip_auto_status(Manager *m, bool enable); +void manager_flip_auto_status(Manager *m, bool enable, const char *reason); Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path); diff --git a/src/core/show-status.c b/src/core/show-status.c index c998b51abd..9d7358a9c1 100644 --- a/src/core/show-status.c +++ b/src/core/show-status.c @@ -16,6 +16,7 @@ static const char* const show_status_table[_SHOW_STATUS_MAX] = { [SHOW_STATUS_NO] = "no", + [SHOW_STATUS_ERROR] = "error", [SHOW_STATUS_AUTO] = "auto", [SHOW_STATUS_TEMPORARY] = "temporary", [SHOW_STATUS_YES] = "yes", diff --git a/src/core/show-status.h b/src/core/show-status.h index 247caec77c..178f624d6c 100644 --- a/src/core/show-status.h +++ b/src/core/show-status.h @@ -8,10 +8,11 @@ /* Manager status */ typedef enum ShowStatus { - SHOW_STATUS_NO, - SHOW_STATUS_AUTO, - SHOW_STATUS_TEMPORARY, - SHOW_STATUS_YES, + SHOW_STATUS_NO, /* printing of status is disabled */ + SHOW_STATUS_ERROR, /* only print errors */ + SHOW_STATUS_AUTO, /* disabled but may flip to _TEMPORARY */ + SHOW_STATUS_TEMPORARY, /* enabled temporarily, may flip back to _AUTO */ + SHOW_STATUS_YES, /* printing of status is enabled */ _SHOW_STATUS_MAX, _SHOW_STATUS_INVALID = -1, } ShowStatus; @@ -28,6 +29,9 @@ typedef enum StatusUnitFormat { _STATUS_UNIT_FORMAT_INVALID = -1, } StatusUnitFormat; +static inline bool show_status_on(ShowStatus s) { + return IN_SET(s, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES); +} ShowStatus show_status_from_string(const char *v) _const_; const char* show_status_to_string(ShowStatus s) _pure_; int parse_show_status(const char *v, ShowStatus *ret); diff --git a/src/core/transaction.c b/src/core/transaction.c index 8d67f9ce1a..49f43e0327 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -425,7 +425,9 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi else status = " SKIP "; - unit_status_printf(delete->unit, status, + unit_status_printf(delete->unit, + STATUS_TYPE_NOTICE, + status, "Ordering cycle found, skipping %s"); transaction_delete_unit(tr, delete->unit); return -EAGAIN; diff --git a/src/core/unit.c b/src/core/unit.c index 35627b3511..2816bcef55 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1659,7 +1659,7 @@ static bool unit_test_assert(Unit *u) { return u->assert_result; } -void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) { +void unit_status_printf(Unit *u, StatusType status_type, const char *status, const char *unit_status_msg_format) { const char *d; d = unit_status_string(u); @@ -1667,7 +1667,7 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg d = strjoina(ANSI_HIGHLIGHT, d, ANSI_NORMAL); DISABLE_WARNING_FORMAT_NONLITERAL; - manager_status_printf(u->manager, STATUS_TYPE_NORMAL, status, unit_status_msg_format, d); + manager_status_printf(u->manager, status_type, status, unit_status_msg_format, d); REENABLE_WARNING; } diff --git a/src/core/unit.h b/src/core/unit.h index 999c7a7d83..20d78971df 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -9,6 +9,7 @@ #include "condition.h" #include "emergency-action.h" #include "list.h" +#include "show-status.h" #include "set.h" #include "unit-file.h" #include "cgroup.h" @@ -748,7 +749,7 @@ int unit_add_blockdev_dependency(Unit *u, const char *what, UnitDependencyMask m int unit_coldplug(Unit *u); void unit_catchup(Unit *u); -void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0); +void unit_status_printf(Unit *u, StatusType status_type, const char *status, const char *unit_status_msg_format) _printf_(4, 0); bool unit_need_daemon_reload(Unit *u); |