logind-core.c revision d3e84ddb885e9d5f0ae9930eb905910e3a81f157
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering/***
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering This file is part of systemd.
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering Copyright 2011 Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering (at your option) any later version.
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering systemd is distributed in the hope that it will be useful, but
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering Lesser General Public License for more details.
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering***/
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek#include <sys/types.h>
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek#include <sys/stat.h>
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek#include <sys/ioctl.h>
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek#include <fcntl.h>
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther#include <pwd.h>
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek#include <unistd.h>
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering#include <linux/vt.h>
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek#include "strv.h"
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek#include "cgroup-util.h"
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek#include "audit.h"
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek#include "bus-util.h"
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek#include "bus-error.h"
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering#include "logind.h"
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmekint manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering Device *d;
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering assert(m);
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering assert(sysfs);
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering d = hashmap_get(m->devices, sysfs);
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering if (d) {
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering if (_device)
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering *_device = d;
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering /* we support adding master-flags, but not removing them */
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering d->master = d->master || master;
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering return 0;
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek }
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek d = device_new(m, sysfs, master);
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek if (!d)
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek return -ENOMEM;
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering if (_device)
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering *_device = d;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering return 0;
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering}
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poetteringint manager_add_seat(Manager *m, const char *id, Seat **_seat) {
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering Seat *s;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering assert(m);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(id);
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek s = hashmap_get(m->seats, id);
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek if (s) {
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering if (_seat)
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering *_seat = s;
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering return 0;
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek }
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek s = seat_new(m, id);
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek if (!s)
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek return -ENOMEM;
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering if (_seat)
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering *_seat = s;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering return 0;
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering}
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poetteringint manager_add_session(Manager *m, const char *id, Session **_session) {
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering Session *s;
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering assert(m);
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering assert(id);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
d7bd3de0654669e65b9642c248c5fa6d1d9a9f61Lennart Poettering s = hashmap_get(m->sessions, id);
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek if (s) {
d4fffc4b8beb86e77fd710c1f43913a490ed083aZbigniew Jędrzejewski-Szmek if (_session)
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering *_session = s;
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering return 0;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering }
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering s = session_new(m, id);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering if (!s)
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek return -ENOMEM;
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering if (_session)
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering *_session = s;
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering return 0;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering}
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poetteringint manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering User *u;
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(m);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(name);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering if (u) {
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering if (_user)
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering *_user = u;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering return 0;
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering }
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering u = user_new(m, uid, gid, name);
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering if (!u)
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering return -ENOMEM;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering if (_user)
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering *_user = u;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering return 0;
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering}
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poettering
374ec6abf31ada6ca554cc8ea99b282373fac010Lennart Poetteringint manager_add_user_by_name(Manager *m, const char *name, User **_user) {
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering uid_t uid;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering gid_t gid;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering int r;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(m);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(name);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering r = get_user_creds(&name, &uid, &gid, NULL, NULL);
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering if (r < 0)
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering return r;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering return manager_add_user(m, uid, gid, name, _user);
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering}
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poetteringint manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering struct passwd *p;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering assert(m);
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering errno = 0;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering p = getpwuid(uid);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (!p)
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering return errno ? -errno : -ENOENT;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering}
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poetteringint manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering Inhibitor *i;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering assert(m);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering assert(id);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering i = hashmap_get(m->inhibitors, id);
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering if (i) {
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering if (_inhibitor)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering *_inhibitor = i;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering return 0;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering }
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
1021b21bc6f8dd522b46116e8598b17f9f93f1b7Lennart Poettering i = inhibitor_new(m, id);
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering if (!i)
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering return -ENOMEM;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering if (_inhibitor)
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering *_inhibitor = i;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering return 0;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering}
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
1021b21bc6f8dd522b46116e8598b17f9f93f1b7Lennart Poetteringint manager_add_button(Manager *m, const char *name, Button **_button) {
1021b21bc6f8dd522b46116e8598b17f9f93f1b7Lennart Poettering Button *b;
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering assert(m);
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering assert(name);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering b = hashmap_get(m->buttons, name);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (b) {
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (_button)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering *_button = b;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering return 0;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering }
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering b = button_new(m, name);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (!b)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering return -ENOMEM;
a0ab566574303be1ca12cdb334f284cfd407caa5Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (_button)
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering *_button = b;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
e13bb5d2b133f9ae51c0a2d20aa51071c780e9aeKay Sievers return 0;
e13bb5d2b133f9ae51c0a2d20aa51071c780e9aeKay Sievers}
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
a0ab566574303be1ca12cdb334f284cfd407caa5Lennart Poetteringint manager_watch_busname(Manager *m, const char *name) {
a0ab566574303be1ca12cdb334f284cfd407caa5Lennart Poettering char *n;
a0ab566574303be1ca12cdb334f284cfd407caa5Lennart Poettering int r;
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering assert(m);
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering assert(name);
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering if (set_get(m->busnames, (char*) name))
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering return 0;
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering n = strdup(name);
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering if (!n)
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering return -ENOMEM;
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering r = set_put(m->busnames, n);
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering if (r < 0) {
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering free(n);
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering return r;
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering }
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering return 0;
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering}
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poetteringvoid manager_drop_busname(Manager *m, const char *name) {
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering Session *session;
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering Iterator i;
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering assert(m);
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering assert(name);
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering /* keep it if the name still owns a controller */
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering HASHMAP_FOREACH(session, m->sessions, i)
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering if (session_is_controller(session, name))
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering return;
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering free(set_remove(m->busnames, (char*) name));
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering}
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek
7027ff61a34a12487712b382a061c654acc3a679Lennart Poetteringint manager_process_seat_device(Manager *m, struct udev_device *d) {
6c03089c32c251d823173bda4d809a9e643219f0Lennart Poettering Device *device;
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering int r;
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering assert(m);
9444b1f20e311f073864d81e913bd4f32fe95cfdLennart Poettering
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther if (streq_ptr(udev_device_get_action(d), "remove")) {
aff38e74bd776471f15ba54b305a24b0251eb865Lennart Poettering
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther device = hashmap_get(m->devices, udev_device_get_syspath(d));
78edb35ab4f4227485cb9ec816b43c37e0d5e62aLennart Poettering if (!device)
a016b9228f338cb9b380ce7e00826ef462767d98Lennart Poettering return 0;
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek seat_add_to_gc_queue(device->seat);
96cde13ace6406582688028f3df5668a172ba628Zbigniew Jędrzejewski-Szmek device_free(device);
} else {
const char *sn;
Seat *seat = NULL;
bool master;
sn = udev_device_get_property_value(d, "ID_SEAT");
if (isempty(sn))
sn = "seat0";
if (!seat_name_is_valid(sn)) {
log_warning("Device with invalid seat name %s found, ignoring.", sn);
return 0;
}
/* ignore non-master devices for unknown seats */
master = udev_device_has_tag(d, "master-of-seat");
if (!master && !(seat = hashmap_get(m->seats, sn)))
return 0;
r = manager_add_device(m, udev_device_get_syspath(d), master, &device);
if (r < 0)
return r;
if (!seat) {
r = manager_add_seat(m, sn, &seat);
if (r < 0) {
if (!device->seat)
device_free(device);
return r;
}
}
device_attach(device, seat);
seat_start(seat);
}
return 0;
}
int manager_process_button_device(Manager *m, struct udev_device *d) {
Button *b;
int r;
assert(m);
if (streq_ptr(udev_device_get_action(d), "remove")) {
b = hashmap_get(m->buttons, udev_device_get_sysname(d));
if (!b)
return 0;
button_free(b);
} else {
const char *sn;
r = manager_add_button(m, udev_device_get_sysname(d), &b);
if (r < 0)
return r;
sn = udev_device_get_property_value(d, "ID_SEAT");
if (isempty(sn))
sn = "seat0";
button_set_seat(b, sn);
button_open(b);
}
return 0;
}
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
_cleanup_free_ char *unit = NULL;
Session *s;
int r;
assert(m);
assert(session);
if (pid < 1)
return -EINVAL;
r = cg_pid_get_unit(pid, &unit);
if (r < 0)
return 0;
s = hashmap_get(m->session_units, unit);
if (!s)
return 0;
*session = s;
return 1;
}
int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
_cleanup_free_ char *unit = NULL;
User *u;
int r;
assert(m);
assert(user);
if (pid < 1)
return -EINVAL;
r = cg_pid_get_slice(pid, &unit);
if (r < 0)
return 0;
u = hashmap_get(m->user_units, unit);
if (!u)
return 0;
*user = u;
return 1;
}
int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
Session *s;
bool idle_hint;
dual_timestamp ts = { 0, 0 };
Iterator i;
assert(m);
idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
HASHMAP_FOREACH(s, m->sessions, i) {
dual_timestamp k;
int ih;
ih = session_get_idle_hint(s, &k);
if (ih < 0)
return ih;
if (!ih) {
if (!idle_hint) {
if (k.monotonic < ts.monotonic)
ts = k;
} else {
idle_hint = false;
ts = k;
}
} else if (idle_hint) {
if (k.monotonic > ts.monotonic)
ts = k;
}
}
if (t)
*t = ts;
return idle_hint;
}
bool manager_shall_kill(Manager *m, const char *user) {
assert(m);
assert(user);
if (!m->kill_user_processes)
return false;
if (strv_contains(m->kill_exclude_users, user))
return false;
if (strv_isempty(m->kill_only_users))
return true;
return strv_contains(m->kill_only_users, user);
}
static int vt_is_busy(int vtnr) {
struct vt_stat vt_stat;
int r = 0, fd;
assert(vtnr >= 1);
/* We explicitly open /dev/tty1 here instead of /dev/tty0. If
* we'd open the latter we'd open the foreground tty which
* hence would be unconditionally busy. By opening /dev/tty1
* we avoid this. Since tty1 is special and needs to be an
* explicitly loaded getty or DM this is safe. */
fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
if (fd < 0)
return -errno;
if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
r = -errno;
else
r = !!(vt_stat.v_state & (1 << vtnr));
close_nointr_nofail(fd);
return r;
}
int manager_spawn_autovt(Manager *m, int vtnr) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *name = NULL;
int r;
assert(m);
assert(vtnr >= 1);
if ((unsigned) vtnr > m->n_autovts &&
(unsigned) vtnr != m->reserve_vt)
return 0;
if ((unsigned) vtnr != m->reserve_vt) {
/* If this is the reserved TTY, we'll start the getty
* on it in any case, but otherwise only if it is not
* busy. */
r = vt_is_busy(vtnr);
if (r < 0)
return r;
else if (r > 0)
return -EBUSY;
}
if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0)
return log_oom();
r = sd_bus_call_method(
m->bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartUnit",
&error,
NULL,
"ss", name, "fail");
if (r < 0)
log_error("Failed to start %s: %s", name, bus_error_message(&error, r));
return r;
}