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