[systemd-commits] 2 commits - src/login
Lennart Poettering
lennart at kemper.freedesktop.org
Thu May 31 10:48:00 PDT 2012
src/login/logind-session.c | 6 ++--
src/login/logind-user.c | 42 ++++++++++++++++++++---------
src/login/logind-user.h | 1
src/login/logind.c | 65 +++++++++++++++++++++++++++++++++++++++------
src/login/logind.h | 5 ++-
5 files changed, 94 insertions(+), 25 deletions(-)
New commits:
commit e96cd586c5195b73af74791280d8461510258b48
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu May 31 19:47:52 2012 +0200
logind: add new user state 'closing'
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 8bd7730..4622812 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -523,9 +523,21 @@ int user_get_idle_hint(User *u, dual_timestamp *t) {
return idle_hint;
}
+static int user_check_linger_file(User *u) {
+ char *p;
+ int r;
+
+ if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0)
+ return -ENOMEM;
+
+ r = access(p, F_OK) >= 0;
+ free(p);
+
+ return r;
+}
+
int user_check_gc(User *u, bool drop_not_started) {
int r;
- char *p;
assert(u);
@@ -535,13 +547,7 @@ int user_check_gc(User *u, bool drop_not_started) {
if (u->sessions)
return 1;
- if (asprintf(&p, "/var/lib/systemd/linger/%s", u->name) < 0)
- return -ENOMEM;
-
- r = access(p, F_OK) >= 0;
- free(p);
-
- if (r > 0)
+ if (user_check_linger_file(u) > 0)
return 1;
if (u->cgroup_path) {
@@ -571,14 +577,17 @@ UserState user_get_state(User *u) {
assert(u);
- if (!u->sessions)
- return USER_LINGERING;
-
LIST_FOREACH(sessions_by_user, i, u->sessions)
if (session_is_active(i))
return USER_ACTIVE;
- return USER_ONLINE;
+ if (u->sessions)
+ return USER_ONLINE;
+
+ if (user_check_linger_file(u) > 0)
+ return USER_LINGERING;
+
+ return USER_CLOSING;
}
int user_kill(User *u, int signo) {
@@ -609,7 +618,8 @@ static const char* const user_state_table[_USER_STATE_MAX] = {
[USER_OFFLINE] = "offline",
[USER_LINGERING] = "lingering",
[USER_ONLINE] = "online",
- [USER_ACTIVE] = "active"
+ [USER_ACTIVE] = "active",
+ [USER_CLOSING] = "closing"
};
DEFINE_STRING_TABLE_LOOKUP(user_state, UserState);
diff --git a/src/login/logind-user.h b/src/login/logind-user.h
index 78249ac..93e5fd9 100644
--- a/src/login/logind-user.h
+++ b/src/login/logind-user.h
@@ -34,6 +34,7 @@ typedef enum UserState {
USER_LINGERING,
USER_ONLINE,
USER_ACTIVE,
+ USER_CLOSING,
_USER_STATE_MAX,
_USER_STATE_INVALID = -1
} UserState;
commit 8c8c43515cee56dfc2298998a9e5958308c46f99
Author: Lennart Poettering <lennart at poettering.net>
Date: Thu May 31 19:46:42 2012 +0200
logind: properly clean up user cgroups when they run empty
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 5c8d549..58514ea 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -88,7 +88,7 @@ void session_free(Session *s) {
}
if (s->cgroup_path)
- hashmap_remove(s->manager->cgroups, s->cgroup_path);
+ hashmap_remove(s->manager->session_cgroups, s->cgroup_path);
free(s->cgroup_path);
strv_free(s->controllers);
@@ -527,7 +527,7 @@ static int session_create_cgroup(Session *s) {
}
}
- hashmap_put(s->manager->cgroups, s->cgroup_path, s);
+ hashmap_put(s->manager->session_cgroups, s->cgroup_path, s);
return 0;
}
@@ -646,7 +646,7 @@ static int session_terminate_cgroup(Session *s) {
STRV_FOREACH(k, s->user->manager->controllers)
cg_trim(*k, s->cgroup_path, true);
- hashmap_remove(s->manager->cgroups, s->cgroup_path);
+ hashmap_remove(s->manager->session_cgroups, s->cgroup_path);
free(s->cgroup_path);
s->cgroup_path = NULL;
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index b971845..8bd7730 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -75,6 +75,8 @@ void user_free(User *u) {
while (u->sessions)
session_free(u->sessions);
+ if (u->cgroup_path)
+ hashmap_remove(u->manager->user_cgroups, u->cgroup_path);
free(u->cgroup_path);
free(u->service);
@@ -313,6 +315,8 @@ static int user_create_cgroup(User *u) {
log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r));
}
+ hashmap_put(u->manager->user_cgroups, u->cgroup_path, u);
+
return 0;
}
@@ -417,6 +421,8 @@ static int user_terminate_cgroup(User *u) {
STRV_FOREACH(k, u->manager->controllers)
cg_trim(*k, u->cgroup_path, true);
+ hashmap_remove(u->manager->user_cgroups, u->cgroup_path);
+
free(u->cgroup_path);
u->cgroup_path = NULL;
diff --git a/src/login/logind.c b/src/login/logind.c
index 632987c..62f7914 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -64,13 +64,16 @@ Manager *manager_new(void) {
m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
m->buttons = hashmap_new(string_hash_func, string_compare_func);
- m->cgroups = hashmap_new(string_hash_func, string_compare_func);
+ m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
+ m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
+
m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
- !m->cgroups || !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
+ !m->user_cgroups || !m->session_cgroups ||
+ !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
manager_free(m);
return NULL;
}
@@ -131,7 +134,9 @@ void manager_free(Manager *m) {
hashmap_free(m->inhibitors);
hashmap_free(m->buttons);
- hashmap_free(m->cgroups);
+ hashmap_free(m->user_cgroups);
+ hashmap_free(m->session_cgroups);
+
hashmap_free(m->session_fds);
hashmap_free(m->inhibitor_fds);
hashmap_free(m->button_fds);
@@ -1008,7 +1013,7 @@ int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **sess
assert(cgroup);
assert(session);
- s = hashmap_get(m->cgroups, cgroup);
+ s = hashmap_get(m->session_cgroups, cgroup);
if (s) {
*session = s;
return 1;
@@ -1032,7 +1037,7 @@ int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **sess
*e = 0;
- s = hashmap_get(m->cgroups, p);
+ s = hashmap_get(m->session_cgroups, p);
if (s) {
free(p);
*session = s;
@@ -1041,6 +1046,47 @@ int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **sess
}
}
+int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
+ User *u;
+ char *p;
+
+ assert(m);
+ assert(cgroup);
+ assert(user);
+
+ u = hashmap_get(m->user_cgroups, cgroup);
+ if (u) {
+ *user = u;
+ return 1;
+ }
+
+ p = strdup(cgroup);
+ if (!p) {
+ log_error("Out of memory.");
+ return -ENOMEM;
+ }
+
+ for (;;) {
+ char *e;
+
+ e = strrchr(p, '/');
+ if (!e || e == p) {
+ free(p);
+ *user = NULL;
+ return 0;
+ }
+
+ *e = 0;
+
+ u = hashmap_get(m->user_cgroups, p);
+ if (u) {
+ free(p);
+ *user = u;
+ return 1;
+ }
+ }
+}
+
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
char *p;
int r;
@@ -1061,13 +1107,16 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
Session *s;
+ User *u;
int r;
r = manager_get_session_by_cgroup(m, cgroup, &s);
- if (r <= 0)
- return;
+ if (r > 0)
+ session_add_to_gc_queue(s);
- session_add_to_gc_queue(s);
+ r = manager_get_user_by_cgroup(m, cgroup, &u);
+ if (r > 0)
+ user_add_to_gc_queue(u);
}
static void manager_dispatch_other(Manager *m, int fd) {
diff --git a/src/login/logind.h b/src/login/logind.h
index 6fcef6f..5e828bf 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -81,7 +81,9 @@ struct Manager {
unsigned long session_counter;
unsigned long inhibit_counter;
- Hashmap *cgroups;
+ Hashmap *session_cgroups;
+ Hashmap *user_cgroups;
+
Hashmap *session_fds;
Hashmap *inhibitor_fds;
Hashmap *button_fds;
@@ -146,6 +148,7 @@ void manager_gc(Manager *m, bool drop_not_started);
int manager_get_idle_hint(Manager *m, dual_timestamp *t);
+int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user);
int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session);
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
More information about the systemd-commits
mailing list