summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--man/systemd.xml17
-rw-r--r--src/core/job.c9
-rw-r--r--src/core/main.c6
-rw-r--r--src/core/manager.c53
-rw-r--r--src/core/manager.h5
-rw-r--r--src/core/show-status.c1
-rw-r--r--src/core/show-status.h12
-rw-r--r--src/core/transaction.c4
-rw-r--r--src/core/unit.c4
-rw-r--r--src/core/unit.h3
11 files changed, 68 insertions, 49 deletions
diff --git a/TODO b/TODO
index d26b1be408..e944245a57 100644
--- a/TODO
+++ b/TODO
@@ -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);