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 k = manager_add_session(m, de->d_name, &s);
689 log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
695 session_add_to_gc_queue(s);
705 int manager_enumerate_inhibitors(Manager *m) {
706 _cleanup_closedir_ DIR *d = NULL;
712 d = opendir("/run/systemd/inhibit");
717 log_error("Failed to open /run/systemd/inhibit: %m");
721 FOREACH_DIRENT(de, d, return -errno) {
725 if (!dirent_is_file(de))
728 k = manager_add_inhibitor(m, de->d_name, &i);
730 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
735 k = inhibitor_load(i);
743 int manager_dispatch_seat_udev(Manager *m) {
744 struct udev_device *d;
749 d = udev_monitor_receive_device(m->udev_seat_monitor);
753 r = manager_process_seat_device(m, d);
754 udev_device_unref(d);
759 int manager_dispatch_vcsa_udev(Manager *m) {
760 struct udev_device *d;
766 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
770 name = udev_device_get_sysname(d);
772 /* Whenever a VCSA device is removed try to reallocate our
773 * VTs, to make sure our auto VTs never go away. */
775 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
776 r = seat_preallocate_vts(m->vtconsole);
778 udev_device_unref(d);
783 int manager_dispatch_button_udev(Manager *m) {
784 struct udev_device *d;
789 d = udev_monitor_receive_device(m->udev_button_monitor);
793 r = manager_process_button_device(m, d);
794 udev_device_unref(d);
799 int manager_dispatch_console(Manager *m) {
803 seat_read_active_vt(m->vtconsole);
808 static int vt_is_busy(int vtnr) {
809 struct vt_stat vt_stat;
814 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
815 * we'd open the latter we'd open the foreground tty which
816 * hence would be unconditionally busy. By opening /dev/tty1
817 * we avoid this. Since tty1 is special and needs to be an
818 * explicitly loaded getty or DM this is safe. */
820 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
824 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
827 r = !!(vt_stat.v_state & (1 << vtnr));
829 close_nointr_nofail(fd);
834 int manager_spawn_autovt(Manager *m, int vtnr) {
837 const char *mode = "fail";
842 if ((unsigned) vtnr > m->n_autovts &&
843 (unsigned) vtnr != m->reserve_vt)
846 if ((unsigned) vtnr != m->reserve_vt) {
847 /* If this is the reserved TTY, we'll start the getty
848 * on it in any case, but otherwise only if it is not
851 r = vt_is_busy(vtnr);
858 if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
859 log_error("Could not allocate service name.");
864 r = bus_method_call_with_reply (
866 "org.freedesktop.systemd1",
867 "/org/freedesktop/systemd1",
868 "org.freedesktop.systemd1.Manager",
872 DBUS_TYPE_STRING, &name,
873 DBUS_TYPE_STRING, &mode,
882 static int manager_reserve_vt(Manager *m) {
883 _cleanup_free_ char *p = NULL;
887 if (m->reserve_vt <= 0)
890 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
893 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
894 if (m->reserve_vt_fd < 0) {
896 /* Don't complain on VT-less systems */
898 log_warning("Failed to pin reserved VT: %m");
905 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
906 _cleanup_free_ char *unit = NULL;
914 r = cg_pid_get_unit(pid, &unit);
918 s = hashmap_get(m->session_units, unit);
926 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
927 _cleanup_free_ char *unit = NULL;
935 r = cg_pid_get_slice(pid, &unit);
939 u = hashmap_get(m->user_units, unit);
947 static void manager_dispatch_other(Manager *m, int fd) {
955 s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
957 assert(s->fifo_fd == fd);
958 session_remove_fifo(s);
963 i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
965 assert(i->fifo_fd == fd);
971 b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
978 assert_not_reached("Got event for unknown fd");
981 static int manager_connect_bus(Manager *m) {
984 struct epoll_event ev = {
991 assert(m->bus_fd < 0);
993 dbus_error_init(&error);
995 m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
997 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1002 if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1003 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1004 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1005 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1006 !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1011 dbus_bus_add_match(m->bus,
1013 "sender='org.freedesktop.systemd1',"
1014 "interface='org.freedesktop.systemd1.Manager',"
1015 "member='JobRemoved',"
1016 "path='/org/freedesktop/systemd1'",
1018 if (dbus_error_is_set(&error)) {
1019 log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
1020 dbus_error_free(&error);
1023 dbus_bus_add_match(m->bus,
1025 "sender='org.freedesktop.systemd1',"
1026 "interface='org.freedesktop.systemd1.Manager',"
1027 "member='UnitRemoved',"
1028 "path='/org/freedesktop/systemd1'",
1030 if (dbus_error_is_set(&error)) {
1031 log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
1032 dbus_error_free(&error);
1035 dbus_bus_add_match(m->bus,
1037 "sender='org.freedesktop.systemd1',"
1038 "interface='org.freedesktop.DBus.Properties',"
1039 "member='PropertiesChanged'",
1041 if (dbus_error_is_set(&error)) {
1042 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1043 dbus_error_free(&error);
1046 dbus_bus_add_match(m->bus,
1048 "sender='org.freedesktop.systemd1',"
1049 "interface='org.freedesktop.systemd1.Manager',"
1050 "member='Reloading',"
1051 "path='/org/freedesktop/systemd1'",
1053 if (dbus_error_is_set(&error)) {
1054 log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
1055 dbus_error_free(&error);
1058 r = bus_method_call_with_reply(
1060 "org.freedesktop.systemd1",
1061 "/org/freedesktop/systemd1",
1062 "org.freedesktop.systemd1.Manager",
1068 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1069 dbus_error_free(&error);
1072 r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1073 if (dbus_error_is_set(&error)) {
1074 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1079 if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1080 log_error("Failed to acquire name.");
1085 m->bus_fd = bus_loop_open(m->bus);
1086 if (m->bus_fd < 0) {
1091 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1097 dbus_error_free(&error);
1102 static int manager_connect_console(Manager *m) {
1103 struct epoll_event ev = {
1105 .data.u32 = FD_CONSOLE,
1109 assert(m->console_active_fd < 0);
1111 /* On certain architectures (S390 and Xen, and containers),
1112 /dev/tty0 does not exist, so don't fail if we can't open
1114 if (access("/dev/tty0", F_OK) < 0) {
1115 m->console_active_fd = -1;
1119 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1120 if (m->console_active_fd < 0) {
1122 /* On some systems the device node /dev/tty0 may exist
1123 * even though /sys/class/tty/tty0 does not. */
1124 if (errno == ENOENT)
1127 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1131 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1137 static int manager_connect_udev(Manager *m) {
1139 struct epoll_event ev = {
1141 .data.u32 = FD_SEAT_UDEV,
1145 assert(!m->udev_seat_monitor);
1146 assert(!m->udev_vcsa_monitor);
1147 assert(!m->udev_button_monitor);
1149 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1150 if (!m->udev_seat_monitor)
1153 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1157 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1161 m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1163 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1166 /* Don't watch keys if nobody cares */
1167 if (m->handle_power_key != HANDLE_IGNORE ||
1168 m->handle_suspend_key != HANDLE_IGNORE ||
1169 m->handle_hibernate_key != HANDLE_IGNORE ||
1170 m->handle_lid_switch != HANDLE_IGNORE) {
1172 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1173 if (!m->udev_button_monitor)
1176 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1180 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1184 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1188 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1191 ev.events = EPOLLIN;
1192 ev.data.u32 = FD_BUTTON_UDEV;
1193 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1197 /* Don't bother watching VCSA devices, if nobody cares */
1198 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1200 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1201 if (!m->udev_vcsa_monitor)
1204 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1208 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1212 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1215 ev.events = EPOLLIN;
1216 ev.data.u32 = FD_VCSA_UDEV;
1217 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1224 void manager_gc(Manager *m, bool drop_not_started) {
1231 while ((seat = m->seat_gc_queue)) {
1232 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1233 seat->in_gc_queue = false;
1235 if (seat_check_gc(seat, drop_not_started) == 0) {
1241 while ((session = m->session_gc_queue)) {
1242 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1243 session->in_gc_queue = false;
1245 if (session_check_gc(session, drop_not_started) == 0) {
1246 session_stop(session);
1247 session_finalize(session);
1248 session_free(session);
1252 while ((user = m->user_gc_queue)) {
1253 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1254 user->in_gc_queue = false;
1256 if (user_check_gc(user, drop_not_started) == 0) {
1258 user_finalize(user);
1264 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1267 dual_timestamp ts = { 0, 0 };
1272 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1274 HASHMAP_FOREACH(s, m->sessions, i) {
1278 ih = session_get_idle_hint(s, &k);
1284 if (k.monotonic < ts.monotonic)
1290 } else if (idle_hint) {
1292 if (k.monotonic > ts.monotonic)
1303 bool manager_shall_kill(Manager *m, const char *user) {
1307 if (!m->kill_user_processes)
1310 if (strv_contains(m->kill_exclude_users, user))
1313 if (strv_isempty(m->kill_only_users))
1316 return strv_contains(m->kill_only_users, user);
1319 int manager_dispatch_idle_action(Manager *m) {
1320 struct dual_timestamp since;
1321 struct itimerspec its = {};
1327 if (m->idle_action == HANDLE_IGNORE ||
1328 m->idle_action_usec <= 0) {
1333 n = now(CLOCK_MONOTONIC);
1335 r = manager_get_idle_hint(m, &since);
1337 /* Not idle. Let's check if after a timeout it might be idle then. */
1338 timespec_store(&its.it_value, n + m->idle_action_usec);
1340 /* Idle! Let's see if it's time to do something, or if
1341 * we shall sleep for longer. */
1343 if (n >= since.monotonic + m->idle_action_usec &&
1344 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1345 log_info("System idle. Taking action.");
1347 manager_handle_action(m, 0, m->idle_action, false, false);
1348 m->idle_action_not_before_usec = n;
1351 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1354 if (m->idle_action_fd < 0) {
1355 struct epoll_event ev = {
1357 .data.u32 = FD_IDLE_ACTION,
1360 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1361 if (m->idle_action_fd < 0) {
1362 log_error("Failed to create idle action timer: %m");
1367 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1368 log_error("Failed to add idle action timer to epoll: %m");
1374 if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1375 log_error("Failed to reset timerfd: %m");
1383 if (m->idle_action_fd >= 0) {
1384 close_nointr_nofail(m->idle_action_fd);
1385 m->idle_action_fd = -1;
1390 int manager_startup(Manager *m) {
1395 Inhibitor *inhibitor;
1399 assert(m->epoll_fd <= 0);
1401 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1402 if (m->epoll_fd < 0)
1405 /* Connect to console */
1406 r = manager_connect_console(m);
1410 /* Connect to udev */
1411 r = manager_connect_udev(m);
1415 /* Connect to the bus */
1416 r = manager_connect_bus(m);
1420 /* Instantiate magic seat 0 */
1421 r = manager_add_seat(m, "seat0", &m->vtconsole);
1425 /* Deserialize state */
1426 manager_enumerate_devices(m);
1427 manager_enumerate_seats(m);
1428 manager_enumerate_users(m);
1429 manager_enumerate_sessions(m);
1430 manager_enumerate_inhibitors(m);
1431 manager_enumerate_buttons(m);
1433 /* Remove stale objects before we start them */
1434 manager_gc(m, false);
1436 /* Reserve the special reserved VT */
1437 manager_reserve_vt(m);
1439 /* And start everything */
1440 HASHMAP_FOREACH(seat, m->seats, i)
1443 HASHMAP_FOREACH(user, m->users, i)
1446 HASHMAP_FOREACH(session, m->sessions, i)
1447 session_start(session);
1449 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1450 inhibitor_start(inhibitor);
1452 manager_dispatch_idle_action(m);
1457 static int manager_recheck_buttons(Manager *m) {
1464 HASHMAP_FOREACH(b, m->buttons, i) {
1467 q = button_recheck(b);
1477 int manager_run(Manager *m) {
1481 struct epoll_event event;
1485 manager_gc(m, true);
1487 if (manager_dispatch_delayed(m) > 0)
1490 if (manager_recheck_buttons(m) > 0)
1493 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1496 manager_gc(m, true);
1498 if (m->action_what != 0 && !m->action_job) {
1501 x = now(CLOCK_MONOTONIC);
1502 y = m->action_timestamp + m->inhibit_delay_max;
1504 msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1507 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1509 if (errno == EINTR || errno == EAGAIN)
1512 log_error("epoll() failed: %m");
1519 switch (event.data.u32) {
1522 manager_dispatch_seat_udev(m);
1526 manager_dispatch_vcsa_udev(m);
1529 case FD_BUTTON_UDEV:
1530 manager_dispatch_button_udev(m);
1534 manager_dispatch_console(m);
1537 case FD_IDLE_ACTION:
1538 manager_dispatch_idle_action(m);
1542 bus_loop_dispatch(m->bus_fd);
1546 if (event.data.u32 >= FD_OTHER_BASE)
1547 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1554 static int manager_parse_config_file(Manager *m) {
1555 static const char fn[] = "/etc/systemd/logind.conf";
1556 _cleanup_fclose_ FILE *f = NULL;
1561 f = fopen(fn, "re");
1563 if (errno == ENOENT)
1566 log_warning("Failed to open configuration file %s: %m", fn);
1570 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1571 (void*) logind_gperf_lookup, false, false, m);
1573 log_warning("Failed to parse configuration file: %s", strerror(-r));
1578 int main(int argc, char *argv[]) {
1582 log_set_target(LOG_TARGET_AUTO);
1583 log_set_facility(LOG_AUTH);
1584 log_parse_environment();
1590 log_error("This program takes no arguments.");
1595 /* Always create the directories people can create inotify
1596 * watches in. Note that some applications might check for the
1597 * existence of /run/systemd/seats/ to determine whether
1598 * logind is available, so please always make sure this check
1600 mkdir_label("/run/systemd/seats", 0755);
1601 mkdir_label("/run/systemd/users", 0755);
1602 mkdir_label("/run/systemd/sessions", 0755);
1610 manager_parse_config_file(m);
1612 r = manager_startup(m);
1614 log_error("Failed to fully start up daemon: %s", strerror(-r));
1618 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1622 "STATUS=Processing requests...");
1626 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1630 "STATUS=Shutting down...");
1635 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;