|
|
b12df0 |
From 89dd5e016a50da082e51129eecb3c5e04b8f0cf5 Mon Sep 17 00:00:00 2001
|
|
|
b12df0 |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
b12df0 |
Date: Wed, 8 Aug 2018 16:04:40 +0200
|
|
|
b12df0 |
Subject: [PATCH] logind: automatically GC lingering users for who now
|
|
|
b12df0 |
user@.service (nor slice, not runtime dir service) is running anymore
|
|
|
b12df0 |
|
|
|
b12df0 |
This heavily borrows from @intelfx' PR #5546, but watches all three
|
|
|
b12df0 |
units that are associated with a user now: the slice, the user@.service
|
|
|
b12df0 |
and user-runtime-dir@.service.
|
|
|
b12df0 |
|
|
|
b12df0 |
The logic and reasoning behind it is the same though: there's no value
|
|
|
b12df0 |
in keeping lingering users around if all their three services are gone.
|
|
|
b12df0 |
|
|
|
b12df0 |
Replaces: #5546
|
|
|
b12df0 |
Fixes: #4162
|
|
|
b12df0 |
(cherry picked from commit 4e5b605af202c770dfc8e3562d0f8d0440b2fe14)
|
|
|
b12df0 |
|
|
|
b12df0 |
Related: #1642460
|
|
|
b12df0 |
---
|
|
|
b12df0 |
src/login/logind-user.c | 28 +++++++++++++++++++++++++---
|
|
|
b12df0 |
1 file changed, 25 insertions(+), 3 deletions(-)
|
|
|
b12df0 |
|
|
|
b12df0 |
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
|
|
|
b12df0 |
index 3fd28fc66c..bba3158d1a 100644
|
|
|
b12df0 |
--- a/src/login/logind-user.c
|
|
|
b12df0 |
+++ b/src/login/logind-user.c
|
|
|
b12df0 |
@@ -26,6 +26,7 @@
|
|
|
b12df0 |
#include "special.h"
|
|
|
b12df0 |
#include "stdio-util.h"
|
|
|
b12df0 |
#include "string-table.h"
|
|
|
b12df0 |
+#include "strv.h"
|
|
|
b12df0 |
#include "unit-name.h"
|
|
|
b12df0 |
#include "user-util.h"
|
|
|
b12df0 |
#include "util.h"
|
|
|
b12df0 |
@@ -542,6 +543,25 @@ int user_check_linger_file(User *u) {
|
|
|
b12df0 |
return true;
|
|
|
b12df0 |
}
|
|
|
b12df0 |
|
|
|
b12df0 |
+static bool user_unit_active(User *u) {
|
|
|
b12df0 |
+ const char *i;
|
|
|
b12df0 |
+ int r;
|
|
|
b12df0 |
+
|
|
|
b12df0 |
+ assert(u->service);
|
|
|
b12df0 |
+ assert(u->runtime_dir_service);
|
|
|
b12df0 |
+ assert(u->slice);
|
|
|
b12df0 |
+
|
|
|
b12df0 |
+ FOREACH_STRING(i, u->service, u->runtime_dir_service, u->slice) {
|
|
|
b12df0 |
+ r = manager_unit_is_active(u->manager, i);
|
|
|
b12df0 |
+ if (r < 0)
|
|
|
b12df0 |
+ log_debug_errno(r, "Failed to determine whether unit '%s' is active, ignoring", u->service);
|
|
|
b12df0 |
+ if (r != 0)
|
|
|
b12df0 |
+ return true;
|
|
|
b12df0 |
+ }
|
|
|
b12df0 |
+
|
|
|
b12df0 |
+ return false;
|
|
|
b12df0 |
+}
|
|
|
b12df0 |
+
|
|
|
b12df0 |
bool user_may_gc(User *u, bool drop_not_started) {
|
|
|
b12df0 |
assert(u);
|
|
|
b12df0 |
|
|
|
b12df0 |
@@ -561,8 +581,10 @@ bool user_may_gc(User *u, bool drop_not_started) {
|
|
|
b12df0 |
return false; /* Leave it around for a bit longer. */
|
|
|
b12df0 |
}
|
|
|
b12df0 |
|
|
|
b12df0 |
- /* Is this a user that shall stay around forever? */
|
|
|
b12df0 |
- if (user_check_linger_file(u) > 0)
|
|
|
b12df0 |
+ /* Is this a user that shall stay around forever ("linger")? Before we say "no" to GC'ing for lingering users, let's check
|
|
|
b12df0 |
+ * if any of the three units that we maintain for this user is still around. If none of them is,
|
|
|
b12df0 |
+ * there's no need to keep this user around even if lingering is enabled. */
|
|
|
b12df0 |
+ if (user_check_linger_file(u) > 0 && user_unit_active(u))
|
|
|
b12df0 |
return false;
|
|
|
b12df0 |
|
|
|
b12df0 |
if (u->service_job && manager_job_is_active(u->manager, u->service_job))
|
|
|
b12df0 |
@@ -608,7 +630,7 @@ UserState user_get_state(User *u) {
|
|
|
b12df0 |
return all_closing ? USER_CLOSING : USER_ONLINE;
|
|
|
b12df0 |
}
|
|
|
b12df0 |
|
|
|
b12df0 |
- if (user_check_linger_file(u) > 0)
|
|
|
b12df0 |
+ if (user_check_linger_file(u) > 0 && user_unit_active(u))
|
|
|
b12df0 |
return USER_LINGERING;
|
|
|
b12df0 |
|
|
|
b12df0 |
return USER_CLOSING;
|