|
|
b12df0 |
From 4703c08fe3a8bfa1bc9b893e8bde365b1cbeffd9 Mon Sep 17 00:00:00 2001
|
|
|
b12df0 |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
b12df0 |
Date: Mon, 6 Aug 2018 18:14:11 +0200
|
|
|
b12df0 |
Subject: [PATCH] logind: save/restore User object's "stopping" field during
|
|
|
b12df0 |
restarts
|
|
|
b12df0 |
|
|
|
b12df0 |
Whether we are stopping or not is highly relevant, hence don't forget it
|
|
|
b12df0 |
across restarts.
|
|
|
b12df0 |
|
|
|
b12df0 |
(cherry picked from commit d865bc024bf28c17120d7322a81e9a99997a59f6)
|
|
|
b12df0 |
|
|
|
b12df0 |
Related: #1642460
|
|
|
b12df0 |
---
|
|
|
b12df0 |
src/login/logind-user.c | 20 +++++++++++++++-----
|
|
|
b12df0 |
src/login/logind-user.h | 5 +++--
|
|
|
b12df0 |
2 files changed, 18 insertions(+), 7 deletions(-)
|
|
|
b12df0 |
|
|
|
b12df0 |
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
|
|
|
b12df0 |
index 17ed361411..35b2ca5489 100644
|
|
|
b12df0 |
--- a/src/login/logind-user.c
|
|
|
b12df0 |
+++ b/src/login/logind-user.c
|
|
|
b12df0 |
@@ -136,9 +136,11 @@ static int user_save_internal(User *u) {
|
|
|
b12df0 |
fprintf(f,
|
|
|
b12df0 |
"# This is private data. Do not parse.\n"
|
|
|
b12df0 |
"NAME=%s\n"
|
|
|
b12df0 |
- "STATE=%s\n",
|
|
|
b12df0 |
+ "STATE=%s\n" /* friendly user-facing state */
|
|
|
b12df0 |
+ "STOPPING=%s\n", /* low-level state */
|
|
|
b12df0 |
u->name,
|
|
|
b12df0 |
- user_state_to_string(user_get_state(u)));
|
|
|
b12df0 |
+ user_state_to_string(user_get_state(u)),
|
|
|
b12df0 |
+ yes_no(u->stopping));
|
|
|
b12df0 |
|
|
|
b12df0 |
/* LEGACY: no-one reads RUNTIME= anymore, drop it at some point */
|
|
|
b12df0 |
if (u->runtime_path)
|
|
|
b12df0 |
@@ -277,14 +279,14 @@ int user_save(User *u) {
|
|
|
b12df0 |
}
|
|
|
b12df0 |
|
|
|
b12df0 |
int user_load(User *u) {
|
|
|
b12df0 |
- _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
|
|
|
b12df0 |
+ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL;
|
|
|
b12df0 |
int r;
|
|
|
b12df0 |
|
|
|
b12df0 |
assert(u);
|
|
|
b12df0 |
|
|
|
b12df0 |
r = parse_env_file(NULL, u->state_file, NEWLINE,
|
|
|
b12df0 |
"SERVICE_JOB", &u->service_job,
|
|
|
b12df0 |
- "SLICE_JOB", &u->slice_job,
|
|
|
b12df0 |
+ "STOPPING", &stopping,
|
|
|
b12df0 |
"REALTIME", &realtime,
|
|
|
b12df0 |
"MONOTONIC", &monotonic,
|
|
|
b12df0 |
NULL);
|
|
|
b12df0 |
@@ -293,12 +295,20 @@ int user_load(User *u) {
|
|
|
b12df0 |
if (r < 0)
|
|
|
b12df0 |
return log_error_errno(r, "Failed to read %s: %m", u->state_file);
|
|
|
b12df0 |
|
|
|
b12df0 |
+ if (stopping) {
|
|
|
b12df0 |
+ r = parse_boolean(stopping);
|
|
|
b12df0 |
+ if (r < 0)
|
|
|
b12df0 |
+ log_debug_errno(r, "Failed to parse 'STOPPING' boolean: %s", stopping);
|
|
|
b12df0 |
+ else
|
|
|
b12df0 |
+ u->stopping = r;
|
|
|
b12df0 |
+ }
|
|
|
b12df0 |
+
|
|
|
b12df0 |
if (realtime)
|
|
|
b12df0 |
timestamp_deserialize(realtime, &u->timestamp.realtime);
|
|
|
b12df0 |
if (monotonic)
|
|
|
b12df0 |
timestamp_deserialize(monotonic, &u->timestamp.monotonic);
|
|
|
b12df0 |
|
|
|
b12df0 |
- return r;
|
|
|
b12df0 |
+ return 0;
|
|
|
b12df0 |
}
|
|
|
b12df0 |
|
|
|
b12df0 |
static int user_start_service(User *u) {
|
|
|
b12df0 |
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
|
|
|
b12df0 |
index eba2325284..03e020b870 100644
|
|
|
b12df0 |
--- a/src/login/logind-user.h
|
|
|
b12df0 |
+++ b/src/login/logind-user.h
|
|
|
b12df0 |
@@ -36,8 +36,9 @@ struct User {
|
|
|
b12df0 |
dual_timestamp timestamp;
|
|
|
b12df0 |
|
|
|
b12df0 |
bool in_gc_queue:1;
|
|
|
b12df0 |
- bool started:1;
|
|
|
b12df0 |
- bool stopping:1;
|
|
|
b12df0 |
+
|
|
|
b12df0 |
+ bool started:1; /* Whenever the user being started, has been started or is being stopped again. */
|
|
|
b12df0 |
+ bool stopping:1; /* Whenever the user is being stopped or has been stopped. */
|
|
|
b12df0 |
|
|
|
b12df0 |
LIST_HEAD(Session, sessions);
|
|
|
b12df0 |
LIST_FIELDS(User, gc_queue);
|