logind-session.c revision a32360f1a5a85c12f00e9dfb7353280067cccb5b
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/***
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt This file is part of systemd.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt Copyright 2011 Lennart Poettering
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is free software; you can redistribute it and/or modify it
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt under the terms of the GNU Lesser General Public License as published by
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt the Free Software Foundation; either version 2.1 of the License, or
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt (at your option) any later version.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is distributed in the hope that it will be useful, but
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt WITHOUT ANY WARRANTY; without even the implied warranty of
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Lesser General Public License for more details.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt You should have received a copy of the GNU Lesser General Public License
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt along with systemd; If not, see <http://www.gnu.org/licenses/>.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt***/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <errno.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <string.h>
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#include <unistd.h>
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include <sys/epoll.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <fcntl.h>
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "systemd/sd-id128.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "systemd/sd-messages.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "strv.h"
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include "util.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "mkdir.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "path-util.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "cgroup-util.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "logind-session.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "fileio.h"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom GundersenSession* session_new(Manager *m, User *u, const char *id) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Session *s;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams assert(m);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(id);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt s = new0(Session, 1);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!s)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return NULL;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt s->state_file = strappend("/run/systemd/sessions/", id);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (!s->state_file) {
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams free(s);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams return NULL;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt s->id = path_get_file_name(s->state_file);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (hashmap_put(m->sessions, s->id, s) < 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt free(s->state_file);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt free(s);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return NULL;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt s->manager = m;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt s->fifo_fd = -1;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt s->user = u;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt LIST_PREPEND(Session, sessions_by_user, u->sessions, s);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen return s;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktvoid session_free(Session *s) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt assert(s);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (s->in_gc_queue)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt LIST_REMOVE(Session, gc_queue, s->manager->session_gc_queue, s);
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (s->user) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt LIST_REMOVE(Session, sessions_by_user, s->user->sessions, s);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->user->display == s)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt s->user->display = NULL;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->seat) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->seat->active == s)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt s->seat->active = NULL;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt LIST_REMOVE(Session, sessions_by_seat, s->seat->sessions, s);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->cgroup_path)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt hashmap_remove(s->manager->session_cgroups, s->cgroup_path);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(s->cgroup_path);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt strv_free(s->controllers);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->tty);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->display);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->remote_host);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->remote_user);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->service);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt hashmap_remove(s->manager->sessions, s->id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt session_remove_fifo(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->state_file);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt}
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flyktint session_save(Session *s) {
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt FILE *f;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt int r = 0;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt char *temp_path;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt assert(s);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!s->started)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt goto finish;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt r = fopen_temporary(s->state_file, &f, &temp_path);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt goto finish;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(s->user);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt fchmod(fileno(f), 0644);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt fprintf(f,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "# This is private data. Do not parse.\n"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "UID=%lu\n"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "USER=%s\n"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "ACTIVE=%i\n"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams "STATE=%s\n"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams "REMOTE=%i\n"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "KILL_PROCESSES=%i\n",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt (unsigned long) s->user->uid,
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams s->user->name,
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams session_is_active(s),
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams session_state_to_string(session_get_state(s)),
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams s->remote,
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams s->kill_processes);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (s->type >= 0)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams fprintf(f,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "TYPE=%s\n",
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams session_type_to_string(s->type));
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (s->class >= 0)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams fprintf(f,
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams "CLASS=%s\n",
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams session_class_to_string(s->class));
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (s->cgroup_path)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams fprintf(f,
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt "CGROUP=%s\n",
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt s->cgroup_path);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (s->fifo_path)
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller fprintf(f,
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller "FIFO=%s\n",
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller s->fifo_path);
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller if (s->seat)
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller fprintf(f,
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller "SEAT=%s\n",
ebe207d4acf38165adbc45298662982eecdb9e9fTom Gundersen s->seat->id);
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams if (s->tty)
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams fprintf(f,
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams "TTY=%s\n",
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams s->tty);
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (s->display)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen fprintf(f,
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen "DISPLAY=%s\n",
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen s->display);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (s->remote_host)
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen fprintf(f,
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen "REMOTE_HOST=%s\n",
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen s->remote_host);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen if (s->remote_user)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen fprintf(f,
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen "REMOTE_USER=%s\n",
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen s->remote_user);
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (s->service)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen fprintf(f,
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen "SERVICE=%s\n",
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen s->service);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen if (s->seat && seat_can_multi_session(s->seat))
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen fprintf(f,
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen "VTNR=%i\n",
ebe207d4acf38165adbc45298662982eecdb9e9fTom Gundersen s->vtnr);
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams if (s->leader > 0)
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams fprintf(f,
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams "LEADER=%lu\n",
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams (unsigned long) s->leader);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (s->audit_id > 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt fprintf(f,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt "AUDIT=%llu\n",
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt (unsigned long long) s->audit_id);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt fflush(f);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (ferror(f) || rename(temp_path, s->state_file) < 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = -errno;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt unlink(s->state_file);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt unlink(temp_path);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt fclose(f);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt free(temp_path);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktfinish:
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt log_error("Failed to save session data for %s: %s", s->id, strerror(-r));
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt}
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktint session_load(Session *s) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt char *remote = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *kill_processes = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *seat = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *vtnr = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *leader = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *audit_id = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *type = NULL,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt *class = NULL;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt int k, r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt assert(s);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt r = parse_env_file(s->state_file, NEWLINE,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "REMOTE", &remote,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "KILL_PROCESSES", &kill_processes,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "CGROUP", &s->cgroup_path,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "FIFO", &s->fifo_path,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "SEAT", &seat,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "TTY", &s->tty,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "DISPLAY", &s->display,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "REMOTE_HOST", &s->remote_host,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "REMOTE_USER", &s->remote_user,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "SERVICE", &s->service,
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt "VTNR", &vtnr,
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt "LEADER", &leader,
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt "TYPE", &type,
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt "CLASS", &class,
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt NULL);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt if (r < 0)
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt goto finish;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt if (remote) {
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt k = parse_boolean(remote);
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt if (k >= 0)
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt s->remote = k;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt }
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (kill_processes) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt k = parse_boolean(kill_processes);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (k >= 0)
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek s->kill_processes = k;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt if (seat && !s->seat) {
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt Seat *o;
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt o = hashmap_get(s->manager->seats, seat);
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt if (o)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt seat_attach_session(o, s);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek if (vtnr && s->seat && seat_can_multi_session(s->seat)) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt int v;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt k = safe_atoi(vtnr, &v);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (k >= 0 && v >= 1)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt s->vtnr = v;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt }
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (leader) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt k = parse_pid(leader, &s->leader);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (k >= 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt audit_session_from_pid(s->leader, &s->audit_id);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (type) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt SessionType t;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt t = session_type_from_string(type);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (t >= 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt s->type = t;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (class) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt SessionClass c;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt c = session_class_from_string(class);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (c >= 0)
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt s->class = c;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (s->fifo_path) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt int fd;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt /* If we open an unopened pipe for reading we will not
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt get an EOF. to trigger an EOF we hence open it for
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt reading, but close it right-away which then will
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt trigger the EOF. */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt fd = session_create_fifo(s);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (fd >= 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt close_nointr_nofail(fd);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktfinish:
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(remote);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(kill_processes);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(seat);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(vtnr);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(leader);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(audit_id);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(class);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return r;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktint session_activate(Session *s) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt int r;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(s);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (s->vtnr < 0)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt return -ENOTSUP;
926695f1b5f9395eeb416cc2f478a9cf75fdbeb4Thomas Hindoe Paaboel Andersen
926695f1b5f9395eeb416cc2f478a9cf75fdbeb4Thomas Hindoe Paaboel Andersen if (!s->seat)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt return -ENOTSUP;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->seat->active == s)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(seat_is_vtconsole(s->seat));
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt r = chvt(s->vtnr);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return seat_set_active(s->seat, s);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flyktstatic int session_link_x11_socket(Session *s) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt char *t, *f, *c;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt size_t k;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(s);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(s->user);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(s->user->runtime_path);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->user->display)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!s->display || !display_is_local(s->display))
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return 0;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt k = strspn(s->display+1, "0123456789");
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt f = new(char, sizeof("/tmp/.X11-unix/X") + k);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (!f)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return log_oom();
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt c = stpcpy(f, "/tmp/.X11-unix/X");
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt memcpy(c, s->display+1, k);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt c[k] = 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (access(f, F_OK) < 0) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_warning("Session %s has display %s with non-existing socket %s.", s->id, s->display, f);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(f);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return -ENOENT;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt /* Note that this cannot be in a subdir to avoid
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt * vulnerabilities since we are privileged but the runtime
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt * path is owned by the user */
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller t = strappend(s->user->runtime_path, "/X11-display");
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (!t) {
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams free(f);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return log_oom();
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (link(f, t) < 0) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (errno == EEXIST) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt unlink(t);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (link(f, t) >= 0)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt goto done;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt }
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (symlink(f, t) < 0) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (errno == EEXIST) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt unlink(t);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (symlink(f, t) >= 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt goto done;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_error("Failed to link %s to %s: %m", f, t);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(f);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt free(t);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return -errno;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktdone:
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_info("Linked %s to %s.", f, t);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt free(f);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt free(t);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt s->user->display = s;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic int session_create_one_group(Session *s, const char *controller, const char *path) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt int r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(s);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(controller);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(path);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (s->leader > 0) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = cg_create_and_attach(controller, path, s->leader);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = cg_create(controller, path, NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt } else
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = cg_create(controller, path, NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = cg_set_task_access(controller, path, 0644, s->user->uid, s->user->gid, -1);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r >= 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = cg_set_group_access(controller, path, 0755, s->user->uid, s->user->gid);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic int session_create_cgroup(Session *s) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char **k;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char *p;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt int r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(s->user);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(s->user->cgroup_path);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!s->cgroup_path) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (asprintf(&p, "%s/%s", s->user->cgroup_path, s->id) < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return log_oom();
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt } else
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt p = s->cgroup_path;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = session_create_one_group(s, SYSTEMD_CGROUP_CONTROLLER, p);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_error("Failed to create "SYSTEMD_CGROUP_CONTROLLER":%s: %s", p, strerror(-r));
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt free(p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt s->cgroup_path = NULL;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt s->cgroup_path = p;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt STRV_FOREACH(k, s->controllers) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (strv_contains(s->reset_controllers, *k))
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt continue;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = session_create_one_group(s, *k, p);
4b4923e65423e60d755841b5b264730e8f3deab3Tom Gundersen if (r < 0)
5e91345094a9e983e7abb2313334e7808bcd2cc2Tom Gundersen log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r));
513a6fa8679510ea1b55967bdb482dd5f8a39f21Ronny Chevalier }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt STRV_FOREACH(k, s->manager->controllers) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (strv_contains(s->reset_controllers, *k) ||
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt strv_contains(s->manager->reset_controllers, *k) ||
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt strv_contains(s->controllers, *k))
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt continue;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = session_create_one_group(s, *k, p);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_warning("Failed to create %s:%s: %s", *k, p, strerror(-r));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (s->leader > 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt STRV_FOREACH(k, s->reset_controllers) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = cg_attach(*k, "/", s->leader);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (r < 0)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt STRV_FOREACH(k, s->manager->reset_controllers) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (strv_contains(s->reset_controllers, *k) ||
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt strv_contains(s->controllers, *k))
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt continue;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt r = cg_attach(*k, "/", s->leader);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (r < 0)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_warning("Failed to reset controller %s: %s", *k, strerror(-r));
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = hashmap_put(s->manager->session_cgroups, s->cgroup_path, s);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_warning("Failed to create mapping between cgroup and session");
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return 0;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt}
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktint session_start(Session *s) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt int r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt assert(s);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt assert(s->user);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (s->started)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return 0;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = user_start(s->user);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt MESSAGE_ID(SD_MESSAGE_SESSION_START),
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "SESSION_ID=%s", s->id,
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "USER_ID=%s", s->user->name,
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "LEADER=%lu", (unsigned long) s->leader,
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt "MESSAGE=New session %s of user %s.", s->id, s->user->name,
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* Create cgroup */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = session_create_cgroup(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt /* Create X11 symlink */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt session_link_x11_socket(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt dual_timestamp_get(&s->timestamp);
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (s->seat)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt seat_read_active_vt(s->seat);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt s->started = true;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt /* Save session data */
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt session_save(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt user_save(s->user);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt session_send_signal(s, true);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->seat) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt seat_save(s->seat);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (s->seat->active == s)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt seat_send_changed(s->seat, "Sessions\0ActiveSession\0");
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt else
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt seat_send_changed(s->seat, "Sessions\0");
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt user_send_changed(s->user, "Sessions\0");
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return 0;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic bool session_shall_kill(Session *s) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(s);
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!s->kill_processes)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return false;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (strv_contains(s->manager->kill_exclude_users, s->user->name))
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return false;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (strv_isempty(s->manager->kill_only_users))
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return true;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return strv_contains(s->manager->kill_only_users, s->user->name);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersenstatic int session_terminate_cgroup(Session *s) {
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen int r;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen char **k;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!s->cgroup_path)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return 0;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt cg_trim(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false);
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (session_shall_kill(s)) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_error("Failed to kill session cgroup: %s", strerror(-r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt } else {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (s->leader > 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt Session *t;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen /* We still send a HUP to the leader process,
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering * even if we are not supposed to kill the
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen * whole cgroup. But let's first check the
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen * leader still exists and belongs to our
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt * session... */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = manager_get_session_by_pid(s->manager, s->leader, &t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r > 0 && t == s) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt kill(s->leader, SIGTERM); /* for normal processes */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt kill(s->leader, SIGHUP); /* for shells */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt kill(s->leader, SIGCONT); /* in case they are stopped */
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, true);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (r < 0)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_error("Failed to check session cgroup: %s", strerror(-r));
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt else if (r > 0) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt r = cg_delete(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (r < 0)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt log_error("Failed to delete session cgroup: %s", strerror(-r));
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen }
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen }
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt STRV_FOREACH(k, s->user->manager->controllers)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt cg_trim(*k, s->cgroup_path, true);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt hashmap_remove(s->manager->session_cgroups, s->cgroup_path);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(s->cgroup_path);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->cgroup_path = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int session_unlink_x11_socket(Session *s) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char *t;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int r;
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek assert(s);
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek assert(s->user);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->user->display != s)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->user->display = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt t = strappend(s->user->runtime_path, "/X11-display");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!t)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return log_oom();
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams r = unlink(t);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(t);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r < 0 ? -errno : 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktint session_stop(Session *s) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int r = 0, k;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->started)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_struct(s->type == SESSION_TTY || s->type == SESSION_X11 ? LOG_INFO : LOG_DEBUG,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt MESSAGE_ID(SD_MESSAGE_SESSION_STOP),
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "SESSION_ID=%s", s->id,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "USER_ID=%s", s->user->name,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "LEADER=%lu", (unsigned long) s->leader,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "MESSAGE=Removed session %s.", s->id,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt NULL);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Kill cgroup */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt k = session_terminate_cgroup(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (k < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = k;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Remove X11 symlink */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt session_unlink_x11_socket(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt unlink(s->state_file);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt session_add_to_gc_queue(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt user_add_to_gc_queue(s->user);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->started)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt session_send_signal(s, false);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->started = false;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->seat) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->seat->active == s)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt seat_set_active(s->seat, NULL);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt seat_send_changed(s->seat, "Sessions\0");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt seat_save(s->seat);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt user_send_changed(s->user, "Sessions\0");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt user_save(s->user);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktbool session_is_active(Session *s) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt assert(s);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (!s->seat)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return true;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return s->seat->active == s;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktstatic int get_tty_atime(const char *tty, usec_t *atime) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt _cleanup_free_ char *p = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct stat st;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(tty);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(atime);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!path_is_absolute(tty)) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt p = strappend("/dev/", tty);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!p)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -ENOMEM;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt tty = p;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt } else if (!path_startswith(tty, "/dev/"))
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt return -ENOENT;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (lstat(tty, &st) < 0)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt return -errno;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt *atime = timespec_load(&st.st_atim);
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt return 0;
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt}
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flyktstatic int get_process_ctty_atime(pid_t pid, usec_t *atime) {
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt _cleanup_free_ char *p = NULL;
7bd8e95d44977833d0de3fc4e893eb3bc84351d6Patrik Flykt int r;
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt assert(pid > 0);
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt assert(atime);
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt r = get_ctty(pid, NULL, &p);
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt if (r < 0)
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt return r;
5da1b97f3c3d15521f2dcfbc18eccd6580122ebcPatrik Flykt
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt return get_tty_atime(p, atime);
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt}
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flyktint session_get_idle_hint(Session *s, dual_timestamp *t) {
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt usec_t atime = 0, n;
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt int r;
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt assert(s);
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt /* Explicit idle hint is set */
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt if (s->idle_hint) {
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt if (t)
41e4615d4f4f5c61afa84ba857f23c0ac496687bPatrik Flykt *t = s->idle_hint_timestamp;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
6599680e2d33597f0f11a99e1c3c957b42418568Patrik Flykt return s->idle_hint;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt /* Graphical sessions should really implement a real
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt * idle hint logic */
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt if (s->display)
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt goto dont_know;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* For sessions with an explicitly configured tty, let's check
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * its atime */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->tty) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = get_tty_atime(s->tty, &atime);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r >= 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt goto found_atime;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt /* For sessions with a leader but no explicitly configured
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt * tty, let's check the controlling tty of the leader */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->leader > 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = get_process_ctty_atime(s->leader, &atime);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r >= 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt goto found_atime;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* For other TTY sessions, let's find the most recent atime of
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * the ttys of any of the processes of the session */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (s->cgroup_path) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt _cleanup_fclose_ FILE *f = NULL;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, &f) >= 0) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt pid_t pid;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt atime = 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt while (cg_read_pid(f, &pid) > 0) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt usec_t a;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (get_process_ctty_atime(pid, &a) >= 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (atime == 0 || atime < a)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt atime = a;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (atime != 0)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt goto found_atime;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt }
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt }
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flyktdont_know:
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (t)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt *t = s->idle_hint_timestamp;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
5364f729ba9616cd9fdab8d5413fbc25a1af3a57Lennart Poettering return 0;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktfound_atime:
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (t)
9d89d1ae71cb298218e35a69d6b70e2c94de5271Patrik Flykt dual_timestamp_from_realtime(t, atime);
9d89d1ae71cb298218e35a69d6b70e2c94de5271Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt n = now(CLOCK_REALTIME);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (s->manager->idle_action_usec <= 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return atime + s->manager->idle_action_usec <= n;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktvoid session_set_idle_hint(Session *s, bool b) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (s->idle_hint == b)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->idle_hint = b;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt dual_timestamp_get(&s->idle_hint_timestamp);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt session_send_changed(s,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleHint\0"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleSinceHint\0"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleSinceHintMonotonic\0");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->seat)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt seat_send_changed(s->seat,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleHint\0"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleSinceHint\0"
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt "IdleSinceHintMonotonic\0");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt user_send_changed(s->user,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleHint\0"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleSinceHint\0"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "IdleSinceHintMonotonic\0");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt manager_send_changed(s->manager,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt "IdleHint\0"
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt "IdleSinceHint\0"
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt "IdleSinceHintMonotonic\0");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktint session_create_fifo(Session *s) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt int r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Create FIFO */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!s->fifo_path) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (asprintf(&s->fifo_path, "/run/systemd/sessions/%s.ref", s->id) < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -ENOMEM;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (mkfifo(s->fifo_path, 0600) < 0 && errno != EEXIST)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -errno;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Open reading side */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->fifo_fd < 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct epoll_event ev = {};
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
6ec60d20724d2a32e20d25ef75d2af178c242bc2Ronny Chevalier s->fifo_fd = open(s->fifo_path, O_RDONLY|O_CLOEXEC|O_NDELAY);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->fifo_fd < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -errno;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = hashmap_put(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1), s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt ev.events = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt ev.data.u32 = FD_OTHER_BASE + s->fifo_fd;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_ADD, s->fifo_fd, &ev) < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -errno;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Open writing side */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = open(s->fifo_path, O_WRONLY|O_CLOEXEC|O_NDELAY);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r < 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return -errno;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktvoid session_remove_fifo(Session *s) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->fifo_fd >= 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert_se(hashmap_remove(s->manager->session_fds, INT_TO_PTR(s->fifo_fd + 1)) == s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert_se(epoll_ctl(s->manager->epoll_fd, EPOLL_CTL_DEL, s->fifo_fd, NULL) == 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt close_nointr_nofail(s->fifo_fd);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->fifo_fd = -1;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt session_save(s);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt user_save(s->user);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (s->fifo_path) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt unlink(s->fifo_path);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt free(s->fifo_path);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt s->fifo_path = NULL;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt}
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flyktint session_check_gc(Session *s, bool drop_not_started) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (drop_not_started && !s->started)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return 0;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (s->fifo_fd >= 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt r = pipe_eof(s->fifo_fd);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (r < 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return r;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r == 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 1;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (s->cgroup_path) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, false);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r <= 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 1;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktvoid session_add_to_gc_queue(Session *s) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(s);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (s->in_gc_queue)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt LIST_PREPEND(Session, gc_queue, s->manager->session_gc_queue, s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->in_gc_queue = true;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik FlyktSessionState session_get_state(Session *s) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->fifo_fd < 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return SESSION_CLOSING;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (session_is_active(s))
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return SESSION_ACTIVE;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return SESSION_ONLINE;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flyktint session_kill(Session *s, KillWho who, int signo) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt int r = 0;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt Set *pid_set = NULL;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt assert(s);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (!s->cgroup_path)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return -ESRCH;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (s->leader <= 0 && who == KILL_LEADER)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return -ESRCH;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering if (s->leader > 0)
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering if (kill(s->leader, signo) < 0)
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering r = -errno;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (who == KILL_ALL) {
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt int q;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt pid_set = set_new(trivial_hash_func, trivial_compare_func);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!pid_set)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return -ENOMEM;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen if (s->leader > 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt q = set_put(pid_set, LONG_TO_PTR(s->leader));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (q < 0)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt r = q;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, s->cgroup_path, signo, false, true, false, pid_set);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (q < 0)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = q;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (pid_set)
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt set_free(pid_set);
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic const char* const session_state_table[_SESSION_TYPE_MAX] = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_ONLINE] = "online",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_ACTIVE] = "active",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_CLOSING] = "closing"
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt};
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik FlyktDEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic const char* const session_type_table[_SESSION_TYPE_MAX] = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_TTY] = "tty",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_X11] = "x11",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_UNSPECIFIED] = "unspecified"
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt};
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik FlyktDEFINE_STRING_TABLE_LOOKUP(session_type, SessionType);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic const char* const session_class_table[_SESSION_CLASS_MAX] = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_USER] = "user",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_GREETER] = "greeter",
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen [SESSION_LOCK_SCREEN] = "lock-screen",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [SESSION_BACKGROUND] = "background"
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt};
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik FlyktDEFINE_STRING_TABLE_LOOKUP(session_class, SessionClass);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic const char* const kill_who_table[_KILL_WHO_MAX] = {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [KILL_LEADER] = "leader",
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt [KILL_ALL] = "all"
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt};
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(kill_who, KillWho);
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen