summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-08-06 18:14:11 +0200
committerSven Eden <sven.eden@prydeworx.com>2018-10-29 10:18:33 +0100
commitccad78e82eb9ee47bda89f662318f4cbed53b904 (patch)
tree910d7794c780586581a13c4a816f1926f3cb9745
parent74aa0d64f922ae65cdea1a62059e4c2d5d7c51f6 (diff)
logind: save/restore User object's "stopping" field during restarts
Whether we are stopping or not is highly relevant, hence don't forget it across restarts. (cherry picked from commit d865bc024bf28c17120d7322a81e9a99997a59f6)
-rw-r--r--src/login/logind-user.c20
-rw-r--r--src/login/logind-user.h5
2 files changed, 18 insertions, 7 deletions
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index e12936129..9468d493d 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -140,9 +140,11 @@ static int user_save_internal(User *u) {
fprintf(f,
"# This is private data. Do not parse.\n"
"NAME=%s\n"
- "STATE=%s\n",
+ "STATE=%s\n" /* friendly user-facing state */
+ "STOPPING=%s\n", /* low-level state */
u->name,
- user_state_to_string(user_get_state(u)));
+ user_state_to_string(user_get_state(u)),
+ yes_no(u->stopping));
/* LEGACY: no-one reads RUNTIME= anymore, drop it at some point */
if (u->runtime_path)
@@ -283,7 +285,7 @@ int user_save(User *u) {
}
int user_load(User *u) {
- _cleanup_free_ char *realtime = NULL, *monotonic = NULL;
+ _cleanup_free_ char *realtime = NULL, *monotonic = NULL, *stopping = NULL;
int r;
assert(u);
@@ -291,8 +293,8 @@ int user_load(User *u) {
r = parse_env_file(NULL, u->state_file, NEWLINE,
#if 0 /// elogind neither supports service nor slice jobs
"SERVICE_JOB", &u->service_job,
- "SLICE_JOB", &u->slice_job,
#endif // 0
+ "STOPPING", &stopping,
"REALTIME", &realtime,
"MONOTONIC", &monotonic,
NULL);
@@ -301,12 +303,20 @@ int user_load(User *u) {
if (r < 0)
return log_error_errno(r, "Failed to read %s: %m", u->state_file);
+ if (stopping) {
+ r = parse_boolean(stopping);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse 'STOPPING' boolean: %s", stopping);
+ else
+ u->stopping = r;
+ }
+
if (realtime)
timestamp_deserialize(realtime, &u->timestamp.realtime);
if (monotonic)
timestamp_deserialize(monotonic, &u->timestamp.monotonic);
- return r;
+ return 0;
}
static int user_start_service(User *u) {
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index afb6f4b1a..9c6dcf074 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -38,8 +38,9 @@ struct User {
dual_timestamp timestamp;
bool in_gc_queue:1;
- bool started:1;
- bool stopping:1;
+
+ bool started:1; /* Whenever the user being started, has been started or is being stopped again. */
+ bool stopping:1; /* Whenever the user is being stopped or has been stopped. */
LIST_HEAD(Session, sessions);
LIST_FIELDS(User, gc_queue);