|
|
44a72b9 |
From 7d9e4212490f7c42d419de4befb438e173380da7 Mon Sep 17 00:00:00 2001
|
|
|
44a72b9 |
From: Alan Jenkins <alan.christopher.jenkins@gmail.com>
|
|
|
44a72b9 |
Date: Mon, 21 Aug 2017 17:28:35 +0100
|
|
|
44a72b9 |
Subject: [PATCH] logind: respect "delay" inhibitors in scheduled shutdowns
|
|
|
44a72b9 |
|
|
|
44a72b9 |
There is no justification not to wait an extra (default) 5 seconds, for
|
|
|
44a72b9 |
a more graceful shutdown of user programs. Again, you don't get to ignore
|
|
|
44a72b9 |
delay inhibitors for unscheduled shutdowns, short of
|
|
|
44a72b9 |
`systemctl poweroff -f`.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
It is simplest if we move the test for `m->shutdown_dry_run` into
|
|
|
44a72b9 |
manager_scheduled_shutdown_handler().
|
|
|
44a72b9 |
|
|
|
44a72b9 |
However we need to not add such delays during a "dry run". Otherwise, we
|
|
|
44a72b9 |
would still have to be considered "in progress" for some seconds after our
|
|
|
44a72b9 |
admin has seen the final wall message. If they go to `poweroff`, we would
|
|
|
44a72b9 |
have blocked them with a misleading error message. Note this `poweroff`
|
|
|
44a72b9 |
will still process delay inhibitors as needed. If the admin planned to
|
|
|
44a72b9 |
use a more forceful method... eh. It's their responsibility to assess
|
|
|
44a72b9 |
whether that's safe.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
There is an argument that the alternative behaviour could be used (racily!)
|
|
|
44a72b9 |
to kludge around them not being able to shutdown to "single user mode". If
|
|
|
44a72b9 |
we cared about that case, we would have easily preserved non-racy support
|
|
|
44a72b9 |
for it in `shutdown`.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
Additionally, though I think this code does read more easily by reducing
|
|
|
44a72b9 |
inconsistencies, we didn't come up with any use case for delay inhibitors
|
|
|
44a72b9 |
v.s. shutdown.[1] The SIGTERM v.s. SIGKILL delay is more general, and we
|
|
|
44a72b9 |
allow a whole 90 seconds for it, not just 5. So I don't think keeping this
|
|
|
44a72b9 |
approach bears a risk of significant damage.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
[1] https://www.freedesktop.org/wiki/Software/systemd/inhibit/
|
|
|
44a72b9 |
|
|
|
44a72b9 |
(cherry picked from commit df75a1a8aa5420335a56093077fa8cfcbfffac78)
|
|
|
44a72b9 |
---
|
|
|
44a72b9 |
src/login/logind-dbus.c | 91 ++++++++++++++++++++++++++-----------------------
|
|
|
44a72b9 |
1 file changed, 48 insertions(+), 43 deletions(-)
|
|
|
44a72b9 |
|
|
|
44a72b9 |
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
|
|
|
44a72b9 |
index 3f05c86f5c..1fd64d32b7 100644
|
|
|
44a72b9 |
--- a/src/login/logind-dbus.c
|
|
|
44a72b9 |
+++ b/src/login/logind-dbus.c
|
|
|
44a72b9 |
@@ -1399,7 +1399,6 @@ static int have_multiple_sessions(
|
|
|
44a72b9 |
|
|
|
44a72b9 |
static int bus_manager_log_shutdown(
|
|
|
44a72b9 |
Manager *m,
|
|
|
44a72b9 |
- InhibitWhat w,
|
|
|
44a72b9 |
const char *unit_name) {
|
|
|
44a72b9 |
|
|
|
44a72b9 |
const char *p, *q;
|
|
|
44a72b9 |
@@ -1407,9 +1406,6 @@ static int bus_manager_log_shutdown(
|
|
|
44a72b9 |
assert(m);
|
|
|
44a72b9 |
assert(unit_name);
|
|
|
44a72b9 |
|
|
|
44a72b9 |
- if (w != INHIBIT_SHUTDOWN)
|
|
|
44a72b9 |
- return 0;
|
|
|
44a72b9 |
-
|
|
|
44a72b9 |
if (streq(unit_name, SPECIAL_POWEROFF_TARGET)) {
|
|
|
44a72b9 |
p = "MESSAGE=System is powering down";
|
|
|
44a72b9 |
q = "SHUTDOWN=power-off";
|
|
|
44a72b9 |
@@ -1484,21 +1480,6 @@ int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
|
|
|
44a72b9 |
return r;
|
|
|
44a72b9 |
}
|
|
|
44a72b9 |
|
|
|
44a72b9 |
-static void reset_scheduled_shutdown(Manager *m) {
|
|
|
44a72b9 |
- m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
|
|
|
44a72b9 |
- m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
|
|
|
44a72b9 |
- m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
|
|
|
44a72b9 |
- m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
|
|
|
44a72b9 |
- m->scheduled_shutdown_timeout = 0;
|
|
|
44a72b9 |
- m->shutdown_dry_run = false;
|
|
|
44a72b9 |
-
|
|
|
44a72b9 |
- if (m->unlink_nologin) {
|
|
|
44a72b9 |
- (void) unlink("/run/nologin");
|
|
|
44a72b9 |
- m->unlink_nologin = false;
|
|
|
44a72b9 |
- }
|
|
|
44a72b9 |
- (void) unlink("/run/systemd/shutdown/scheduled");
|
|
|
44a72b9 |
-}
|
|
|
44a72b9 |
-
|
|
|
44a72b9 |
static int execute_shutdown_or_sleep(
|
|
|
44a72b9 |
Manager *m,
|
|
|
44a72b9 |
InhibitWhat w,
|
|
|
44a72b9 |
@@ -1515,32 +1496,28 @@ static int execute_shutdown_or_sleep(
|
|
|
44a72b9 |
assert(w < _INHIBIT_WHAT_MAX);
|
|
|
44a72b9 |
assert(unit_name);
|
|
|
44a72b9 |
|
|
|
44a72b9 |
- bus_manager_log_shutdown(m, w, unit_name);
|
|
|
44a72b9 |
+ if (w == INHIBIT_SHUTDOWN)
|
|
|
44a72b9 |
+ bus_manager_log_shutdown(m, unit_name);
|
|
|
44a72b9 |
|
|
|
44a72b9 |
- if (m->shutdown_dry_run) {
|
|
|
44a72b9 |
- log_info("Running in dry run, suppressing action.");
|
|
|
44a72b9 |
- reset_scheduled_shutdown(m);
|
|
|
44a72b9 |
- } else {
|
|
|
44a72b9 |
- r = sd_bus_call_method(
|
|
|
44a72b9 |
- m->bus,
|
|
|
44a72b9 |
- "org.freedesktop.systemd1",
|
|
|
44a72b9 |
- "/org/freedesktop/systemd1",
|
|
|
44a72b9 |
- "org.freedesktop.systemd1.Manager",
|
|
|
44a72b9 |
- "StartUnit",
|
|
|
44a72b9 |
- error,
|
|
|
44a72b9 |
- &reply,
|
|
|
44a72b9 |
- "ss", unit_name, "replace-irreversibly");
|
|
|
44a72b9 |
- if (r < 0)
|
|
|
44a72b9 |
- return r;
|
|
|
44a72b9 |
+ r = sd_bus_call_method(
|
|
|
44a72b9 |
+ m->bus,
|
|
|
44a72b9 |
+ "org.freedesktop.systemd1",
|
|
|
44a72b9 |
+ "/org/freedesktop/systemd1",
|
|
|
44a72b9 |
+ "org.freedesktop.systemd1.Manager",
|
|
|
44a72b9 |
+ "StartUnit",
|
|
|
44a72b9 |
+ error,
|
|
|
44a72b9 |
+ &reply,
|
|
|
44a72b9 |
+ "ss", unit_name, "replace-irreversibly");
|
|
|
44a72b9 |
+ if (r < 0)
|
|
|
44a72b9 |
+ return r;
|
|
|
44a72b9 |
|
|
|
44a72b9 |
- r = sd_bus_message_read(reply, "o", &p);
|
|
|
44a72b9 |
- if (r < 0)
|
|
|
44a72b9 |
- return r;
|
|
|
44a72b9 |
+ r = sd_bus_message_read(reply, "o", &p);
|
|
|
44a72b9 |
+ if (r < 0)
|
|
|
44a72b9 |
+ return r;
|
|
|
44a72b9 |
|
|
|
44a72b9 |
- c = strdup(p);
|
|
|
44a72b9 |
- if (!c)
|
|
|
44a72b9 |
- return -ENOMEM;
|
|
|
44a72b9 |
- }
|
|
|
44a72b9 |
+ c = strdup(p);
|
|
|
44a72b9 |
+ if (!c)
|
|
|
44a72b9 |
+ return -ENOMEM;
|
|
|
44a72b9 |
|
|
|
44a72b9 |
m->action_unit = unit_name;
|
|
|
44a72b9 |
free(m->action_job);
|
|
|
44a72b9 |
@@ -1924,6 +1901,21 @@ fail:
|
|
|
44a72b9 |
return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
|
|
|
44a72b9 |
}
|
|
|
44a72b9 |
|
|
|
44a72b9 |
+static void reset_scheduled_shutdown(Manager *m) {
|
|
|
44a72b9 |
+ m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
|
|
|
44a72b9 |
+ m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
|
|
|
44a72b9 |
+ m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
|
|
|
44a72b9 |
+ m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type);
|
|
|
44a72b9 |
+ m->scheduled_shutdown_timeout = 0;
|
|
|
44a72b9 |
+ m->shutdown_dry_run = false;
|
|
|
44a72b9 |
+
|
|
|
44a72b9 |
+ if (m->unlink_nologin) {
|
|
|
44a72b9 |
+ (void) unlink("/run/nologin");
|
|
|
44a72b9 |
+ m->unlink_nologin = false;
|
|
|
44a72b9 |
+ }
|
|
|
44a72b9 |
+ (void) unlink("/run/systemd/shutdown/scheduled");
|
|
|
44a72b9 |
+}
|
|
|
44a72b9 |
+
|
|
|
44a72b9 |
static int manager_scheduled_shutdown_handler(
|
|
|
44a72b9 |
sd_event_source *s,
|
|
|
44a72b9 |
uint64_t usec,
|
|
|
44a72b9 |
@@ -1952,7 +1944,20 @@ static int manager_scheduled_shutdown_handler(
|
|
|
44a72b9 |
return -EALREADY;
|
|
|
44a72b9 |
}
|
|
|
44a72b9 |
|
|
|
44a72b9 |
- r = execute_shutdown_or_sleep(m, INHIBIT_SHUTDOWN, target, &error);
|
|
|
44a72b9 |
+ if (m->shutdown_dry_run) {
|
|
|
44a72b9 |
+ /* We do not process delay inhibitors here. Otherwise, we
|
|
|
44a72b9 |
+ * would have to be considered "in progress" (like the check
|
|
|
44a72b9 |
+ * above) for some seconds after our admin has seen the final
|
|
|
44a72b9 |
+ * wall message. */
|
|
|
44a72b9 |
+
|
|
|
44a72b9 |
+ bus_manager_log_shutdown(m, target);
|
|
|
44a72b9 |
+ log_info("Running in dry run, suppressing action.");
|
|
|
44a72b9 |
+ reset_scheduled_shutdown(m);
|
|
|
44a72b9 |
+
|
|
|
44a72b9 |
+ return 0;
|
|
|
44a72b9 |
+ }
|
|
|
44a72b9 |
+
|
|
|
44a72b9 |
+ r = bus_manager_shutdown_or_sleep_now_or_later(m, target, INHIBIT_SHUTDOWN, &error);
|
|
|
44a72b9 |
if (r < 0)
|
|
|
44a72b9 |
return log_error_errno(r, "Scheduled shutdown to %s failed: %m", target);
|
|
|
44a72b9 |
|