1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/types.h>
24 #include <sys/ioctl.h>
31 #include "cgroup-util.h"
34 #include "bus-error.h"
35 #include "udev-util.h"
38 int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
44 d = hashmap_get(m->devices, sysfs);
49 /* we support adding master-flags, but not removing them */
50 d->master = d->master || master;
55 d = device_new(m, sysfs, master);
65 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
71 s = hashmap_get(m->seats, id);
89 int manager_add_session(Manager *m, const char *id, Session **_session) {
95 s = hashmap_get(m->sessions, id);
103 s = session_new(m, id);
113 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
119 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
127 u = user_new(m, uid, gid, name);
137 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
145 r = get_user_creds(&name, &uid, &gid, NULL, NULL);
149 return manager_add_user(m, uid, gid, name, _user);
152 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
160 return errno ? -errno : -ENOENT;
162 return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
165 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
171 i = hashmap_get(m->inhibitors, id);
179 i = inhibitor_new(m, id);
189 int manager_add_button(Manager *m, const char *name, Button **_button) {
195 b = hashmap_get(m->buttons, name);
203 b = button_new(m, name);
213 int manager_watch_busname(Manager *m, const char *name) {
220 if (set_get(m->busnames, (char*) name))
227 r = set_put(m->busnames, n);
236 void manager_drop_busname(Manager *m, const char *name) {
243 /* keep it if the name still owns a controller */
244 HASHMAP_FOREACH(session, m->sessions, i)
245 if (session_is_controller(session, name))
248 free(set_remove(m->busnames, (char*) name));
251 int manager_process_seat_device(Manager *m, struct udev_device *d) {
257 if (streq_ptr(udev_device_get_action(d), "remove")) {
259 device = hashmap_get(m->devices, udev_device_get_syspath(d));
263 seat_add_to_gc_queue(device->seat);
271 sn = udev_device_get_property_value(d, "ID_SEAT");
275 if (!seat_name_is_valid(sn)) {
276 log_warning("Device with invalid seat name %s found, ignoring.", sn);
280 seat = hashmap_get(m->seats, sn);
281 master = udev_device_has_tag(d, "master-of-seat");
283 /* Ignore non-master devices for unknown seats */
284 if (!master && !seat)
287 r = manager_add_device(m, udev_device_get_syspath(d), master, &device);
292 r = manager_add_seat(m, sn, &seat);
301 device_attach(device, seat);
308 int manager_process_button_device(Manager *m, struct udev_device *d) {
315 if (streq_ptr(udev_device_get_action(d), "remove")) {
317 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
326 r = manager_add_button(m, udev_device_get_sysname(d), &b);
330 sn = udev_device_get_property_value(d, "ID_SEAT");
334 button_set_seat(b, sn);
341 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
342 _cleanup_free_ char *unit = NULL;
352 r = cg_pid_get_unit(pid, &unit);
356 s = hashmap_get(m->session_units, unit);
364 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
365 _cleanup_free_ char *unit = NULL;
375 r = cg_pid_get_slice(pid, &unit);
379 u = hashmap_get(m->user_units, unit);
387 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
390 dual_timestamp ts = { 0, 0 };
395 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0, NULL);
397 HASHMAP_FOREACH(s, m->sessions, i) {
401 ih = session_get_idle_hint(s, &k);
407 if (k.monotonic < ts.monotonic)
413 } else if (idle_hint) {
415 if (k.monotonic > ts.monotonic)
426 bool manager_shall_kill(Manager *m, const char *user) {
430 if (!m->kill_user_processes)
433 if (strv_contains(m->kill_exclude_users, user))
436 if (strv_isempty(m->kill_only_users))
439 return strv_contains(m->kill_only_users, user);
442 static int vt_is_busy(unsigned int vtnr) {
443 struct vt_stat vt_stat;
448 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
449 * we'd open the latter we'd open the foreground tty which
450 * hence would be unconditionally busy. By opening /dev/tty1
451 * we avoid this. Since tty1 is special and needs to be an
452 * explicitly loaded getty or DM this is safe. */
454 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
458 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
461 r = !!(vt_stat.v_state & (1 << vtnr));
463 close_nointr_nofail(fd);
468 int manager_spawn_autovt(Manager *m, unsigned int vtnr) {
469 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
470 _cleanup_free_ char *name = NULL;
476 if (vtnr > m->n_autovts &&
477 vtnr != m->reserve_vt)
480 if (vtnr != m->reserve_vt) {
481 /* If this is the reserved TTY, we'll start the getty
482 * on it in any case, but otherwise only if it is not
485 r = vt_is_busy(vtnr);
492 if (asprintf(&name, "autovt@tty%u.service", vtnr) < 0)
495 r = sd_bus_call_method(
497 "org.freedesktop.systemd1",
498 "/org/freedesktop/systemd1",
499 "org.freedesktop.systemd1.Manager",
505 log_error("Failed to start %s: %s", name, bus_error_message(&error, r));
510 bool manager_is_docked(Manager *m) {
514 HASHMAP_FOREACH(b, m->buttons, i)
521 int manager_count_displays(Manager *m) {
522 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
523 struct udev_list_entry *item = NULL, *first = NULL;
527 e = udev_enumerate_new(m->udev);
531 r = udev_enumerate_add_match_subsystem(e, "drm");
535 r = udev_enumerate_scan_devices(e);
539 first = udev_enumerate_get_list_entry(e);
540 udev_list_entry_foreach(item, first) {
541 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
542 struct udev_device *p;
545 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
549 p = udev_device_get_parent(d);
553 /* If the parent shares the same subsystem as the
554 * device we are looking at then it is a connector,
555 * which is what we are interested in. */
556 if (!streq_ptr(udev_device_get_subsystem(p), "drm"))
559 /* We count any connector which is not explicitly
560 * "disconnected" as connected. */
561 status = udev_device_get_sysattr_value(d, "status");
562 if (!streq_ptr(status, "disconnected"))