chiark / gitweb /
random-seed: fix error message typo
[elogind.git] / src / login / logind-user.c
index 8bd773086e11a6653a03122ee328c6b28b25517e..b692b533e25f0341dd7f8fc0c02a1c51b9dc31b1 100644 (file)
@@ -180,6 +180,20 @@ int user_save(User *u) {
                         fputs(i->id, f);
                 }
 
+                fputs("\nONLINE_SESSIONS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (session_get_state(i) == SESSION_CLOSING)
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->id, f);
+                }
+
                 fputs("\nACTIVE_SEATS=", f);
                 first = true;
                 LIST_FOREACH(sessions_by_user, i, u->sessions) {
@@ -189,7 +203,23 @@ int user_save(User *u) {
                         if (first)
                                 first = false;
                         else
-                                fputs(i->seat->id, f);
+                                fputc(' ', f);
+
+                        fputs(i->seat->id, f);
+                }
+
+                fputs("\nONLINE_SEATS=", f);
+                first = true;
+                LIST_FOREACH(sessions_by_user, i, u->sessions) {
+                        if (session_get_state(i) == SESSION_CLOSING || !i->seat)
+                                continue;
+
+                        if (first)
+                                first = false;
+                        else
+                                fputc(' ', f);
+
+                        fputs(i->seat->id, f);
                 }
                 fputc('\n', f);
         }
@@ -259,12 +289,8 @@ static int user_mkdir_runtime_path(User *u) {
         }
 
         if (!u->runtime_path) {
-                p = strappend("/run/user/", u->name);
-
-                if (!p) {
-                        log_error("Out of memory");
-                        return -ENOMEM;
-                }
+                if (asprintf(&p, "/run/user/%lu", (unsigned long) u->uid) < 0)
+                        return log_oom();
         } else
                 p = u->runtime_path;
 
@@ -288,10 +314,8 @@ static int user_create_cgroup(User *u) {
         assert(u);
 
         if (!u->cgroup_path) {
-                if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0) {
-                        log_error("Out of memory");
-                        return -ENOMEM;
-                }
+                if (asprintf(&p, "%s/%s", u->manager->cgroup_path, u->name) < 0)
+                        return log_oom();
         } else
                 p = u->cgroup_path;
 
@@ -315,7 +339,9 @@ 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);
+        r = hashmap_put(u->manager->user_cgroups, u->cgroup_path, u);
+        if (r < 0)
+                log_warning("Failed to create mapping between cgroup and user");
 
         return 0;
 }
@@ -523,9 +549,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 +573,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) {
@@ -568,17 +600,25 @@ void user_add_to_gc_queue(User *u) {
 
 UserState user_get_state(User *u) {
         Session *i;
+        bool all_closing = true;
 
         assert(u);
 
-        if (!u->sessions)
-                return USER_LINGERING;
 
-        LIST_FOREACH(sessions_by_user, i, u->sessions)
+        LIST_FOREACH(sessions_by_user, i, u->sessions) {
                 if (session_is_active(i))
                         return USER_ACTIVE;
+                if (session_get_state(i) != SESSION_CLOSING)
+                        all_closing = false;
+        }
+
+        if (u->sessions)
+                return all_closing ? USER_CLOSING : USER_ONLINE;
+
+        if (user_check_linger_file(u) > 0)
+                return USER_LINGERING;
 
-        return USER_ONLINE;
+        return USER_CLOSING;
 }
 
 int user_kill(User *u, int signo) {
@@ -609,7 +649,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);