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_vcsa_monitor)
155 udev_monitor_unref(m->udev_vcsa_monitor);
156 if (m->udev_button_monitor)
157 udev_monitor_unref(m->udev_button_monitor);
163 dbus_connection_flush(m->bus);
164 dbus_connection_close(m->bus);
165 dbus_connection_unref(m->bus);
169 close_nointr_nofail(m->bus_fd);
171 if (m->epoll_fd >= 0)
172 close_nointr_nofail(m->epoll_fd);
174 if (m->reserve_vt_fd >= 0)
175 close_nointr_nofail(m->reserve_vt_fd);
177 if (m->idle_action_fd >= 0)
178 close_nointr_nofail(m->idle_action_fd);
180 strv_free(m->kill_only_users);
181 strv_free(m->kill_exclude_users);
187 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
193 d = hashmap_get(m->devices, sysfs);
201 d = device_new(m, sysfs);
211 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
217 s = hashmap_get(m->seats, id);
235 int manager_add_session(Manager *m, const char *id, Session **_session) {
241 s = hashmap_get(m->sessions, id);
249 s = session_new(m, id);
259 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
265 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
273 u = user_new(m, uid, gid, name);
283 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
291 r = get_user_creds(&name, &uid, &gid, NULL, NULL);
295 return manager_add_user(m, uid, gid, name, _user);
298 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
306 return errno ? -errno : -ENOENT;
308 return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
311 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
317 i = hashmap_get(m->inhibitors, id);
325 i = inhibitor_new(m, id);
335 int manager_add_button(Manager *m, const char *name, Button **_button) {
341 b = hashmap_get(m->buttons, name);
349 b = button_new(m, name);
359 int manager_process_seat_device(Manager *m, struct udev_device *d) {
365 if (streq_ptr(udev_device_get_action(d), "remove")) {
367 device = hashmap_get(m->devices, udev_device_get_syspath(d));
371 seat_add_to_gc_queue(device->seat);
378 sn = udev_device_get_property_value(d, "ID_SEAT");
382 if (!seat_name_is_valid(sn)) {
383 log_warning("Device with invalid seat name %s found, ignoring.", sn);
387 r = manager_add_device(m, udev_device_get_syspath(d), &device);
391 r = manager_add_seat(m, sn, &seat);
399 device_attach(device, seat);
406 int manager_process_button_device(Manager *m, struct udev_device *d) {
413 if (streq_ptr(udev_device_get_action(d), "remove")) {
415 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
424 r = manager_add_button(m, udev_device_get_sysname(d), &b);
428 sn = udev_device_get_property_value(d, "ID_SEAT");
432 button_set_seat(b, sn);
439 int manager_enumerate_devices(Manager *m) {
440 struct udev_list_entry *item = NULL, *first = NULL;
441 struct udev_enumerate *e;
446 /* Loads devices from udev and creates seats for them as
449 e = udev_enumerate_new(m->udev);
455 r = udev_enumerate_add_match_tag(e, "master-of-seat");
459 r = udev_enumerate_scan_devices(e);
463 first = udev_enumerate_get_list_entry(e);
464 udev_list_entry_foreach(item, first) {
465 struct udev_device *d;
468 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
474 k = manager_process_seat_device(m, d);
475 udev_device_unref(d);
483 udev_enumerate_unref(e);
488 int manager_enumerate_buttons(Manager *m) {
489 struct udev_list_entry *item = NULL, *first = NULL;
490 struct udev_enumerate *e;
495 /* Loads buttons from udev */
497 if (m->handle_power_key == HANDLE_IGNORE &&
498 m->handle_suspend_key == HANDLE_IGNORE &&
499 m->handle_hibernate_key == HANDLE_IGNORE &&
500 m->handle_lid_switch == HANDLE_IGNORE)
503 e = udev_enumerate_new(m->udev);
509 r = udev_enumerate_add_match_subsystem(e, "input");
513 r = udev_enumerate_add_match_tag(e, "power-switch");
517 r = udev_enumerate_scan_devices(e);
521 first = udev_enumerate_get_list_entry(e);
522 udev_list_entry_foreach(item, first) {
523 struct udev_device *d;
526 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
532 k = manager_process_button_device(m, d);
533 udev_device_unref(d);
541 udev_enumerate_unref(e);
546 int manager_enumerate_seats(Manager *m) {
547 _cleanup_closedir_ DIR *d = NULL;
553 /* This loads data about seats stored on disk, but does not
554 * actually create any seats. Removes data of seats that no
557 d = opendir("/run/systemd/seats");
562 log_error("Failed to open /run/systemd/seats: %m");
566 FOREACH_DIRENT(de, d, return -errno) {
570 if (!dirent_is_file(de))
573 s = hashmap_get(m->seats, de->d_name);
575 unlinkat(dirfd(d), de->d_name, 0);
587 static int manager_enumerate_linger_users(Manager *m) {
588 _cleanup_closedir_ DIR *d = NULL;
594 d = opendir("/var/lib/systemd/linger");
599 log_error("Failed to open /var/lib/systemd/linger/: %m");
603 FOREACH_DIRENT(de, d, return -errno) {
606 if (!dirent_is_file(de))
609 k = manager_add_user_by_name(m, de->d_name, NULL);
611 log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
619 int manager_enumerate_users(Manager *m) {
620 _cleanup_closedir_ DIR *d = NULL;
626 /* Add lingering users */
627 r = manager_enumerate_linger_users(m);
629 /* Read in user data stored on disk */
630 d = opendir("/run/systemd/users");
635 log_error("Failed to open /run/systemd/users: %m");
639 FOREACH_DIRENT(de, d, return -errno) {
642 if (!dirent_is_file(de))
645 k = manager_add_user_by_name(m, de->d_name, &u);
647 log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
653 user_add_to_gc_queue(u);
663 int manager_enumerate_sessions(Manager *m) {
664 _cleanup_closedir_ DIR *d = NULL;
670 /* Read in session data stored on disk */
671 d = opendir("/run/systemd/sessions");
676 log_error("Failed to open /run/systemd/sessions: %m");
680 FOREACH_DIRENT(de, d, return -errno) {
684 if (!dirent_is_file(de))
687 if (!session_id_valid(de->d_name)) {
688 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
693 k = manager_add_session(m, de->d_name, &s);
695 log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
701 session_add_to_gc_queue(s);
711 int manager_enumerate_inhibitors(Manager *m) {
712 _cleanup_closedir_ DIR *d = NULL;
718 d = opendir("/run/systemd/inhibit");
723 log_error("Failed to open /run/systemd/inhibit: %m");
727 FOREACH_DIRENT(de, d, return -errno) {
731 if (!dirent_is_file(de))
734 k = manager_add_inhibitor(m, de->d_name, &i);
736 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
741 k = inhibitor_load(i);
749 int manager_dispatch_seat_udev(Manager *m) {
750 struct udev_device *d;
755 d = udev_monitor_receive_device(m->udev_seat_monitor);
759 r = manager_process_seat_device(m, d);
760 udev_device_unref(d);
765 int manager_dispatch_vcsa_udev(Manager *m) {
766 struct udev_device *d;
772 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
776 name = udev_device_get_sysname(d);
778 /* Whenever a VCSA device is removed try to reallocate our
779 * VTs, to make sure our auto VTs never go away. */
781 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
782 r = seat_preallocate_vts(m->vtconsole);
784 udev_device_unref(d);
789 int manager_dispatch_button_udev(Manager *m) {
790 struct udev_device *d;
795 d = udev_monitor_receive_device(m->udev_button_monitor);
799 r = manager_process_button_device(m, d);
800 udev_device_unref(d);
805 int manager_dispatch_console(Manager *m) {
809 seat_read_active_vt(m->vtconsole);
814 static int vt_is_busy(int vtnr) {
815 struct vt_stat vt_stat;
820 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
821 * we'd open the latter we'd open the foreground tty which
822 * hence would be unconditionally busy. By opening /dev/tty1
823 * we avoid this. Since tty1 is special and needs to be an
824 * explicitly loaded getty or DM this is safe. */
826 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
830 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
833 r = !!(vt_stat.v_state & (1 << vtnr));
835 close_nointr_nofail(fd);
840 int manager_spawn_autovt(Manager *m, int vtnr) {
843 const char *mode = "fail";
848 if ((unsigned) vtnr > m->n_autovts &&
849 (unsigned) vtnr != m->reserve_vt)
852 if ((unsigned) vtnr != m->reserve_vt) {
853 /* If this is the reserved TTY, we'll start the getty
854 * on it in any case, but otherwise only if it is not
857 r = vt_is_busy(vtnr);
864 if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
865 log_error("Could not allocate service name.");
870 r = bus_method_call_with_reply (
872 "org.freedesktop.systemd1",
873 "/org/freedesktop/systemd1",
874 "org.freedesktop.systemd1.Manager",
878 DBUS_TYPE_STRING, &name,
879 DBUS_TYPE_STRING, &mode,
888 static int manager_reserve_vt(Manager *m) {
889 _cleanup_free_ char *p = NULL;
893 if (m->reserve_vt <= 0)
896 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
899 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
900 if (m->reserve_vt_fd < 0) {
902 /* Don't complain on VT-less systems */
904 log_warning("Failed to pin reserved VT: %m");
911 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
912 _cleanup_free_ char *unit = NULL;
920 r = cg_pid_get_unit(pid, &unit);
924 s = hashmap_get(m->session_units, unit);
932 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
933 _cleanup_free_ char *unit = NULL;
941 r = cg_pid_get_slice(pid, &unit);
945 u = hashmap_get(m->user_units, unit);
953 static void manager_dispatch_other(Manager *m, int fd) {
961 s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
963 assert(s->fifo_fd == fd);
964 session_remove_fifo(s);
969 i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
971 assert(i->fifo_fd == fd);
977 b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
984 assert_not_reached("Got event for unknown fd");
987 static int manager_connect_bus(Manager *m) {
990 struct epoll_event ev = {
997 assert(m->bus_fd < 0);
999 dbus_error_init(&error);
1001 m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1003 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1008 if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1009 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1010 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1011 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1012 !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1017 dbus_bus_add_match(m->bus,
1019 "sender='org.freedesktop.systemd1',"
1020 "interface='org.freedesktop.systemd1.Manager',"
1021 "member='JobRemoved',"
1022 "path='/org/freedesktop/systemd1'",
1024 if (dbus_error_is_set(&error)) {
1025 log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
1026 dbus_error_free(&error);
1029 dbus_bus_add_match(m->bus,
1031 "sender='org.freedesktop.systemd1',"
1032 "interface='org.freedesktop.systemd1.Manager',"
1033 "member='UnitRemoved',"
1034 "path='/org/freedesktop/systemd1'",
1036 if (dbus_error_is_set(&error)) {
1037 log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
1038 dbus_error_free(&error);
1041 dbus_bus_add_match(m->bus,
1043 "sender='org.freedesktop.systemd1',"
1044 "interface='org.freedesktop.DBus.Properties',"
1045 "member='PropertiesChanged'",
1047 if (dbus_error_is_set(&error)) {
1048 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1049 dbus_error_free(&error);
1052 dbus_bus_add_match(m->bus,
1054 "sender='org.freedesktop.systemd1',"
1055 "interface='org.freedesktop.systemd1.Manager',"
1056 "member='Reloading',"
1057 "path='/org/freedesktop/systemd1'",
1059 if (dbus_error_is_set(&error)) {
1060 log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
1061 dbus_error_free(&error);
1064 r = bus_method_call_with_reply(
1066 "org.freedesktop.systemd1",
1067 "/org/freedesktop/systemd1",
1068 "org.freedesktop.systemd1.Manager",
1074 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1075 dbus_error_free(&error);
1078 r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1079 if (dbus_error_is_set(&error)) {
1080 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1085 if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1086 log_error("Failed to acquire name.");
1091 m->bus_fd = bus_loop_open(m->bus);
1092 if (m->bus_fd < 0) {
1097 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1103 dbus_error_free(&error);
1108 static int manager_connect_console(Manager *m) {
1109 struct epoll_event ev = {
1111 .data.u32 = FD_CONSOLE,
1115 assert(m->console_active_fd < 0);
1117 /* On certain architectures (S390 and Xen, and containers),
1118 /dev/tty0 does not exist, so don't fail if we can't open
1120 if (access("/dev/tty0", F_OK) < 0) {
1121 m->console_active_fd = -1;
1125 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1126 if (m->console_active_fd < 0) {
1128 /* On some systems the device node /dev/tty0 may exist
1129 * even though /sys/class/tty/tty0 does not. */
1130 if (errno == ENOENT)
1133 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1137 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1143 static int manager_connect_udev(Manager *m) {
1145 struct epoll_event ev = {
1147 .data.u32 = FD_SEAT_UDEV,
1151 assert(!m->udev_seat_monitor);
1152 assert(!m->udev_vcsa_monitor);
1153 assert(!m->udev_button_monitor);
1155 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1156 if (!m->udev_seat_monitor)
1159 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1163 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1167 m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1169 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1172 /* Don't watch keys if nobody cares */
1173 if (m->handle_power_key != HANDLE_IGNORE ||
1174 m->handle_suspend_key != HANDLE_IGNORE ||
1175 m->handle_hibernate_key != HANDLE_IGNORE ||
1176 m->handle_lid_switch != HANDLE_IGNORE) {
1178 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1179 if (!m->udev_button_monitor)
1182 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1186 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1190 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1194 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1197 ev.events = EPOLLIN;
1198 ev.data.u32 = FD_BUTTON_UDEV;
1199 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1203 /* Don't bother watching VCSA devices, if nobody cares */
1204 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1206 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1207 if (!m->udev_vcsa_monitor)
1210 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1214 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1218 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1221 ev.events = EPOLLIN;
1222 ev.data.u32 = FD_VCSA_UDEV;
1223 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1230 void manager_gc(Manager *m, bool drop_not_started) {
1237 while ((seat = m->seat_gc_queue)) {
1238 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1239 seat->in_gc_queue = false;
1241 if (seat_check_gc(seat, drop_not_started) == 0) {
1247 while ((session = m->session_gc_queue)) {
1248 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1249 session->in_gc_queue = false;
1251 if (session_check_gc(session, drop_not_started) == 0) {
1252 session_stop(session);
1253 session_finalize(session);
1254 session_free(session);
1258 while ((user = m->user_gc_queue)) {
1259 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1260 user->in_gc_queue = false;
1262 if (user_check_gc(user, drop_not_started) == 0) {
1264 user_finalize(user);
1270 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1273 dual_timestamp ts = { 0, 0 };
1278 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1280 HASHMAP_FOREACH(s, m->sessions, i) {
1284 ih = session_get_idle_hint(s, &k);
1290 if (k.monotonic < ts.monotonic)
1296 } else if (idle_hint) {
1298 if (k.monotonic > ts.monotonic)
1309 bool manager_shall_kill(Manager *m, const char *user) {
1313 if (!m->kill_user_processes)
1316 if (strv_contains(m->kill_exclude_users, user))
1319 if (strv_isempty(m->kill_only_users))
1322 return strv_contains(m->kill_only_users, user);
1325 int manager_dispatch_idle_action(Manager *m) {
1326 struct dual_timestamp since;
1327 struct itimerspec its = {};
1333 if (m->idle_action == HANDLE_IGNORE ||
1334 m->idle_action_usec <= 0) {
1339 n = now(CLOCK_MONOTONIC);
1341 r = manager_get_idle_hint(m, &since);
1343 /* Not idle. Let's check if after a timeout it might be idle then. */
1344 timespec_store(&its.it_value, n + m->idle_action_usec);
1346 /* Idle! Let's see if it's time to do something, or if
1347 * we shall sleep for longer. */
1349 if (n >= since.monotonic + m->idle_action_usec &&
1350 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1351 log_info("System idle. Taking action.");
1353 manager_handle_action(m, 0, m->idle_action, false, false);
1354 m->idle_action_not_before_usec = n;
1357 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1360 if (m->idle_action_fd < 0) {
1361 struct epoll_event ev = {
1363 .data.u32 = FD_IDLE_ACTION,
1366 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1367 if (m->idle_action_fd < 0) {
1368 log_error("Failed to create idle action timer: %m");
1373 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1374 log_error("Failed to add idle action timer to epoll: %m");
1380 if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1381 log_error("Failed to reset timerfd: %m");
1389 if (m->idle_action_fd >= 0) {
1390 close_nointr_nofail(m->idle_action_fd);
1391 m->idle_action_fd = -1;
1396 int manager_startup(Manager *m) {
1401 Inhibitor *inhibitor;
1405 assert(m->epoll_fd <= 0);
1407 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1408 if (m->epoll_fd < 0)
1411 /* Connect to console */
1412 r = manager_connect_console(m);
1416 /* Connect to udev */
1417 r = manager_connect_udev(m);
1421 /* Connect to the bus */
1422 r = manager_connect_bus(m);
1426 /* Instantiate magic seat 0 */
1427 r = manager_add_seat(m, "seat0", &m->vtconsole);
1431 /* Deserialize state */
1432 r = manager_enumerate_devices(m);
1434 log_warning("Device enumeration failed: %s", strerror(-r));
1436 r = manager_enumerate_seats(m);
1438 log_warning("Seat enumeration failed: %s", strerror(-r));
1440 r = manager_enumerate_users(m);
1442 log_warning("User enumeration failed: %s", strerror(-r));
1444 r = manager_enumerate_sessions(m);
1446 log_warning("Session enumeration failed: %s", strerror(-r));
1448 r = manager_enumerate_inhibitors(m);
1450 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1452 r = manager_enumerate_buttons(m);
1454 log_warning("Button enumeration failed: %s", strerror(-r));
1456 /* Remove stale objects before we start them */
1457 manager_gc(m, false);
1459 /* Reserve the special reserved VT */
1460 manager_reserve_vt(m);
1462 /* And start everything */
1463 HASHMAP_FOREACH(seat, m->seats, i)
1466 HASHMAP_FOREACH(user, m->users, i)
1469 HASHMAP_FOREACH(session, m->sessions, i)
1470 session_start(session);
1472 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1473 inhibitor_start(inhibitor);
1475 manager_dispatch_idle_action(m);
1480 static int manager_recheck_buttons(Manager *m) {
1487 HASHMAP_FOREACH(b, m->buttons, i) {
1490 q = button_recheck(b);
1500 int manager_run(Manager *m) {
1504 struct epoll_event event;
1508 manager_gc(m, true);
1510 if (manager_dispatch_delayed(m) > 0)
1513 if (manager_recheck_buttons(m) > 0)
1516 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1519 manager_gc(m, true);
1521 if (m->action_what != 0 && !m->action_job) {
1524 x = now(CLOCK_MONOTONIC);
1525 y = m->action_timestamp + m->inhibit_delay_max;
1527 msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1530 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1532 if (errno == EINTR || errno == EAGAIN)
1535 log_error("epoll() failed: %m");
1542 switch (event.data.u32) {
1545 manager_dispatch_seat_udev(m);
1549 manager_dispatch_vcsa_udev(m);
1552 case FD_BUTTON_UDEV:
1553 manager_dispatch_button_udev(m);
1557 manager_dispatch_console(m);
1560 case FD_IDLE_ACTION:
1561 manager_dispatch_idle_action(m);
1565 bus_loop_dispatch(m->bus_fd);
1569 if (event.data.u32 >= FD_OTHER_BASE)
1570 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1577 static int manager_parse_config_file(Manager *m) {
1578 static const char fn[] = "/etc/systemd/logind.conf";
1579 _cleanup_fclose_ FILE *f = NULL;
1584 f = fopen(fn, "re");
1586 if (errno == ENOENT)
1589 log_warning("Failed to open configuration file %s: %m", fn);
1593 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1594 (void*) logind_gperf_lookup, false, false, m);
1596 log_warning("Failed to parse configuration file: %s", strerror(-r));
1601 int main(int argc, char *argv[]) {
1605 log_set_target(LOG_TARGET_AUTO);
1606 log_set_facility(LOG_AUTH);
1607 log_parse_environment();
1613 log_error("This program takes no arguments.");
1618 /* Always create the directories people can create inotify
1619 * watches in. Note that some applications might check for the
1620 * existence of /run/systemd/seats/ to determine whether
1621 * logind is available, so please always make sure this check
1623 mkdir_label("/run/systemd/seats", 0755);
1624 mkdir_label("/run/systemd/users", 0755);
1625 mkdir_label("/run/systemd/sessions", 0755);
1633 manager_parse_config_file(m);
1635 r = manager_startup(m);
1637 log_error("Failed to fully start up daemon: %s", strerror(-r));
1641 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1645 "STATUS=Processing requests...");
1649 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1653 "STATUS=Shutting down...");
1658 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;