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);