Merge pull request #14976 from keszybz/show-status-message

core: fix message about show status state
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-03-01 23:37:41 +01:00 committed by GitHub
commit df46dbca92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 68 additions and 49 deletions

3
TODO
View File

@ -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)

View File

@ -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>

View File

@ -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) {

View File

@ -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,

View File

@ -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) {

View File

@ -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);

View File

@ -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",

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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);