pid1: rework handling of m->show_status

The fact that m->show_status was serialized/deserialized made impossible any
further customisation of this setting via system.conf. IOW the value was
basically always locked unless it was changed via signals.

This patch reworks the handling of m->show_status but also makes sure that if a
new value was changed via the signal API then this value is kept and preserved
accross PID1 reexecuting or reloading.

Note: this effectively means that once the value is set via the signal
interface, it can be changed again only through the signal API.
This commit is contained in:
Franck Bui 2020-04-27 11:06:34 +02:00
parent 0d6d3cf055
commit 44a419540e
3 changed files with 74 additions and 22 deletions

View File

@ -234,14 +234,12 @@ static int property_get_show_status(
sd_bus_error *error) {
Manager *m = userdata;
int b;
assert(m);
assert(bus);
assert(reply);
assert(m);
b = show_status_on(m->show_status);
return sd_bus_message_append_basic(reply, 'b', &b);
return sd_bus_message_append(reply, "b", manager_get_show_status_on(m));
}
static int property_get_runtime_watchdog(

View File

@ -779,6 +779,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
.watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY,
.watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY,
.show_status_overridden = _SHOW_STATUS_INVALID,
.notify_fd = -1,
.cgroups_agent_fd = -1,
.signal_fd = -1,
@ -2759,11 +2761,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, "signal");
manager_set_show_status_overridden(m, SHOW_STATUS_YES, "signal");
break;
case 21:
manager_set_show_status(m, SHOW_STATUS_NO, "signal");
manager_set_show_status_overridden(m, SHOW_STATUS_NO, "signal");
break;
case 22:
@ -3219,9 +3221,9 @@ int manager_serialize(
/* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
(void) serialize_bool(f, "honor-device-enumeration", !switching_root);
t = show_status_to_string(m->show_status);
if (t)
(void) serialize_item(f, "show-status", t);
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
(void) serialize_item(f, "show-status-overridden",
show_status_to_string(m->show_status_overridden));
if (m->log_level_overridden)
(void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
@ -3568,14 +3570,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
else
m->honor_device_enumeration = b;
} else if ((val = startswith(l, "show-status="))) {
} else if ((val = startswith(l, "show-status-overridden="))) {
ShowStatus s;
s = show_status_from_string(val);
if (s < 0)
log_notice("Failed to parse show-status flag '%s', ignoring.", val);
log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
else
manager_set_show_status(m, s, "deserialization");
manager_set_show_status_overridden(m, s, "deserialize");
} else if ((val = startswith(l, "log-level-override="))) {
int level;
@ -4264,30 +4266,78 @@ void manager_recheck_journal(Manager *m) {
log_open();
}
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) {
bool enabled;
static ShowStatus manager_get_show_status(Manager *m) {
assert(m);
if (MANAGER_IS_USER(m))
return _SHOW_STATUS_INVALID;
if (m->show_status_overridden != _SHOW_STATUS_INVALID)
return m->show_status_overridden;
return m->show_status;
}
bool manager_get_show_status_on(Manager *m) {
assert(m);
return show_status_on(manager_get_show_status(m));
}
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) {
assert(m);
assert(reason);
assert(mode >= 0 && mode < _SHOW_STATUS_MAX);
if (!MANAGER_IS_SYSTEM(m))
if (MANAGER_IS_USER(m))
return;
if (mode == m->show_status)
return;
enabled = show_status_on(mode);
if (m->show_status_overridden == _SHOW_STATUS_INVALID) {
bool enabled;
enabled = show_status_on(mode);
log_debug("%s (%s) showing of status (%s).",
enabled ? "Enabling" : "Disabling",
strna(show_status_to_string(mode)),
reason);
if (enabled)
(void) touch("/run/systemd/show-status");
else
(void) unlink("/run/systemd/show-status");
}
m->show_status = mode;
}
void manager_set_show_status_overridden(Manager *m, ShowStatus mode, const char *reason) {
assert(m);
assert(mode < _SHOW_STATUS_MAX);
if (MANAGER_IS_USER(m))
return;
if (mode == m->show_status_overridden)
return;
m->show_status_overridden = mode;
if (mode == _SHOW_STATUS_INVALID)
mode = m->show_status;
log_debug("%s (%s) showing of status (%s).",
enabled ? "Enabling" : "Disabling",
m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring",
strna(show_status_to_string(mode)),
reason);
m->show_status = mode;
if (enabled)
if (show_status_on(mode))
(void) touch("/run/systemd/show-status");
else
(void) unlink("/run/systemd/show-status");
}
const char *manager_get_confirm_spawn(Manager *m) {
@ -4381,7 +4431,7 @@ static bool manager_should_show_status(Manager *m, StatusType type) {
if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO)
return true;
return show_status_on(m->show_status);
return manager_get_show_status_on(m);
}
void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) {

View File

@ -335,6 +335,7 @@ struct Manager {
uint8_t return_value;
ShowStatus show_status;
ShowStatus show_status_overridden;
StatusUnitFormat status_unit_format;
char *confirm_spawn;
bool no_console_output;
@ -512,7 +513,10 @@ void disable_printk_ratelimit(void);
void manager_recheck_dbus(Manager *m);
void manager_recheck_journal(Manager *m);
bool manager_get_show_status_on(Manager *m);
void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason);
void manager_set_show_status_overridden(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);