1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-11 09:18:07 +03:00

core: add a new unit_needs_console() call

This call determines whether a specific unit currently needs access to
the console. It's a fancy wrapper around
exec_context_may_touch_console() ultimately, however for service units
we'll explicitly exclude the SERVICE_EXITED state from when we report
true.
This commit is contained in:
Lennart Poettering 2018-01-24 19:54:26 +01:00
parent 46fb617bf9
commit bb2c768545
3 changed files with 54 additions and 0 deletions

View File

@ -3806,6 +3806,32 @@ static int service_control_pid(Unit *u) {
return s->control_pid;
}
static bool service_needs_console(Unit *u) {
Service *s = SERVICE(u);
assert(s);
/* We provide our own implementation of this here, instead of relying of the generic implementation
* unit_needs_console() provides, since we want to return false if we are in SERVICE_EXITED state. */
if (!exec_context_may_touch_console(&s->exec_context))
return false;
return IN_SET(s->state,
SERVICE_START_PRE,
SERVICE_START,
SERVICE_START_POST,
SERVICE_RUNNING,
SERVICE_RELOAD,
SERVICE_STOP,
SERVICE_STOP_SIGABRT,
SERVICE_STOP_SIGTERM,
SERVICE_STOP_SIGKILL,
SERVICE_STOP_POST,
SERVICE_FINAL_SIGTERM,
SERVICE_FINAL_SIGKILL);
}
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
[SERVICE_RESTART_NO] = "no",
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
@ -3921,6 +3947,7 @@ const UnitVTable service_vtable = {
.bus_commit_properties = bus_service_commit_properties,
.get_timeout = service_get_timeout,
.needs_console = service_needs_console,
.can_transient = true,
.status_message_formats = {

View File

@ -5350,6 +5350,28 @@ void unit_warn_leftover_processes(Unit *u) {
(void) cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0, 0, NULL, log_leftover, u);
}
bool unit_needs_console(Unit *u) {
ExecContext *ec;
UnitActiveState state;
assert(u);
state = unit_active_state(u);
if (UNIT_IS_INACTIVE_OR_FAILED(state))
return false;
if (UNIT_VTABLE(u)->needs_console)
return UNIT_VTABLE(u)->needs_console(u);
/* If this unit type doesn't implement this call, let's use a generic fallback implementation: */
ec = unit_get_exec_context(u);
if (!ec)
return false;
return exec_context_may_touch_console(ec);
}
static const char* const collect_mode_table[_COLLECT_MODE_MAX] = {
[COLLECT_INACTIVE] = "inactive",
[COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed",

View File

@ -541,6 +541,9 @@ struct UnitVTable {
/* Returns the main PID if there is any defined, or 0. */
pid_t (*control_pid)(Unit *u);
/* Returns true if the unit currently needs access to the console */
bool (*needs_console)(Unit *u);
/* This is called for each unit type and should be used to
* enumerate existing devices and load them. However,
* everything that is loaded here should still stay in
@ -795,6 +798,8 @@ int unit_prepare_exec(Unit *u);
void unit_warn_leftover_processes(Unit *u);
bool unit_needs_console(Unit *u);
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_unit_full(unit, level, error, ...) \