logind-session.c revision fc3c1c6e091ea16ad5600b145201ec535bbb5d7c
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2011 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#define IDLE_THRESHOLD_USEC (5*USEC_PER_MINUTE)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringSession* session_new(Manager *m, User *u, const char *id) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering s->state_file = strappend("/run/systemd/sessions/", id);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering s->id = file_name_from_path(s->state_file);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (hashmap_put(m->sessions, s->id, s) < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_PREPEND(Session, sessions_by_user, u->sessions, s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_REMOVE(Session, gc_queue, s->manager->session_gc_queue, s);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hashmap_remove(s->manager->cgroups, s->cgroup_path);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hashmap_remove(s->manager->sessions, s->id);
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0);
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering r = fopen_temporary(s->state_file, &f, &temp_path);
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek "# This is private data. Do not parse.\n"
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek "KILL_PROCESSES=%i\n",
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "CGROUP=%s\n",
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering "DISPLAY=%s\n",
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering "REMOTE_HOST=%s\n",
s->remote_user);
if (s->service)
fprintf(f,
s->service);
fprintf(f,
s->vtnr);
if (s->leader > 0)
fprintf(f,
(unsigned long) s->leader);
if (s->audit_id > 0)
fprintf(f,
(unsigned long long) s->audit_id);
fflush(f);
r = -errno;
fclose(f);
assert(s);
NULL);
goto finish;
if (remote) {
s->remote = k;
if (kill_processes) {
s->kill_processes = k;
Seat *o;
seat_attach_session(o, s);
s->vtnr = v;
if (leader) {
if (type) {
SessionType t;
s->type = t;
if (s->fifo_path) {
int fd;
if (fd >= 0)
assert(s);
if (s->vtnr < 0)
return -ENOTSUP;
if (!s->seat)
return -ENOTSUP;
size_t k;
assert(s);
return -ENOMEM;
free(f);
return -ENOENT;
free(f);
return -ENOMEM;
if (link(f, t) < 0) {
unlink(t);
if (link(f, t) >= 0)
goto done;
if (symlink(f, t) < 0) {
unlink(t);
if (symlink(f, t) >= 0)
goto done;
free(f);
free(t);
return -errno;
done:
free(f);
free(t);
assert(s);
if (s->leader > 0) {
assert(s);
if (!s->cgroup_path) {
return -ENOMEM;
p = s->cgroup_path;
free(p);
s->cgroup_path = p;
r = session_create_one_group(s, *k, p);
r = session_create_one_group(s, *k, p);
if (s->leader > 0) {
assert(s);
if (s->started)
r = session_create_cgroup(s);
if (s->seat)
s->started = true;
session_save(s);
session_send_signal(s, true);
if (s->seat) {
assert(s);
if (!s->kill_processes)
assert(s);
if (!s->cgroup_path)
if (session_shall_kill(s)) {
r = -EBUSY;
assert(s);
return -ENOMEM;
r = unlink(t);
free(t);
return r < 0 ? -errno : 0;
assert(s);
if (s->started)
k = session_terminate_cgroup(s);
if (s->started)
session_send_signal(s, false);
if (s->seat) {
s->started = false;
assert(s);
if (!s->seat)
usec_t u, n;
assert(s);
if (s->idle_hint) {
*t = s->idle_hint_timestamp;
return s->idle_hint;
goto dont_know;
return -ENOMEM;
p = NULL;
free(p);
goto dont_know;
free(p);
goto dont_know;
b = u + IDLE_THRESHOLD_USEC < n;
*t = s->idle_hint_timestamp;
assert(s);
if (s->idle_hint == b)
s->idle_hint = b;
if (s->seat)
assert(s);
if (!s->fifo_path) {
return -ENOMEM;
return -errno;
if (s->fifo_fd < 0) {
if (s->fifo_fd < 0)
return -errno;
return -errno;
return -errno;
assert(s);
if (s->fifo_fd >= 0) {
if (s->fifo_path) {
assert(s);
if (s->fifo_fd >= 0) {
if (s->cgroup_path) {
assert(s);
if (s->in_gc_queue)
s->in_gc_queue = true;
assert(s);
if (!s->cgroup_path)
return -ESRCH;
return -ESRCH;
if (s->leader > 0)
r = -errno;
if (!pid_set)
return -ENOMEM;
if (s->leader > 0) {
q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set);
if (pid_set)