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/>.
28 #include <sys/epoll.h>
29 #include <sys/ioctl.h>
31 #include <sys/timerfd.h>
33 #include <systemd/sd-daemon.h>
36 #include "dbus-common.h"
37 #include "dbus-loop.h"
39 #include "conf-parser.h"
42 Manager *manager_new(void) {
49 m->console_active_fd = -1;
53 m->udev_button_fd = -1;
55 m->reserve_vt_fd = -1;
59 m->inhibit_delay_max = 5 * USEC_PER_SEC;
60 m->handle_power_key = HANDLE_POWEROFF;
61 m->handle_suspend_key = HANDLE_SUSPEND;
62 m->handle_hibernate_key = HANDLE_HIBERNATE;
63 m->handle_lid_switch = HANDLE_SUSPEND;
64 m->lid_switch_ignore_inhibited = true;
66 m->idle_action_fd = -1;
67 m->idle_action_usec = 30 * USEC_PER_MINUTE;
68 m->idle_action = HANDLE_IGNORE;
69 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
71 m->devices = hashmap_new(string_hash_func, string_compare_func);
72 m->seats = hashmap_new(string_hash_func, string_compare_func);
73 m->sessions = hashmap_new(string_hash_func, string_compare_func);
74 m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
75 m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
76 m->buttons = hashmap_new(string_hash_func, string_compare_func);
78 m->user_units = hashmap_new(string_hash_func, string_compare_func);
79 m->session_units = hashmap_new(string_hash_func, string_compare_func);
81 m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
82 m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
83 m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
85 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
86 !m->user_units || !m->session_units ||
87 !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
92 m->kill_exclude_users = strv_new("root", NULL);
93 if (!m->kill_exclude_users) {
107 void manager_free(Manager *m) {
117 while ((session = hashmap_first(m->sessions)))
118 session_free(session);
120 while ((u = hashmap_first(m->users)))
123 while ((d = hashmap_first(m->devices)))
126 while ((s = hashmap_first(m->seats)))
129 while ((i = hashmap_first(m->inhibitors)))
132 while ((b = hashmap_first(m->buttons)))
135 hashmap_free(m->devices);
136 hashmap_free(m->seats);
137 hashmap_free(m->sessions);
138 hashmap_free(m->users);
139 hashmap_free(m->inhibitors);
140 hashmap_free(m->buttons);
142 hashmap_free(m->user_units);
143 hashmap_free(m->session_units);
145 hashmap_free(m->session_fds);
146 hashmap_free(m->inhibitor_fds);
147 hashmap_free(m->button_fds);
149 if (m->console_active_fd >= 0)
150 close_nointr_nofail(m->console_active_fd);
152 if (m->udev_seat_monitor)
153 udev_monitor_unref(m->udev_seat_monitor);
154 if (m->udev_device_monitor)
155 udev_monitor_unref(m->udev_device_monitor);
156 if (m->udev_vcsa_monitor)
157 udev_monitor_unref(m->udev_vcsa_monitor);
158 if (m->udev_button_monitor)
159 udev_monitor_unref(m->udev_button_monitor);
165 dbus_connection_flush(m->bus);
166 dbus_connection_close(m->bus);
167 dbus_connection_unref(m->bus);
171 close_nointr_nofail(m->bus_fd);
173 if (m->epoll_fd >= 0)
174 close_nointr_nofail(m->epoll_fd);
176 if (m->reserve_vt_fd >= 0)
177 close_nointr_nofail(m->reserve_vt_fd);
179 if (m->idle_action_fd >= 0)
180 close_nointr_nofail(m->idle_action_fd);
182 strv_free(m->kill_only_users);
183 strv_free(m->kill_exclude_users);
189 int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
195 d = hashmap_get(m->devices, sysfs);
200 /* we support adding master-flags, but not removing them */
201 d->master = d->master || master;
206 d = device_new(m, sysfs, master);
216 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
222 s = hashmap_get(m->seats, id);
240 int manager_add_session(Manager *m, const char *id, Session **_session) {
246 s = hashmap_get(m->sessions, id);
254 s = session_new(m, id);
264 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
270 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
278 u = user_new(m, uid, gid, name);
288 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
296 r = get_user_creds(&name, &uid, &gid, NULL, NULL);
300 return manager_add_user(m, uid, gid, name, _user);
303 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
311 return errno ? -errno : -ENOENT;
313 return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
316 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
322 i = hashmap_get(m->inhibitors, id);
330 i = inhibitor_new(m, id);
340 int manager_add_button(Manager *m, const char *name, Button **_button) {
346 b = hashmap_get(m->buttons, name);
354 b = button_new(m, name);
364 int manager_process_seat_device(Manager *m, struct udev_device *d) {
370 if (streq_ptr(udev_device_get_action(d), "remove")) {
372 device = hashmap_get(m->devices, udev_device_get_syspath(d));
376 seat_add_to_gc_queue(device->seat);
384 sn = udev_device_get_property_value(d, "ID_SEAT");
388 if (!seat_name_is_valid(sn)) {
389 log_warning("Device with invalid seat name %s found, ignoring.", sn);
393 /* ignore non-master devices for unknown seats */
394 master = udev_device_has_tag(d, "master-of-seat");
395 if (!master && !(seat = hashmap_get(m->seats, sn)))
398 r = manager_add_device(m, udev_device_get_syspath(d), master, &device);
403 r = manager_add_seat(m, sn, &seat);
412 device_attach(device, seat);
419 int manager_process_button_device(Manager *m, struct udev_device *d) {
426 if (streq_ptr(udev_device_get_action(d), "remove")) {
428 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
437 r = manager_add_button(m, udev_device_get_sysname(d), &b);
441 sn = udev_device_get_property_value(d, "ID_SEAT");
445 button_set_seat(b, sn);
452 int manager_enumerate_devices(Manager *m) {
453 struct udev_list_entry *item = NULL, *first = NULL;
454 struct udev_enumerate *e;
459 /* Loads devices from udev and creates seats for them as
462 e = udev_enumerate_new(m->udev);
468 r = udev_enumerate_add_match_tag(e, "master-of-seat");
472 r = udev_enumerate_scan_devices(e);
476 first = udev_enumerate_get_list_entry(e);
477 udev_list_entry_foreach(item, first) {
478 struct udev_device *d;
481 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
487 k = manager_process_seat_device(m, d);
488 udev_device_unref(d);
496 udev_enumerate_unref(e);
501 int manager_enumerate_buttons(Manager *m) {
502 struct udev_list_entry *item = NULL, *first = NULL;
503 struct udev_enumerate *e;
508 /* Loads buttons from udev */
510 if (m->handle_power_key == HANDLE_IGNORE &&
511 m->handle_suspend_key == HANDLE_IGNORE &&
512 m->handle_hibernate_key == HANDLE_IGNORE &&
513 m->handle_lid_switch == HANDLE_IGNORE)
516 e = udev_enumerate_new(m->udev);
522 r = udev_enumerate_add_match_subsystem(e, "input");
526 r = udev_enumerate_add_match_tag(e, "power-switch");
530 r = udev_enumerate_scan_devices(e);
534 first = udev_enumerate_get_list_entry(e);
535 udev_list_entry_foreach(item, first) {
536 struct udev_device *d;
539 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
545 k = manager_process_button_device(m, d);
546 udev_device_unref(d);
554 udev_enumerate_unref(e);
559 int manager_enumerate_seats(Manager *m) {
560 _cleanup_closedir_ DIR *d = NULL;
566 /* This loads data about seats stored on disk, but does not
567 * actually create any seats. Removes data of seats that no
570 d = opendir("/run/systemd/seats");
575 log_error("Failed to open /run/systemd/seats: %m");
579 FOREACH_DIRENT(de, d, return -errno) {
583 if (!dirent_is_file(de))
586 s = hashmap_get(m->seats, de->d_name);
588 unlinkat(dirfd(d), de->d_name, 0);
600 static int manager_enumerate_linger_users(Manager *m) {
601 _cleanup_closedir_ DIR *d = NULL;
607 d = opendir("/var/lib/systemd/linger");
612 log_error("Failed to open /var/lib/systemd/linger/: %m");
616 FOREACH_DIRENT(de, d, return -errno) {
619 if (!dirent_is_file(de))
622 k = manager_add_user_by_name(m, de->d_name, NULL);
624 log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
632 int manager_enumerate_users(Manager *m) {
633 _cleanup_closedir_ DIR *d = NULL;
639 /* Add lingering users */
640 r = manager_enumerate_linger_users(m);
642 /* Read in user data stored on disk */
643 d = opendir("/run/systemd/users");
648 log_error("Failed to open /run/systemd/users: %m");
652 FOREACH_DIRENT(de, d, return -errno) {
655 if (!dirent_is_file(de))
658 k = manager_add_user_by_name(m, de->d_name, &u);
660 log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
666 user_add_to_gc_queue(u);
676 int manager_enumerate_sessions(Manager *m) {
677 _cleanup_closedir_ DIR *d = NULL;
683 /* Read in session data stored on disk */
684 d = opendir("/run/systemd/sessions");
689 log_error("Failed to open /run/systemd/sessions: %m");
693 FOREACH_DIRENT(de, d, return -errno) {
697 if (!dirent_is_file(de))
700 if (!session_id_valid(de->d_name)) {
701 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
706 k = manager_add_session(m, de->d_name, &s);
708 log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
714 session_add_to_gc_queue(s);
724 int manager_enumerate_inhibitors(Manager *m) {
725 _cleanup_closedir_ DIR *d = NULL;
731 d = opendir("/run/systemd/inhibit");
736 log_error("Failed to open /run/systemd/inhibit: %m");
740 FOREACH_DIRENT(de, d, return -errno) {
744 if (!dirent_is_file(de))
747 k = manager_add_inhibitor(m, de->d_name, &i);
749 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
754 k = inhibitor_load(i);
762 int manager_dispatch_seat_udev(Manager *m) {
763 struct udev_device *d;
768 d = udev_monitor_receive_device(m->udev_seat_monitor);
772 r = manager_process_seat_device(m, d);
773 udev_device_unref(d);
778 static int manager_dispatch_device_udev(Manager *m) {
779 struct udev_device *d;
784 d = udev_monitor_receive_device(m->udev_device_monitor);
788 r = manager_process_seat_device(m, d);
789 udev_device_unref(d);
794 int manager_dispatch_vcsa_udev(Manager *m) {
795 struct udev_device *d;
801 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
805 name = udev_device_get_sysname(d);
807 /* Whenever a VCSA device is removed try to reallocate our
808 * VTs, to make sure our auto VTs never go away. */
810 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
811 r = seat_preallocate_vts(m->vtconsole);
813 udev_device_unref(d);
818 int manager_dispatch_button_udev(Manager *m) {
819 struct udev_device *d;
824 d = udev_monitor_receive_device(m->udev_button_monitor);
828 r = manager_process_button_device(m, d);
829 udev_device_unref(d);
834 int manager_dispatch_console(Manager *m) {
838 seat_read_active_vt(m->vtconsole);
843 static int vt_is_busy(int vtnr) {
844 struct vt_stat vt_stat;
849 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
850 * we'd open the latter we'd open the foreground tty which
851 * hence would be unconditionally busy. By opening /dev/tty1
852 * we avoid this. Since tty1 is special and needs to be an
853 * explicitly loaded getty or DM this is safe. */
855 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
859 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
862 r = !!(vt_stat.v_state & (1 << vtnr));
864 close_nointr_nofail(fd);
869 int manager_spawn_autovt(Manager *m, int vtnr) {
872 const char *mode = "fail";
877 if ((unsigned) vtnr > m->n_autovts &&
878 (unsigned) vtnr != m->reserve_vt)
881 if ((unsigned) vtnr != m->reserve_vt) {
882 /* If this is the reserved TTY, we'll start the getty
883 * on it in any case, but otherwise only if it is not
886 r = vt_is_busy(vtnr);
893 if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
894 log_error("Could not allocate service name.");
899 r = bus_method_call_with_reply (
901 "org.freedesktop.systemd1",
902 "/org/freedesktop/systemd1",
903 "org.freedesktop.systemd1.Manager",
907 DBUS_TYPE_STRING, &name,
908 DBUS_TYPE_STRING, &mode,
917 static int manager_reserve_vt(Manager *m) {
918 _cleanup_free_ char *p = NULL;
922 if (m->reserve_vt <= 0)
925 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
928 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
929 if (m->reserve_vt_fd < 0) {
931 /* Don't complain on VT-less systems */
933 log_warning("Failed to pin reserved VT: %m");
940 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
941 _cleanup_free_ char *unit = NULL;
949 r = cg_pid_get_unit(pid, &unit);
953 s = hashmap_get(m->session_units, unit);
961 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
962 _cleanup_free_ char *unit = NULL;
970 r = cg_pid_get_slice(pid, &unit);
974 u = hashmap_get(m->user_units, unit);
982 static void manager_dispatch_other(Manager *m, int fd) {
990 s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
992 assert(s->fifo_fd == fd);
993 session_remove_fifo(s);
998 i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1000 assert(i->fifo_fd == fd);
1006 b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1008 assert(b->fd == fd);
1013 assert_not_reached("Got event for unknown fd");
1016 static int manager_connect_bus(Manager *m) {
1019 struct epoll_event ev = {
1026 assert(m->bus_fd < 0);
1028 dbus_error_init(&error);
1030 m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1032 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1037 if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1038 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1039 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1040 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1041 !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1046 dbus_bus_add_match(m->bus,
1048 "sender='org.freedesktop.systemd1',"
1049 "interface='org.freedesktop.systemd1.Manager',"
1050 "member='JobRemoved',"
1051 "path='/org/freedesktop/systemd1'",
1053 if (dbus_error_is_set(&error)) {
1054 log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
1055 dbus_error_free(&error);
1058 dbus_bus_add_match(m->bus,
1060 "sender='org.freedesktop.systemd1',"
1061 "interface='org.freedesktop.systemd1.Manager',"
1062 "member='UnitRemoved',"
1063 "path='/org/freedesktop/systemd1'",
1065 if (dbus_error_is_set(&error)) {
1066 log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
1067 dbus_error_free(&error);
1070 dbus_bus_add_match(m->bus,
1072 "sender='org.freedesktop.systemd1',"
1073 "interface='org.freedesktop.DBus.Properties',"
1074 "member='PropertiesChanged'",
1076 if (dbus_error_is_set(&error)) {
1077 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1078 dbus_error_free(&error);
1081 dbus_bus_add_match(m->bus,
1083 "sender='org.freedesktop.systemd1',"
1084 "interface='org.freedesktop.systemd1.Manager',"
1085 "member='Reloading',"
1086 "path='/org/freedesktop/systemd1'",
1088 if (dbus_error_is_set(&error)) {
1089 log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
1090 dbus_error_free(&error);
1093 r = bus_method_call_with_reply(
1095 "org.freedesktop.systemd1",
1096 "/org/freedesktop/systemd1",
1097 "org.freedesktop.systemd1.Manager",
1103 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1104 dbus_error_free(&error);
1107 r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1108 if (dbus_error_is_set(&error)) {
1109 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1114 if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1115 log_error("Failed to acquire name.");
1120 m->bus_fd = bus_loop_open(m->bus);
1121 if (m->bus_fd < 0) {
1126 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1132 dbus_error_free(&error);
1137 static int manager_connect_console(Manager *m) {
1138 struct epoll_event ev = {
1140 .data.u32 = FD_CONSOLE,
1144 assert(m->console_active_fd < 0);
1146 /* On certain architectures (S390 and Xen, and containers),
1147 /dev/tty0 does not exist, so don't fail if we can't open
1149 if (access("/dev/tty0", F_OK) < 0) {
1150 m->console_active_fd = -1;
1154 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1155 if (m->console_active_fd < 0) {
1157 /* On some systems the device node /dev/tty0 may exist
1158 * even though /sys/class/tty/tty0 does not. */
1159 if (errno == ENOENT)
1162 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1166 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1172 static int manager_connect_udev(Manager *m) {
1174 struct epoll_event ev = {
1176 .data.u32 = FD_SEAT_UDEV,
1180 assert(!m->udev_seat_monitor);
1181 assert(!m->udev_device_monitor);
1182 assert(!m->udev_vcsa_monitor);
1183 assert(!m->udev_button_monitor);
1185 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1186 if (!m->udev_seat_monitor)
1189 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1193 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1197 m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1199 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1202 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1203 if (!m->udev_device_monitor)
1206 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
1210 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
1214 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
1218 r = udev_monitor_enable_receiving(m->udev_device_monitor);
1222 m->udev_device_fd = udev_monitor_get_fd(m->udev_device_monitor);
1224 ev.events = EPOLLIN;
1225 ev.data.u32 = FD_DEVICE_UDEV;
1226 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_device_fd, &ev) < 0)
1229 /* Don't watch keys if nobody cares */
1230 if (m->handle_power_key != HANDLE_IGNORE ||
1231 m->handle_suspend_key != HANDLE_IGNORE ||
1232 m->handle_hibernate_key != HANDLE_IGNORE ||
1233 m->handle_lid_switch != HANDLE_IGNORE) {
1235 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1236 if (!m->udev_button_monitor)
1239 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1243 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1247 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1251 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1254 ev.events = EPOLLIN;
1255 ev.data.u32 = FD_BUTTON_UDEV;
1256 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1260 /* Don't bother watching VCSA devices, if nobody cares */
1261 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1263 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1264 if (!m->udev_vcsa_monitor)
1267 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1271 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1275 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1278 ev.events = EPOLLIN;
1279 ev.data.u32 = FD_VCSA_UDEV;
1280 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1287 void manager_gc(Manager *m, bool drop_not_started) {
1294 while ((seat = m->seat_gc_queue)) {
1295 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1296 seat->in_gc_queue = false;
1298 if (seat_check_gc(seat, drop_not_started) == 0) {
1304 while ((session = m->session_gc_queue)) {
1305 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1306 session->in_gc_queue = false;
1308 if (session_check_gc(session, drop_not_started) == 0) {
1309 session_stop(session);
1310 session_finalize(session);
1311 session_free(session);
1315 while ((user = m->user_gc_queue)) {
1316 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1317 user->in_gc_queue = false;
1319 if (user_check_gc(user, drop_not_started) == 0) {
1321 user_finalize(user);
1327 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1330 dual_timestamp ts = { 0, 0 };
1335 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1337 HASHMAP_FOREACH(s, m->sessions, i) {
1341 ih = session_get_idle_hint(s, &k);
1347 if (k.monotonic < ts.monotonic)
1353 } else if (idle_hint) {
1355 if (k.monotonic > ts.monotonic)
1366 bool manager_shall_kill(Manager *m, const char *user) {
1370 if (!m->kill_user_processes)
1373 if (strv_contains(m->kill_exclude_users, user))
1376 if (strv_isempty(m->kill_only_users))
1379 return strv_contains(m->kill_only_users, user);
1382 int manager_dispatch_idle_action(Manager *m) {
1383 struct dual_timestamp since;
1384 struct itimerspec its = {};
1390 if (m->idle_action == HANDLE_IGNORE ||
1391 m->idle_action_usec <= 0) {
1396 n = now(CLOCK_MONOTONIC);
1398 r = manager_get_idle_hint(m, &since);
1400 /* Not idle. Let's check if after a timeout it might be idle then. */
1401 timespec_store(&its.it_value, n + m->idle_action_usec);
1403 /* Idle! Let's see if it's time to do something, or if
1404 * we shall sleep for longer. */
1406 if (n >= since.monotonic + m->idle_action_usec &&
1407 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1408 log_info("System idle. Taking action.");
1410 manager_handle_action(m, 0, m->idle_action, false, false);
1411 m->idle_action_not_before_usec = n;
1414 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1417 if (m->idle_action_fd < 0) {
1418 struct epoll_event ev = {
1420 .data.u32 = FD_IDLE_ACTION,
1423 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1424 if (m->idle_action_fd < 0) {
1425 log_error("Failed to create idle action timer: %m");
1430 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1431 log_error("Failed to add idle action timer to epoll: %m");
1437 if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1438 log_error("Failed to reset timerfd: %m");
1446 if (m->idle_action_fd >= 0) {
1447 close_nointr_nofail(m->idle_action_fd);
1448 m->idle_action_fd = -1;
1453 int manager_startup(Manager *m) {
1458 Inhibitor *inhibitor;
1462 assert(m->epoll_fd <= 0);
1464 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1465 if (m->epoll_fd < 0)
1468 /* Connect to console */
1469 r = manager_connect_console(m);
1473 /* Connect to udev */
1474 r = manager_connect_udev(m);
1478 /* Connect to the bus */
1479 r = manager_connect_bus(m);
1483 /* Instantiate magic seat 0 */
1484 r = manager_add_seat(m, "seat0", &m->vtconsole);
1488 /* Deserialize state */
1489 r = manager_enumerate_devices(m);
1491 log_warning("Device enumeration failed: %s", strerror(-r));
1493 r = manager_enumerate_seats(m);
1495 log_warning("Seat enumeration failed: %s", strerror(-r));
1497 r = manager_enumerate_users(m);
1499 log_warning("User enumeration failed: %s", strerror(-r));
1501 r = manager_enumerate_sessions(m);
1503 log_warning("Session enumeration failed: %s", strerror(-r));
1505 r = manager_enumerate_inhibitors(m);
1507 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1509 r = manager_enumerate_buttons(m);
1511 log_warning("Button enumeration failed: %s", strerror(-r));
1513 /* Remove stale objects before we start them */
1514 manager_gc(m, false);
1516 /* Reserve the special reserved VT */
1517 manager_reserve_vt(m);
1519 /* And start everything */
1520 HASHMAP_FOREACH(seat, m->seats, i)
1523 HASHMAP_FOREACH(user, m->users, i)
1526 HASHMAP_FOREACH(session, m->sessions, i)
1527 session_start(session);
1529 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1530 inhibitor_start(inhibitor);
1532 manager_dispatch_idle_action(m);
1537 static int manager_recheck_buttons(Manager *m) {
1544 HASHMAP_FOREACH(b, m->buttons, i) {
1547 q = button_recheck(b);
1557 int manager_run(Manager *m) {
1561 struct epoll_event event;
1565 manager_gc(m, true);
1567 if (manager_dispatch_delayed(m) > 0)
1570 if (manager_recheck_buttons(m) > 0)
1573 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1576 manager_gc(m, true);
1578 if (m->action_what != 0 && !m->action_job) {
1581 x = now(CLOCK_MONOTONIC);
1582 y = m->action_timestamp + m->inhibit_delay_max;
1584 msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1587 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1589 if (errno == EINTR || errno == EAGAIN)
1592 log_error("epoll() failed: %m");
1599 switch (event.data.u32) {
1602 manager_dispatch_seat_udev(m);
1605 case FD_DEVICE_UDEV:
1606 manager_dispatch_device_udev(m);
1610 manager_dispatch_vcsa_udev(m);
1613 case FD_BUTTON_UDEV:
1614 manager_dispatch_button_udev(m);
1618 manager_dispatch_console(m);
1621 case FD_IDLE_ACTION:
1622 manager_dispatch_idle_action(m);
1626 bus_loop_dispatch(m->bus_fd);
1630 if (event.data.u32 >= FD_OTHER_BASE)
1631 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1638 static int manager_parse_config_file(Manager *m) {
1639 static const char fn[] = "/etc/systemd/logind.conf";
1640 _cleanup_fclose_ FILE *f = NULL;
1645 f = fopen(fn, "re");
1647 if (errno == ENOENT)
1650 log_warning("Failed to open configuration file %s: %m", fn);
1654 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1655 (void*) logind_gperf_lookup, false, false, m);
1657 log_warning("Failed to parse configuration file: %s", strerror(-r));
1662 int main(int argc, char *argv[]) {
1666 log_set_target(LOG_TARGET_AUTO);
1667 log_set_facility(LOG_AUTH);
1668 log_parse_environment();
1674 log_error("This program takes no arguments.");
1679 /* Always create the directories people can create inotify
1680 * watches in. Note that some applications might check for the
1681 * existence of /run/systemd/seats/ to determine whether
1682 * logind is available, so please always make sure this check
1684 mkdir_label("/run/systemd/seats", 0755);
1685 mkdir_label("/run/systemd/users", 0755);
1686 mkdir_label("/run/systemd/sessions", 0755);
1694 manager_parse_config_file(m);
1696 r = manager_startup(m);
1698 log_error("Failed to fully start up daemon: %s", strerror(-r));
1702 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1706 "STATUS=Processing requests...");
1710 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1714 "STATUS=Shutting down...");
1719 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;