if (!s)
return NULL;
- s->state_file = strappend("/run/systemd/session/", id);
+ s->state_file = strappend("/run/systemd/sessions/", id);
if (!s->state_file) {
free(s);
return NULL;
s->user->display = NULL;
}
- if (s->seat)
+ if (s->seat) {
+ if (s->seat->active == s)
+ s->seat->active = NULL;
+
LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s);
+ }
+
+ if (s->cgroup_path)
+ hashmap_remove(s->manager->cgroups, s->cgroup_path);
free(s->cgroup_path);
strv_free(s->controllers);
free(s->display);
free(s->remote_host);
free(s->remote_user);
+ free(s->service);
hashmap_remove(s->manager->sessions, s->id);
+ if (s->pipe_fd >= 0)
+ close_nointr_nofail(s->pipe_fd);
+
free(s->state_file);
free(s);
}
assert(s);
- r = safe_mkdir("/run/systemd/session", 0755, 0, 0);
+ r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0);
if (r < 0)
goto finish;
"REMOTE_USER=%s\n",
s->remote_user);
+ if (s->service)
+ fprintf(f,
+ "SERVICE=%s\n",
+ s->service);
+
if (s->seat && seat_is_vtconsole(s->seat))
fprintf(f,
"VTNR=%i\n",
"DISPLAY", &s->display,
"REMOTE_HOST", &s->remote_host,
"REMOTE_USER", &s->remote_user,
+ "SERVICE", &s->service,
"VTNR", &vtnr,
"LEADER", &leader,
- "AUDIT_ID", &audit_id,
NULL);
if (r < 0)
s->kill_processes = k;
}
- if (seat) {
+ if (seat && !s->seat) {
Seat *o;
o = hashmap_get(s->manager->seats, seat);
pid_t pid;
k = parse_pid(leader, &pid);
- if (k >= 0 && pid >= 1)
+ if (k >= 0 && pid >= 1) {
s->leader = pid;
- }
- if (audit_id) {
- uint32_t l;
-
- k = safe_atou32(audit_id, &l);
- if (k >= 0 && l >= l)
- s->audit_id = l;
+ audit_session_from_pid(pid, &s->audit_id);
+ }
}
finish:
return 0;
}
+static int session_create_one_group(Session *s, const char *controller, const char *path) {
+ int r;
+
+ assert(s);
+ assert(controller);
+ assert(path);
+
+ if (s->leader > 0)
+ r = cg_create_and_attach(controller, path, s->leader);
+ else
+ r = cg_create(controller, path);
+
+ if (r < 0)
+ return r;
+
+ r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid);
+ if (r >= 0)
+ r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid);
+
+ return r;
+}
+
static int session_create_cgroup(Session *s) {
char **k;
char *p;
} else
p = s->cgroup_path;
- if (s->leader > 0)
- r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, p, s->leader);
- else
- r = cg_create(SYSTEMD_CGROUP_CONTROLLER, p);
-
+ r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, p);
if (r < 0) {
free(p);
s->cgroup_path = NULL;
s->cgroup_path = p;
+ STRV_FOREACH(k, s->controllers) {
+
+ if (strv_contains(s->reset_controllers, *k))
+ continue;
+
+ r = session_create_one_group(s, *k, p);
+ if (r < 0)
+ log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r));
+ }
+
STRV_FOREACH(k, s->manager->controllers) {
- if (s->leader > 0)
- r = cg_create_and_attach(*k, p, s->leader);
- else
- r = cg_create(*k, p);
+ if (strv_contains(s->reset_controllers, *k) ||
+ strv_contains(s->controllers, *k))
+ continue;
+
+ r = session_create_one_group(s, *k, p);
if (r < 0)
- log_warning("Failed to create cgroup %s:%s: %s", *k, p, strerror(-r));
+ log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r));
}
+ if (s->leader > 0) {
+
+ STRV_FOREACH(k, s->reset_controllers) {
+ r = cg_attach(*k, "/", s->leader);
+ if (r < 0)
+ log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
+
+ }
+ }
+
+ hashmap_put(s->manager->cgroups, s->cgroup_path, s);
+
return 0;
}
assert(s);
assert(s->user);
+ if (s->started)
+ return 0;
+
+ r = user_start(s->user);
+ if (r < 0)
+ return r;
+
+ log_info("New session %s of user %s.", s->id, s->user->name);
+
/* Create cgroup */
r = session_create_cgroup(s);
if (r < 0)
dual_timestamp_get(&s->timestamp);
+ s->started = true;
+
+ session_send_signal(s, true);
+
+ if (s->seat) {
+ if (s->seat->active == s)
+ seat_send_changed(s->seat, "Sessions\0ActiveSession\0");
+ else
+ seat_send_changed(s->seat, "Sessions\0");
+ }
+
+ user_send_changed(s->user, "Sessions\0");
+
return 0;
}
static bool session_shall_kill(Session *s) {
assert(s);
- return s->kill_processes;
+ if (!s->kill_processes)
+ return false;
+
+ if (strv_contains(s->manager->kill_exclude_users, s->user->name))
+ return false;
+
+ if (strv_isempty(s->manager->kill_only_users))
+ return true;
+
+ return strv_contains(s->manager->kill_only_users, s->user->name);
}
static int session_kill_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);
+
free(s->cgroup_path);
s->cgroup_path = NULL;
assert(s);
+ if (s->started)
+ log_info("Removed session %s.", s->id);
+
/* Kill cgroup */
k = session_kill_cgroup(s);
if (k < 0)
unlink(s->state_file);
session_add_to_gc_queue(s);
+ user_add_to_gc_queue(s->user);
+
+ if (s->started)
+ session_send_signal(s, false);
+
+ if (s->seat) {
+ if (s->seat->active == s)
+ seat_set_active(s->seat, NULL);
+
+ seat_send_changed(s->seat, "Sessions\0");
+ }
+
+ user_send_changed(s->user, "Sessions\0");
+
+ s->started = false;
return r;
}
s->idle_hint = b;
dual_timestamp_get(&s->idle_hint_timestamp);
+
+ session_send_changed(s,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
+
+ if (s->seat)
+ seat_send_changed(s->seat,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
+
+ user_send_changed(s->user,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
+
+ manager_send_changed(s->manager,
+ "IdleHint\0"
+ "IdleSinceHint\0"
+ "IdleSinceHintMonotonic\0");
}
int session_check_gc(Session *s) {
static const char* const session_type_table[_SESSION_TYPE_MAX] = {
[SESSION_TTY] = "tty",
- [SESSION_X11] = "x11"
+ [SESSION_X11] = "x11",
+ [SESSION_OTHER] = "other"
};
DEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);