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>
32 #include <systemd/sd-daemon.h>
35 #include "dbus-common.h"
36 #include "dbus-loop.h"
38 #include "conf-parser.h"
40 Manager *manager_new(void) {
47 m->console_active_fd = -1;
51 m->udev_button_fd = -1;
53 m->reserve_vt_fd = -1;
57 m->inhibit_delay_max = 5 * USEC_PER_SEC;
58 m->handle_power_key = HANDLE_NO_SESSION;
59 m->handle_sleep_key = HANDLE_TTY_SESSION;
60 m->handle_lid_switch = HANDLE_OFF;
62 m->devices = hashmap_new(string_hash_func, string_compare_func);
63 m->seats = hashmap_new(string_hash_func, string_compare_func);
64 m->sessions = hashmap_new(string_hash_func, string_compare_func);
65 m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
66 m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
67 m->buttons = hashmap_new(string_hash_func, string_compare_func);
69 m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
70 m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
72 m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
73 m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
74 m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
76 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
77 !m->user_cgroups || !m->session_cgroups ||
78 !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
83 m->reset_controllers = strv_new("cpu", NULL);
84 m->kill_exclude_users = strv_new("root", NULL);
85 if (!m->reset_controllers || !m->kill_exclude_users) {
96 if (cg_get_user_path(&m->cgroup_path) < 0) {
104 void manager_free(Manager *m) {
114 while ((session = hashmap_first(m->sessions)))
115 session_free(session);
117 while ((u = hashmap_first(m->users)))
120 while ((d = hashmap_first(m->devices)))
123 while ((s = hashmap_first(m->seats)))
126 while ((i = hashmap_first(m->inhibitors)))
129 while ((b = hashmap_first(m->buttons)))
132 hashmap_free(m->devices);
133 hashmap_free(m->seats);
134 hashmap_free(m->sessions);
135 hashmap_free(m->users);
136 hashmap_free(m->inhibitors);
137 hashmap_free(m->buttons);
139 hashmap_free(m->user_cgroups);
140 hashmap_free(m->session_cgroups);
142 hashmap_free(m->session_fds);
143 hashmap_free(m->inhibitor_fds);
144 hashmap_free(m->button_fds);
146 if (m->console_active_fd >= 0)
147 close_nointr_nofail(m->console_active_fd);
149 if (m->udev_seat_monitor)
150 udev_monitor_unref(m->udev_seat_monitor);
151 if (m->udev_vcsa_monitor)
152 udev_monitor_unref(m->udev_vcsa_monitor);
153 if (m->udev_button_monitor)
154 udev_monitor_unref(m->udev_button_monitor);
160 dbus_connection_flush(m->bus);
161 dbus_connection_close(m->bus);
162 dbus_connection_unref(m->bus);
166 close_nointr_nofail(m->bus_fd);
168 if (m->epoll_fd >= 0)
169 close_nointr_nofail(m->epoll_fd);
171 if (m->reserve_vt_fd >= 0)
172 close_nointr_nofail(m->reserve_vt_fd);
174 strv_free(m->controllers);
175 strv_free(m->reset_controllers);
176 strv_free(m->kill_only_users);
177 strv_free(m->kill_exclude_users);
179 free(m->cgroup_path);
183 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
189 d = hashmap_get(m->devices, sysfs);
197 d = device_new(m, sysfs);
207 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
213 s = hashmap_get(m->seats, id);
231 int manager_add_session(Manager *m, User *u, const char *id, Session **_session) {
237 s = hashmap_get(m->sessions, id);
245 s = session_new(m, u, id);
255 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
261 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
269 u = user_new(m, uid, gid, name);
279 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
287 r = get_user_creds(&name, &uid, &gid, NULL, NULL);
291 return manager_add_user(m, uid, gid, name, _user);
294 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
302 return errno ? -errno : -ENOENT;
304 return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
307 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
313 i = hashmap_get(m->inhibitors, id);
321 i = inhibitor_new(m, id);
331 int manager_add_button(Manager *m, const char *name, Button **_button) {
337 b = hashmap_get(m->buttons, name);
345 b = button_new(m, name);
355 int manager_process_seat_device(Manager *m, struct udev_device *d) {
361 if (streq_ptr(udev_device_get_action(d), "remove")) {
363 device = hashmap_get(m->devices, udev_device_get_syspath(d));
367 seat_add_to_gc_queue(device->seat);
374 sn = udev_device_get_property_value(d, "ID_SEAT");
378 if (!seat_name_is_valid(sn)) {
379 log_warning("Device with invalid seat name %s found, ignoring.", sn);
383 r = manager_add_device(m, udev_device_get_syspath(d), &device);
387 r = manager_add_seat(m, sn, &seat);
395 device_attach(device, seat);
402 int manager_process_button_device(Manager *m, struct udev_device *d) {
409 if (streq_ptr(udev_device_get_action(d), "remove")) {
411 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
420 r = manager_add_button(m, udev_device_get_sysname(d), &b);
424 sn = udev_device_get_property_value(d, "ID_SEAT");
428 button_set_seat(b, sn);
435 int manager_enumerate_devices(Manager *m) {
436 struct udev_list_entry *item = NULL, *first = NULL;
437 struct udev_enumerate *e;
442 /* Loads devices from udev and creates seats for them as
445 e = udev_enumerate_new(m->udev);
451 r = udev_enumerate_add_match_subsystem(e, "graphics");
455 r = udev_enumerate_add_match_tag(e, "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_OFF &&
498 m->handle_sleep_key == HANDLE_OFF &&
499 m->handle_lid_switch == HANDLE_OFF)
502 e = udev_enumerate_new(m->udev);
508 r = udev_enumerate_add_match_subsystem(e, "input");
512 r = udev_enumerate_add_match_tag(e, "power-switch");
516 r = udev_enumerate_scan_devices(e);
520 first = udev_enumerate_get_list_entry(e);
521 udev_list_entry_foreach(item, first) {
522 struct udev_device *d;
525 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
531 k = manager_process_button_device(m, d);
532 udev_device_unref(d);
540 udev_enumerate_unref(e);
545 int manager_enumerate_seats(Manager *m) {
552 /* This loads data about seats stored on disk, but does not
553 * actually create any seats. Removes data of seats that no
556 d = opendir("/run/systemd/seats");
561 log_error("Failed to open /run/systemd/seats: %m");
565 while ((de = readdir(d))) {
569 if (!dirent_is_file(de))
572 s = hashmap_get(m->seats, de->d_name);
574 unlinkat(dirfd(d), de->d_name, 0);
588 static int manager_enumerate_users_from_cgroup(Manager *m) {
593 r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
598 log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
602 while ((k = cg_read_subgroup(d, &name)) > 0) {
605 k = manager_add_user_by_name(m, name, &user);
612 user_add_to_gc_queue(user);
614 if (!user->cgroup_path)
615 if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) {
632 static int manager_enumerate_linger_users(Manager *m) {
637 d = opendir("/var/lib/systemd/linger");
642 log_error("Failed to open /var/lib/systemd/linger/: %m");
646 while ((de = readdir(d))) {
649 if (!dirent_is_file(de))
652 k = manager_add_user_by_name(m, de->d_name, NULL);
654 log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
664 int manager_enumerate_users(Manager *m) {
671 /* First, enumerate user cgroups */
672 r = manager_enumerate_users_from_cgroup(m);
674 /* Second, add lingering users on top */
675 k = manager_enumerate_linger_users(m);
679 /* Third, read in user data stored on disk */
680 d = opendir("/run/systemd/users");
685 log_error("Failed to open /run/systemd/users: %m");
689 while ((de = readdir(d))) {
693 if (!dirent_is_file(de))
696 k = parse_uid(de->d_name, &uid);
698 log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
702 u = hashmap_get(m->users, ULONG_TO_PTR(uid));
704 unlinkat(dirfd(d), de->d_name, 0);
718 static int manager_enumerate_sessions_from_cgroup(Manager *m) {
723 HASHMAP_FOREACH(u, m->users, i) {
731 k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
736 log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
741 while ((k = cg_read_subgroup(d, &name)) > 0) {
744 if (streq(name, "shared"))
747 k = manager_add_session(m, u, name, &session);
753 session_add_to_gc_queue(session);
755 if (!session->cgroup_path)
756 if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) {
774 int manager_enumerate_sessions(Manager *m) {
781 /* First enumerate session cgroups */
782 r = manager_enumerate_sessions_from_cgroup(m);
784 /* Second, read in session data stored on disk */
785 d = opendir("/run/systemd/sessions");
790 log_error("Failed to open /run/systemd/sessions: %m");
794 while ((de = readdir(d))) {
798 if (!dirent_is_file(de))
801 s = hashmap_get(m->sessions, de->d_name);
803 unlinkat(dirfd(d), de->d_name, 0);
817 int manager_enumerate_inhibitors(Manager *m) {
824 d = opendir("/run/systemd/inhibit");
829 log_error("Failed to open /run/systemd/inhibit: %m");
833 while ((de = readdir(d))) {
837 if (!dirent_is_file(de))
840 k = manager_add_inhibitor(m, de->d_name, &i);
842 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
847 k = inhibitor_load(i);
857 int manager_dispatch_seat_udev(Manager *m) {
858 struct udev_device *d;
863 d = udev_monitor_receive_device(m->udev_seat_monitor);
867 r = manager_process_seat_device(m, d);
868 udev_device_unref(d);
873 int manager_dispatch_vcsa_udev(Manager *m) {
874 struct udev_device *d;
880 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
884 name = udev_device_get_sysname(d);
886 /* Whenever a VCSA device is removed try to reallocate our
887 * VTs, to make sure our auto VTs never go away. */
889 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
890 r = seat_preallocate_vts(m->vtconsole);
892 udev_device_unref(d);
897 int manager_dispatch_button_udev(Manager *m) {
898 struct udev_device *d;
903 d = udev_monitor_receive_device(m->udev_button_monitor);
907 r = manager_process_button_device(m, d);
908 udev_device_unref(d);
913 int manager_dispatch_console(Manager *m) {
917 seat_read_active_vt(m->vtconsole);
922 static int vt_is_busy(int vtnr) {
923 struct vt_stat vt_stat;
928 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
929 * we'd open the latter we'd open the foreground tty which
930 * hence would be unconditionally busy. By opening /dev/tty1
931 * we avoid this. Since tty1 is special and needs to be an
932 * explicitly loaded getty or DM this is safe. */
934 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
938 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
941 r = !!(vt_stat.v_state & (1 << vtnr));
943 close_nointr_nofail(fd);
948 int manager_spawn_autovt(Manager *m, int vtnr) {
951 const char *mode = "fail";
956 if ((unsigned) vtnr > m->n_autovts &&
957 (unsigned) vtnr != m->reserve_vt)
960 if ((unsigned) vtnr != m->reserve_vt) {
961 /* If this is the reserved TTY, we'll start the getty
962 * on it in any case, but otherwise only if it is not
965 r = vt_is_busy(vtnr);
972 if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
973 log_error("Could not allocate service name.");
978 r = bus_method_call_with_reply (
980 "org.freedesktop.systemd1",
981 "/org/freedesktop/systemd1",
982 "org.freedesktop.systemd1.Manager",
986 DBUS_TYPE_STRING, &name,
987 DBUS_TYPE_STRING, &mode,
996 static int manager_reserve_vt(Manager *m) {
997 _cleanup_free_ char *p = NULL;
1001 if (m->reserve_vt <= 0)
1004 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
1007 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
1008 if (m->reserve_vt_fd < 0) {
1009 log_warning("Failed to pin reserved VT: %m");
1016 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
1024 s = hashmap_get(m->session_cgroups, cgroup);
1037 e = strrchr(p, '/');
1046 s = hashmap_get(m->session_cgroups, p);
1055 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1063 u = hashmap_get(m->user_cgroups, cgroup);
1076 e = strrchr(p, '/');
1085 u = hashmap_get(m->user_cgroups, p);
1094 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1102 r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1106 r = manager_get_session_by_cgroup(m, p, session);
1112 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1117 r = manager_get_session_by_cgroup(m, cgroup, &s);
1119 session_add_to_gc_queue(s);
1121 r = manager_get_user_by_cgroup(m, cgroup, &u);
1123 user_add_to_gc_queue(u);
1126 static void manager_dispatch_other(Manager *m, int fd) {
1134 s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1136 assert(s->fifo_fd == fd);
1137 session_remove_fifo(s);
1142 i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1144 assert(i->fifo_fd == fd);
1150 b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1152 assert(b->fd == fd);
1157 assert_not_reached("Got event for unknown fd");
1160 static int manager_connect_bus(Manager *m) {
1163 struct epoll_event ev;
1167 assert(m->bus_fd < 0);
1169 dbus_error_init(&error);
1171 m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1173 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1178 if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1179 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1180 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1181 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1182 !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1187 dbus_bus_add_match(m->bus,
1189 "interface='org.freedesktop.systemd1.Agent',"
1190 "member='Released',"
1191 "path='/org/freedesktop/systemd1/agent'",
1194 if (dbus_error_is_set(&error)) {
1195 log_error("Failed to register match: %s", bus_error_message(&error));
1200 r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1201 if (dbus_error_is_set(&error)) {
1202 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1207 if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1208 log_error("Failed to acquire name.");
1213 m->bus_fd = bus_loop_open(m->bus);
1214 if (m->bus_fd < 0) {
1220 ev.events = EPOLLIN;
1221 ev.data.u32 = FD_BUS;
1223 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1229 dbus_error_free(&error);
1234 static int manager_connect_console(Manager *m) {
1235 struct epoll_event ev;
1238 assert(m->console_active_fd < 0);
1240 /* On certain architectures (S390 and Xen, and containers),
1241 /dev/tty0 does not exist, so don't fail if we can't open
1243 if (access("/dev/tty0", F_OK) < 0) {
1244 m->console_active_fd = -1;
1248 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1249 if (m->console_active_fd < 0) {
1251 /* On some systems the device node /dev/tty0 may exist
1252 * even though /sys/class/tty/tty0 does not. */
1253 if (errno == ENOENT)
1256 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1262 ev.data.u32 = FD_CONSOLE;
1264 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1270 static int manager_connect_udev(Manager *m) {
1271 struct epoll_event ev;
1275 assert(!m->udev_seat_monitor);
1276 assert(!m->udev_vcsa_monitor);
1277 assert(!m->udev_button_monitor);
1279 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1280 if (!m->udev_seat_monitor)
1283 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat");
1287 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL);
1291 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1295 m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1298 ev.events = EPOLLIN;
1299 ev.data.u32 = FD_SEAT_UDEV;
1300 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1303 /* Don't watch keys if nobody cares */
1304 if (m->handle_power_key != HANDLE_OFF ||
1305 m->handle_sleep_key != HANDLE_OFF ||
1306 m->handle_lid_switch != HANDLE_OFF) {
1308 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1309 if (!m->udev_button_monitor)
1312 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1316 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1320 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1324 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1327 ev.events = EPOLLIN;
1328 ev.data.u32 = FD_BUTTON_UDEV;
1329 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1333 /* Don't bother watching VCSA devices, if nobody cares */
1334 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1336 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1337 if (!m->udev_vcsa_monitor)
1340 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1344 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1348 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1351 ev.events = EPOLLIN;
1352 ev.data.u32 = FD_VCSA_UDEV;
1353 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1360 void manager_gc(Manager *m, bool drop_not_started) {
1367 while ((seat = m->seat_gc_queue)) {
1368 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1369 seat->in_gc_queue = false;
1371 if (seat_check_gc(seat, drop_not_started) == 0) {
1377 while ((session = m->session_gc_queue)) {
1378 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1379 session->in_gc_queue = false;
1381 if (session_check_gc(session, drop_not_started) == 0) {
1382 session_stop(session);
1383 session_free(session);
1387 while ((user = m->user_gc_queue)) {
1388 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1389 user->in_gc_queue = false;
1391 if (user_check_gc(user, drop_not_started) == 0) {
1398 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1401 dual_timestamp ts = { 0, 0 };
1406 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t);
1408 HASHMAP_FOREACH(s, m->sessions, i) {
1412 ih = session_get_idle_hint(s, &k);
1418 if (k.monotonic < ts.monotonic)
1424 } else if (idle_hint) {
1426 if (k.monotonic > ts.monotonic)
1437 int manager_startup(Manager *m) {
1442 Inhibitor *inhibitor;
1446 assert(m->epoll_fd <= 0);
1448 cg_shorten_controllers(m->reset_controllers);
1449 cg_shorten_controllers(m->controllers);
1451 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1452 if (m->epoll_fd < 0)
1455 /* Connect to console */
1456 r = manager_connect_console(m);
1460 /* Connect to udev */
1461 r = manager_connect_udev(m);
1465 /* Connect to the bus */
1466 r = manager_connect_bus(m);
1470 /* Instantiate magic seat 0 */
1471 r = manager_add_seat(m, "seat0", &m->vtconsole);
1475 /* Deserialize state */
1476 manager_enumerate_devices(m);
1477 manager_enumerate_seats(m);
1478 manager_enumerate_users(m);
1479 manager_enumerate_sessions(m);
1480 manager_enumerate_inhibitors(m);
1481 manager_enumerate_buttons(m);
1483 /* Remove stale objects before we start them */
1484 manager_gc(m, false);
1486 /* Reserve the special reserved VT */
1487 manager_reserve_vt(m);
1489 /* And start everything */
1490 HASHMAP_FOREACH(seat, m->seats, i)
1493 HASHMAP_FOREACH(user, m->users, i)
1496 HASHMAP_FOREACH(session, m->sessions, i)
1497 session_start(session);
1499 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1500 inhibitor_start(inhibitor);
1505 int manager_run(Manager *m) {
1509 struct epoll_event event;
1513 manager_gc(m, true);
1515 if (manager_dispatch_delayed(m) > 0)
1518 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1521 manager_gc(m, true);
1523 if (m->delayed_unit) {
1526 x = now(CLOCK_MONOTONIC);
1527 y = m->delayed_timestamp + m->inhibit_delay_max;
1529 msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1532 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1534 if (errno == EINTR || errno == EAGAIN)
1537 log_error("epoll() failed: %m");
1544 switch (event.data.u32) {
1547 manager_dispatch_seat_udev(m);
1551 manager_dispatch_vcsa_udev(m);
1554 case FD_BUTTON_UDEV:
1555 manager_dispatch_button_udev(m);
1559 manager_dispatch_console(m);
1563 bus_loop_dispatch(m->bus_fd);
1567 if (event.data.u32 >= FD_OTHER_BASE)
1568 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1575 static int manager_parse_config_file(Manager *m) {
1582 fn = "/etc/systemd/logind.conf";
1583 f = fopen(fn, "re");
1585 if (errno == ENOENT)
1588 log_warning("Failed to open configuration file %s: %m", fn);
1592 r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
1594 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.");
1624 manager_parse_config_file(m);
1626 r = manager_startup(m);
1628 log_error("Failed to fully start up daemon: %s", strerror(-r));
1632 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1636 "STATUS=Processing requests...");
1640 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1644 "STATUS=Shutting down...");
1649 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;