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) {
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);
}
}
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;
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;
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;
}
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);
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) {
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) {
[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);