|
|
661545 |
From 94355e0146245c14012ac177461110d0a0c65f10 Mon Sep 17 00:00:00 2001
|
|
|
661545 |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
661545 |
Date: Wed, 24 Jan 2018 19:54:26 +0100
|
|
|
661545 |
Subject: [PATCH] core: add a new unit_needs_console() call
|
|
|
661545 |
|
|
|
661545 |
This call determines whether a specific unit currently needs access to
|
|
|
661545 |
the console. It's a fancy wrapper around
|
|
|
661545 |
exec_context_may_touch_console() ultimately, however for service units
|
|
|
661545 |
we'll explicitly exclude the SERVICE_EXITED state from when we report
|
|
|
661545 |
true.
|
|
|
661545 |
|
|
|
661545 |
(cherry picked from commit bb2c7685454842549bc1fe47adc35cbca2a84190)
|
|
|
661545 |
|
|
|
661545 |
Related: #1524359
|
|
|
661545 |
---
|
|
|
661545 |
src/core/service.c | 27 +++++++++++++++++++++++++++
|
|
|
661545 |
src/core/unit.c | 22 ++++++++++++++++++++++
|
|
|
661545 |
src/core/unit.h | 5 +++++
|
|
|
661545 |
3 files changed, 54 insertions(+)
|
|
|
661545 |
|
|
|
661545 |
diff --git a/src/core/service.c b/src/core/service.c
|
|
|
661545 |
index 1ad154e41f..8a8f4be149 100644
|
|
|
661545 |
--- a/src/core/service.c
|
|
|
661545 |
+++ b/src/core/service.c
|
|
|
661545 |
@@ -3368,6 +3368,32 @@ static int service_control_pid(Unit *u) {
|
|
|
661545 |
return s->control_pid;
|
|
|
661545 |
}
|
|
|
661545 |
|
|
|
661545 |
+static bool service_needs_console(Unit *u) {
|
|
|
661545 |
+ Service *s = SERVICE(u);
|
|
|
661545 |
+
|
|
|
661545 |
+ assert(s);
|
|
|
661545 |
+
|
|
|
661545 |
+ /* We provide our own implementation of this here, instead of relying of the generic implementation
|
|
|
661545 |
+ * unit_needs_console() provides, since we want to return false if we are in SERVICE_EXITED state. */
|
|
|
661545 |
+
|
|
|
661545 |
+ if (!exec_context_may_touch_console(&s->exec_context))
|
|
|
661545 |
+ return false;
|
|
|
661545 |
+
|
|
|
661545 |
+ return IN_SET(s->state,
|
|
|
661545 |
+ SERVICE_START_PRE,
|
|
|
661545 |
+ SERVICE_START,
|
|
|
661545 |
+ SERVICE_START_POST,
|
|
|
661545 |
+ SERVICE_RUNNING,
|
|
|
661545 |
+ SERVICE_RELOAD,
|
|
|
661545 |
+ SERVICE_STOP,
|
|
|
661545 |
+ SERVICE_STOP_SIGABRT,
|
|
|
661545 |
+ SERVICE_STOP_SIGTERM,
|
|
|
661545 |
+ SERVICE_STOP_SIGKILL,
|
|
|
661545 |
+ SERVICE_STOP_POST,
|
|
|
661545 |
+ SERVICE_FINAL_SIGTERM,
|
|
|
661545 |
+ SERVICE_FINAL_SIGKILL);
|
|
|
661545 |
+}
|
|
|
661545 |
+
|
|
|
661545 |
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
|
|
|
661545 |
[SERVICE_RESTART_NO] = "no",
|
|
|
661545 |
[SERVICE_RESTART_ON_SUCCESS] = "on-success",
|
|
|
661545 |
@@ -3489,6 +3515,7 @@ const UnitVTable service_vtable = {
|
|
|
661545 |
.bus_commit_properties = bus_service_commit_properties,
|
|
|
661545 |
|
|
|
661545 |
.get_timeout = service_get_timeout,
|
|
|
661545 |
+ .needs_console = service_needs_console,
|
|
|
661545 |
.can_transient = true,
|
|
|
661545 |
|
|
|
661545 |
.status_message_formats = {
|
|
|
661545 |
diff --git a/src/core/unit.c b/src/core/unit.c
|
|
|
661545 |
index 4069a6f4c4..48358bc026 100644
|
|
|
661545 |
--- a/src/core/unit.c
|
|
|
661545 |
+++ b/src/core/unit.c
|
|
|
661545 |
@@ -3699,6 +3699,28 @@ pid_t unit_main_pid(Unit *u) {
|
|
|
661545 |
return 0;
|
|
|
661545 |
}
|
|
|
661545 |
|
|
|
661545 |
+bool unit_needs_console(Unit *u) {
|
|
|
661545 |
+ ExecContext *ec;
|
|
|
661545 |
+ UnitActiveState state;
|
|
|
661545 |
+
|
|
|
661545 |
+ assert(u);
|
|
|
661545 |
+
|
|
|
661545 |
+ state = unit_active_state(u);
|
|
|
661545 |
+
|
|
|
661545 |
+ if (UNIT_IS_INACTIVE_OR_FAILED(state))
|
|
|
661545 |
+ return false;
|
|
|
661545 |
+
|
|
|
661545 |
+ if (UNIT_VTABLE(u)->needs_console)
|
|
|
661545 |
+ return UNIT_VTABLE(u)->needs_console(u);
|
|
|
661545 |
+
|
|
|
661545 |
+ /* If this unit type doesn't implement this call, let's use a generic fallback implementation: */
|
|
|
661545 |
+ ec = unit_get_exec_context(u);
|
|
|
661545 |
+ if (!ec)
|
|
|
661545 |
+ return false;
|
|
|
661545 |
+
|
|
|
661545 |
+ return exec_context_may_touch_console(ec);
|
|
|
661545 |
+}
|
|
|
661545 |
+
|
|
|
661545 |
static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
|
|
|
661545 |
[UNIT_ACTIVE] = "active",
|
|
|
661545 |
[UNIT_RELOADING] = "reloading",
|
|
|
661545 |
diff --git a/src/core/unit.h b/src/core/unit.h
|
|
|
661545 |
index 4a8bd79052..fa7de11645 100644
|
|
|
661545 |
--- a/src/core/unit.h
|
|
|
661545 |
+++ b/src/core/unit.h
|
|
|
661545 |
@@ -408,6 +408,9 @@ struct UnitVTable {
|
|
|
661545 |
/* Returns the main PID if there is any defined, or 0. */
|
|
|
661545 |
pid_t (*control_pid)(Unit *u);
|
|
|
661545 |
|
|
|
661545 |
+ /* Returns true if the unit currently needs access to the console */
|
|
|
661545 |
+ bool (*needs_console)(Unit *u);
|
|
|
661545 |
+
|
|
|
661545 |
/* This is called for each unit type and should be used to
|
|
|
661545 |
* enumerate existing devices and load them. However,
|
|
|
661545 |
* everything that is loaded here should still stay in
|
|
|
661545 |
@@ -627,6 +630,8 @@ pid_t unit_main_pid(Unit *u);
|
|
|
661545 |
const char *unit_active_state_to_string(UnitActiveState i) _const_;
|
|
|
661545 |
UnitActiveState unit_active_state_from_string(const char *s) _pure_;
|
|
|
661545 |
|
|
|
661545 |
+bool unit_needs_console(Unit *u);
|
|
|
661545 |
+
|
|
|
661545 |
/* Macros which append UNIT= or USER_UNIT= to the message */
|
|
|
661545 |
|
|
|
661545 |
#define log_unit_full_errno(unit, level, error, ...) log_object_internal(level, error, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__)
|