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_cgroups = hashmap_new(string_hash_func, string_compare_func);
79 m->session_cgroups = 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_cgroups || !m->session_cgroups ||
87 !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
92 m->reset_controllers = strv_new("cpu", NULL);
93 m->kill_exclude_users = strv_new("root", NULL);
94 if (!m->reset_controllers || !m->kill_exclude_users) {
105 if (cg_get_user_path(&m->cgroup_path) < 0) {
113 void manager_free(Manager *m) {
123 while ((session = hashmap_first(m->sessions)))
124 session_free(session);
126 while ((u = hashmap_first(m->users)))
129 while ((d = hashmap_first(m->devices)))
132 while ((s = hashmap_first(m->seats)))
135 while ((i = hashmap_first(m->inhibitors)))
138 while ((b = hashmap_first(m->buttons)))
141 hashmap_free(m->devices);
142 hashmap_free(m->seats);
143 hashmap_free(m->sessions);
144 hashmap_free(m->users);
145 hashmap_free(m->inhibitors);
146 hashmap_free(m->buttons);
148 hashmap_free(m->user_cgroups);
149 hashmap_free(m->session_cgroups);
151 hashmap_free(m->session_fds);
152 hashmap_free(m->inhibitor_fds);
153 hashmap_free(m->button_fds);
155 if (m->console_active_fd >= 0)
156 close_nointr_nofail(m->console_active_fd);
158 if (m->udev_seat_monitor)
159 udev_monitor_unref(m->udev_seat_monitor);
160 if (m->udev_vcsa_monitor)
161 udev_monitor_unref(m->udev_vcsa_monitor);
162 if (m->udev_button_monitor)
163 udev_monitor_unref(m->udev_button_monitor);
169 dbus_connection_flush(m->bus);
170 dbus_connection_close(m->bus);
171 dbus_connection_unref(m->bus);
175 close_nointr_nofail(m->bus_fd);
177 if (m->epoll_fd >= 0)
178 close_nointr_nofail(m->epoll_fd);
180 if (m->reserve_vt_fd >= 0)
181 close_nointr_nofail(m->reserve_vt_fd);
183 if (m->idle_action_fd >= 0)
184 close_nointr_nofail(m->idle_action_fd);
186 strv_free(m->controllers);
187 strv_free(m->reset_controllers);
188 strv_free(m->kill_only_users);
189 strv_free(m->kill_exclude_users);
193 free(m->cgroup_path);
197 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
203 d = hashmap_get(m->devices, sysfs);
211 d = device_new(m, sysfs);
221 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
227 s = hashmap_get(m->seats, id);
245 int manager_add_session(Manager *m, User *u, const char *id, Session **_session) {
251 s = hashmap_get(m->sessions, id);
259 s = session_new(m, u, id);
269 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
275 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
283 u = user_new(m, uid, gid, name);
293 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
301 r = get_user_creds(&name, &uid, &gid, NULL, NULL);
305 return manager_add_user(m, uid, gid, name, _user);
308 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
316 return errno ? -errno : -ENOENT;
318 return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
321 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
327 i = hashmap_get(m->inhibitors, id);
335 i = inhibitor_new(m, id);
345 int manager_add_button(Manager *m, const char *name, Button **_button) {
351 b = hashmap_get(m->buttons, name);
359 b = button_new(m, name);
369 int manager_process_seat_device(Manager *m, struct udev_device *d) {
375 if (streq_ptr(udev_device_get_action(d), "remove")) {
377 device = hashmap_get(m->devices, udev_device_get_syspath(d));
381 seat_add_to_gc_queue(device->seat);
388 sn = udev_device_get_property_value(d, "ID_SEAT");
392 if (!seat_name_is_valid(sn)) {
393 log_warning("Device with invalid seat name %s found, ignoring.", sn);
397 r = manager_add_device(m, udev_device_get_syspath(d), &device);
401 r = manager_add_seat(m, sn, &seat);
409 device_attach(device, seat);
416 int manager_process_button_device(Manager *m, struct udev_device *d) {
423 if (streq_ptr(udev_device_get_action(d), "remove")) {
425 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
434 r = manager_add_button(m, udev_device_get_sysname(d), &b);
438 sn = udev_device_get_property_value(d, "ID_SEAT");
442 button_set_seat(b, sn);
449 int manager_enumerate_devices(Manager *m) {
450 struct udev_list_entry *item = NULL, *first = NULL;
451 struct udev_enumerate *e;
456 /* Loads devices from udev and creates seats for them as
459 e = udev_enumerate_new(m->udev);
465 r = udev_enumerate_add_match_tag(e, "master-of-seat");
469 r = udev_enumerate_scan_devices(e);
473 first = udev_enumerate_get_list_entry(e);
474 udev_list_entry_foreach(item, first) {
475 struct udev_device *d;
478 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
484 k = manager_process_seat_device(m, d);
485 udev_device_unref(d);
493 udev_enumerate_unref(e);
498 int manager_enumerate_buttons(Manager *m) {
499 struct udev_list_entry *item = NULL, *first = NULL;
500 struct udev_enumerate *e;
505 /* Loads buttons from udev */
507 if (m->handle_power_key == HANDLE_IGNORE &&
508 m->handle_suspend_key == HANDLE_IGNORE &&
509 m->handle_hibernate_key == HANDLE_IGNORE &&
510 m->handle_lid_switch == HANDLE_IGNORE)
513 e = udev_enumerate_new(m->udev);
519 r = udev_enumerate_add_match_subsystem(e, "input");
523 r = udev_enumerate_add_match_tag(e, "power-switch");
527 r = udev_enumerate_scan_devices(e);
531 first = udev_enumerate_get_list_entry(e);
532 udev_list_entry_foreach(item, first) {
533 struct udev_device *d;
536 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
542 k = manager_process_button_device(m, d);
543 udev_device_unref(d);
551 udev_enumerate_unref(e);
556 int manager_enumerate_seats(Manager *m) {
563 /* This loads data about seats stored on disk, but does not
564 * actually create any seats. Removes data of seats that no
567 d = opendir("/run/systemd/seats");
572 log_error("Failed to open /run/systemd/seats: %m");
576 while ((de = readdir(d))) {
580 if (!dirent_is_file(de))
583 s = hashmap_get(m->seats, de->d_name);
585 unlinkat(dirfd(d), de->d_name, 0);
599 static int manager_enumerate_users_from_cgroup(Manager *m) {
600 _cleanup_closedir_ DIR *d = NULL;
604 r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
609 log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
613 while ((k = cg_read_subgroup(d, &name)) > 0) {
617 e = endswith(name, ".user");
621 k = manager_add_user_by_name(m, name, &user);
628 user_add_to_gc_queue(user);
630 if (!user->cgroup_path) {
631 user->cgroup_path = strjoin(m->cgroup_path, "/", name, NULL);
632 if (!user->cgroup_path) {
649 static int manager_enumerate_linger_users(Manager *m) {
654 d = opendir("/var/lib/systemd/linger");
659 log_error("Failed to open /var/lib/systemd/linger/: %m");
663 while ((de = readdir(d))) {
666 if (!dirent_is_file(de))
669 k = manager_add_user_by_name(m, de->d_name, NULL);
671 log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
681 int manager_enumerate_users(Manager *m) {
688 /* First, enumerate user cgroups */
689 r = manager_enumerate_users_from_cgroup(m);
691 /* Second, add lingering users on top */
692 k = manager_enumerate_linger_users(m);
696 /* Third, read in user data stored on disk */
697 d = opendir("/run/systemd/users");
702 log_error("Failed to open /run/systemd/users: %m");
706 while ((de = readdir(d))) {
710 if (!dirent_is_file(de))
713 k = parse_uid(de->d_name, &uid);
715 log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
719 u = hashmap_get(m->users, ULONG_TO_PTR(uid));
721 unlinkat(dirfd(d), de->d_name, 0);
735 static int manager_enumerate_sessions_from_cgroup(Manager *m) {
740 HASHMAP_FOREACH(u, m->users, i) {
741 _cleanup_closedir_ DIR *d = NULL;
748 k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
753 log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
758 while ((k = cg_read_subgroup(d, &name)) > 0) {
762 e = endswith(name, ".session");
766 k = manager_add_session(m, u, name, &session);
773 session_add_to_gc_queue(session);
775 if (!session->cgroup_path) {
776 session->cgroup_path = strjoin(m->cgroup_path, "/", name, NULL);
777 if (!session->cgroup_path) {
795 int manager_enumerate_sessions(Manager *m) {
802 /* First enumerate session cgroups */
803 r = manager_enumerate_sessions_from_cgroup(m);
805 /* Second, read in session data stored on disk */
806 d = opendir("/run/systemd/sessions");
811 log_error("Failed to open /run/systemd/sessions: %m");
815 while ((de = readdir(d))) {
819 if (!dirent_is_file(de))
822 s = hashmap_get(m->sessions, de->d_name);
824 unlinkat(dirfd(d), de->d_name, 0);
838 int manager_enumerate_inhibitors(Manager *m) {
845 d = opendir("/run/systemd/inhibit");
850 log_error("Failed to open /run/systemd/inhibit: %m");
854 while ((de = readdir(d))) {
858 if (!dirent_is_file(de))
861 k = manager_add_inhibitor(m, de->d_name, &i);
863 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
868 k = inhibitor_load(i);
878 int manager_dispatch_seat_udev(Manager *m) {
879 struct udev_device *d;
884 d = udev_monitor_receive_device(m->udev_seat_monitor);
888 r = manager_process_seat_device(m, d);
889 udev_device_unref(d);
894 int manager_dispatch_vcsa_udev(Manager *m) {
895 struct udev_device *d;
901 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
905 name = udev_device_get_sysname(d);
907 /* Whenever a VCSA device is removed try to reallocate our
908 * VTs, to make sure our auto VTs never go away. */
910 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
911 r = seat_preallocate_vts(m->vtconsole);
913 udev_device_unref(d);
918 int manager_dispatch_button_udev(Manager *m) {
919 struct udev_device *d;
924 d = udev_monitor_receive_device(m->udev_button_monitor);
928 r = manager_process_button_device(m, d);
929 udev_device_unref(d);
934 int manager_dispatch_console(Manager *m) {
938 seat_read_active_vt(m->vtconsole);
943 static int vt_is_busy(int vtnr) {
944 struct vt_stat vt_stat;
949 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
950 * we'd open the latter we'd open the foreground tty which
951 * hence would be unconditionally busy. By opening /dev/tty1
952 * we avoid this. Since tty1 is special and needs to be an
953 * explicitly loaded getty or DM this is safe. */
955 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
959 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
962 r = !!(vt_stat.v_state & (1 << vtnr));
964 close_nointr_nofail(fd);
969 int manager_spawn_autovt(Manager *m, int vtnr) {
972 const char *mode = "fail";
977 if ((unsigned) vtnr > m->n_autovts &&
978 (unsigned) vtnr != m->reserve_vt)
981 if ((unsigned) vtnr != m->reserve_vt) {
982 /* If this is the reserved TTY, we'll start the getty
983 * on it in any case, but otherwise only if it is not
986 r = vt_is_busy(vtnr);
993 if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
994 log_error("Could not allocate service name.");
999 r = bus_method_call_with_reply (
1001 "org.freedesktop.systemd1",
1002 "/org/freedesktop/systemd1",
1003 "org.freedesktop.systemd1.Manager",
1007 DBUS_TYPE_STRING, &name,
1008 DBUS_TYPE_STRING, &mode,
1017 static int manager_reserve_vt(Manager *m) {
1018 _cleanup_free_ char *p = NULL;
1022 if (m->reserve_vt <= 0)
1025 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
1028 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
1029 if (m->reserve_vt_fd < 0) {
1031 /* Don't complain on VT-less systems */
1032 if (errno != ENOENT)
1033 log_warning("Failed to pin reserved VT: %m");
1040 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
1048 s = hashmap_get(m->session_cgroups, cgroup);
1054 p = strdupa(cgroup);
1059 e = strrchr(p, '/');
1067 s = hashmap_get(m->session_cgroups, p);
1075 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1083 u = hashmap_get(m->user_cgroups, cgroup);
1089 p = strdupa(cgroup);
1096 e = strrchr(p, '/');
1104 u = hashmap_get(m->user_cgroups, p);
1112 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1113 _cleanup_free_ char *p = NULL;
1120 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1124 return manager_get_session_by_cgroup(m, p, session);
1127 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1132 r = manager_get_session_by_cgroup(m, cgroup, &s);
1134 session_add_to_gc_queue(s);
1136 r = manager_get_user_by_cgroup(m, cgroup, &u);
1138 user_add_to_gc_queue(u);
1141 static void manager_dispatch_other(Manager *m, int fd) {
1149 s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1151 assert(s->fifo_fd == fd);
1152 session_remove_fifo(s);
1157 i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1159 assert(i->fifo_fd == fd);
1165 b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1167 assert(b->fd == fd);
1172 assert_not_reached("Got event for unknown fd");
1175 static int manager_connect_bus(Manager *m) {
1178 struct epoll_event ev = {
1185 assert(m->bus_fd < 0);
1187 dbus_error_init(&error);
1189 m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1191 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1196 if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1197 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1198 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1199 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1200 !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1205 dbus_bus_add_match(m->bus,
1207 "interface='org.freedesktop.systemd1.Agent',"
1208 "member='Released',"
1209 "path='/org/freedesktop/systemd1/agent'",
1212 if (dbus_error_is_set(&error)) {
1213 log_error("Failed to register match: %s", bus_error_message(&error));
1218 r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1219 if (dbus_error_is_set(&error)) {
1220 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1225 if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1226 log_error("Failed to acquire name.");
1231 m->bus_fd = bus_loop_open(m->bus);
1232 if (m->bus_fd < 0) {
1237 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1243 dbus_error_free(&error);
1248 static int manager_connect_console(Manager *m) {
1249 struct epoll_event ev = {
1251 .data.u32 = FD_CONSOLE,
1255 assert(m->console_active_fd < 0);
1257 /* On certain architectures (S390 and Xen, and containers),
1258 /dev/tty0 does not exist, so don't fail if we can't open
1260 if (access("/dev/tty0", F_OK) < 0) {
1261 m->console_active_fd = -1;
1265 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1266 if (m->console_active_fd < 0) {
1268 /* On some systems the device node /dev/tty0 may exist
1269 * even though /sys/class/tty/tty0 does not. */
1270 if (errno == ENOENT)
1273 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1277 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1283 static int manager_connect_udev(Manager *m) {
1285 struct epoll_event ev = {
1287 .data.u32 = FD_SEAT_UDEV,
1291 assert(!m->udev_seat_monitor);
1292 assert(!m->udev_vcsa_monitor);
1293 assert(!m->udev_button_monitor);
1295 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1296 if (!m->udev_seat_monitor)
1299 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1303 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1307 m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1309 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1312 /* Don't watch keys if nobody cares */
1313 if (m->handle_power_key != HANDLE_IGNORE ||
1314 m->handle_suspend_key != HANDLE_IGNORE ||
1315 m->handle_hibernate_key != HANDLE_IGNORE ||
1316 m->handle_lid_switch != HANDLE_IGNORE) {
1318 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1319 if (!m->udev_button_monitor)
1322 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1326 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1330 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1334 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1337 ev.events = EPOLLIN;
1338 ev.data.u32 = FD_BUTTON_UDEV;
1339 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1343 /* Don't bother watching VCSA devices, if nobody cares */
1344 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1346 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1347 if (!m->udev_vcsa_monitor)
1350 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1354 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1358 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1361 ev.events = EPOLLIN;
1362 ev.data.u32 = FD_VCSA_UDEV;
1363 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1370 void manager_gc(Manager *m, bool drop_not_started) {
1377 while ((seat = m->seat_gc_queue)) {
1378 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1379 seat->in_gc_queue = false;
1381 if (seat_check_gc(seat, drop_not_started) == 0) {
1387 while ((session = m->session_gc_queue)) {
1388 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1389 session->in_gc_queue = false;
1391 if (session_check_gc(session, drop_not_started) == 0) {
1392 session_stop(session);
1393 session_free(session);
1397 while ((user = m->user_gc_queue)) {
1398 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1399 user->in_gc_queue = false;
1401 if (user_check_gc(user, drop_not_started) == 0) {
1408 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1411 dual_timestamp ts = { 0, 0 };
1416 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1418 HASHMAP_FOREACH(s, m->sessions, i) {
1422 ih = session_get_idle_hint(s, &k);
1428 if (k.monotonic < ts.monotonic)
1434 } else if (idle_hint) {
1436 if (k.monotonic > ts.monotonic)
1447 int manager_dispatch_idle_action(Manager *m) {
1448 struct dual_timestamp since;
1449 struct itimerspec its = {};
1455 if (m->idle_action == HANDLE_IGNORE ||
1456 m->idle_action_usec <= 0) {
1461 n = now(CLOCK_MONOTONIC);
1463 r = manager_get_idle_hint(m, &since);
1465 /* Not idle. Let's check if after a timeout it might be idle then. */
1466 timespec_store(&its.it_value, n + m->idle_action_usec);
1468 /* Idle! Let's see if it's time to do something, or if
1469 * we shall sleep for longer. */
1471 if (n >= since.monotonic + m->idle_action_usec &&
1472 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1473 log_info("System idle. Taking action.");
1475 manager_handle_action(m, 0, m->idle_action, false, false);
1476 m->idle_action_not_before_usec = n;
1479 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1482 if (m->idle_action_fd < 0) {
1483 struct epoll_event ev = {
1485 .data.u32 = FD_IDLE_ACTION,
1488 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1489 if (m->idle_action_fd < 0) {
1490 log_error("Failed to create idle action timer: %m");
1495 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1496 log_error("Failed to add idle action timer to epoll: %m");
1502 if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1503 log_error("Failed to reset timerfd: %m");
1511 if (m->idle_action_fd >= 0) {
1512 close_nointr_nofail(m->idle_action_fd);
1513 m->idle_action_fd = -1;
1518 int manager_startup(Manager *m) {
1523 Inhibitor *inhibitor;
1527 assert(m->epoll_fd <= 0);
1529 cg_shorten_controllers(m->reset_controllers);
1530 cg_shorten_controllers(m->controllers);
1532 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1533 if (m->epoll_fd < 0)
1536 /* Connect to console */
1537 r = manager_connect_console(m);
1541 /* Connect to udev */
1542 r = manager_connect_udev(m);
1546 /* Connect to the bus */
1547 r = manager_connect_bus(m);
1551 /* Instantiate magic seat 0 */
1552 r = manager_add_seat(m, "seat0", &m->vtconsole);
1556 /* Deserialize state */
1557 manager_enumerate_devices(m);
1558 manager_enumerate_seats(m);
1559 manager_enumerate_users(m);
1560 manager_enumerate_sessions(m);
1561 manager_enumerate_inhibitors(m);
1562 manager_enumerate_buttons(m);
1564 /* Remove stale objects before we start them */
1565 manager_gc(m, false);
1567 /* Reserve the special reserved VT */
1568 manager_reserve_vt(m);
1570 /* And start everything */
1571 HASHMAP_FOREACH(seat, m->seats, i)
1574 HASHMAP_FOREACH(user, m->users, i)
1577 HASHMAP_FOREACH(session, m->sessions, i)
1578 session_start(session);
1580 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1581 inhibitor_start(inhibitor);
1583 manager_dispatch_idle_action(m);
1588 static int manager_recheck_buttons(Manager *m) {
1595 HASHMAP_FOREACH(b, m->buttons, i) {
1598 q = button_recheck(b);
1608 int manager_run(Manager *m) {
1612 struct epoll_event event;
1616 manager_gc(m, true);
1618 if (manager_dispatch_delayed(m) > 0)
1621 if (manager_recheck_buttons(m) > 0)
1624 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1627 manager_gc(m, true);
1629 if (m->action_what != 0 && !m->action_job) {
1632 x = now(CLOCK_MONOTONIC);
1633 y = m->action_timestamp + m->inhibit_delay_max;
1635 msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1638 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1640 if (errno == EINTR || errno == EAGAIN)
1643 log_error("epoll() failed: %m");
1650 switch (event.data.u32) {
1653 manager_dispatch_seat_udev(m);
1657 manager_dispatch_vcsa_udev(m);
1660 case FD_BUTTON_UDEV:
1661 manager_dispatch_button_udev(m);
1665 manager_dispatch_console(m);
1668 case FD_IDLE_ACTION:
1669 manager_dispatch_idle_action(m);
1673 bus_loop_dispatch(m->bus_fd);
1677 if (event.data.u32 >= FD_OTHER_BASE)
1678 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1685 static int manager_parse_config_file(Manager *m) {
1686 static const char fn[] = "/etc/systemd/logind.conf";
1687 _cleanup_fclose_ FILE *f = NULL;
1692 f = fopen(fn, "re");
1694 if (errno == ENOENT)
1697 log_warning("Failed to open configuration file %s: %m", fn);
1701 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1702 (void*) logind_gperf_lookup, false, false, m);
1704 log_warning("Failed to parse configuration file: %s", strerror(-r));
1709 int main(int argc, char *argv[]) {
1713 log_set_target(LOG_TARGET_AUTO);
1714 log_set_facility(LOG_AUTH);
1715 log_parse_environment();
1721 log_error("This program takes no arguments.");
1726 /* Always create the directories people can create inotify
1727 * watches in. Note that some applications might check for the
1728 * existence of /run/systemd/seats/ to determine whether
1729 * logind is available, so please always make sure this check
1731 mkdir_label("/run/systemd/seats", 0755);
1732 mkdir_label("/run/systemd/users", 0755);
1733 mkdir_label("/run/systemd/sessions", 0755);
1741 manager_parse_config_file(m);
1743 r = manager_startup(m);
1745 log_error("Failed to fully start up daemon: %s", strerror(-r));
1749 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1753 "STATUS=Processing requests...");
1757 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1761 "STATUS=Shutting down...");
1766 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;