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 "sd-daemon.h"
30 #include "conf-parser.h"
32 #include "bus-error.h"
34 #include "udev-util.h"
36 Manager *manager_new(void) {
44 m->console_active_fd = -1;
45 m->reserve_vt_fd = -1;
50 m->inhibit_delay_max = 5 * USEC_PER_SEC;
51 m->handle_power_key = HANDLE_POWEROFF;
52 m->handle_suspend_key = HANDLE_SUSPEND;
53 m->handle_hibernate_key = HANDLE_HIBERNATE;
54 m->handle_lid_switch = HANDLE_SUSPEND;
55 m->handle_lid_switch_docked = HANDLE_IGNORE;
56 m->lid_switch_ignore_inhibited = true;
58 m->idle_action_usec = 30 * USEC_PER_MINUTE;
59 m->idle_action = HANDLE_IGNORE;
60 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
62 m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
64 m->devices = hashmap_new(&string_hash_ops);
65 m->seats = hashmap_new(&string_hash_ops);
66 m->sessions = hashmap_new(&string_hash_ops);
67 m->users = hashmap_new(NULL);
68 m->inhibitors = hashmap_new(&string_hash_ops);
69 m->buttons = hashmap_new(&string_hash_ops);
71 m->user_units = hashmap_new(&string_hash_ops);
72 m->session_units = hashmap_new(&string_hash_ops);
74 m->busnames = set_new(&string_hash_ops);
76 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
77 !m->user_units || !m->session_units)
80 m->kill_exclude_users = strv_new("root", NULL);
81 if (!m->kill_exclude_users)
88 r = sd_event_default(&m->event);
92 sd_event_set_watchdog(m->event, true);
101 void manager_free(Manager *m) {
111 while ((session = hashmap_first(m->sessions)))
112 session_free(session);
114 while ((u = hashmap_first(m->users)))
117 while ((d = hashmap_first(m->devices)))
120 while ((s = hashmap_first(m->seats)))
123 while ((i = hashmap_first(m->inhibitors)))
126 while ((b = hashmap_first(m->buttons)))
129 hashmap_free(m->devices);
130 hashmap_free(m->seats);
131 hashmap_free(m->sessions);
132 hashmap_free(m->users);
133 hashmap_free(m->inhibitors);
134 hashmap_free(m->buttons);
136 hashmap_free(m->user_units);
137 hashmap_free(m->session_units);
139 set_free_free(m->busnames);
141 sd_event_source_unref(m->idle_action_event_source);
143 sd_event_source_unref(m->console_active_event_source);
144 sd_event_source_unref(m->udev_seat_event_source);
145 sd_event_source_unref(m->udev_device_event_source);
146 sd_event_source_unref(m->udev_vcsa_event_source);
147 sd_event_source_unref(m->udev_button_event_source);
148 sd_event_source_unref(m->lid_switch_ignore_event_source);
150 safe_close(m->console_active_fd);
152 if (m->udev_seat_monitor)
153 udev_monitor_unref(m->udev_seat_monitor);
154 if (m->udev_device_monitor)
155 udev_monitor_unref(m->udev_device_monitor);
156 if (m->udev_vcsa_monitor)
157 udev_monitor_unref(m->udev_vcsa_monitor);
158 if (m->udev_button_monitor)
159 udev_monitor_unref(m->udev_button_monitor);
164 bus_verify_polkit_async_registry_free(m->polkit_registry);
166 sd_bus_unref(m->bus);
167 sd_event_unref(m->event);
169 safe_close(m->reserve_vt_fd);
171 strv_free(m->kill_only_users);
172 strv_free(m->kill_exclude_users);
178 static int manager_enumerate_devices(Manager *m) {
179 struct udev_list_entry *item = NULL, *first = NULL;
180 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
185 /* Loads devices from udev and creates seats for them as
188 e = udev_enumerate_new(m->udev);
192 r = udev_enumerate_add_match_tag(e, "master-of-seat");
196 r = udev_enumerate_add_match_is_initialized(e);
200 r = udev_enumerate_scan_devices(e);
204 first = udev_enumerate_get_list_entry(e);
205 udev_list_entry_foreach(item, first) {
206 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
209 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
213 k = manager_process_seat_device(m, d);
221 static int manager_enumerate_buttons(Manager *m) {
222 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
223 struct udev_list_entry *item = NULL, *first = NULL;
228 /* Loads buttons from udev */
230 if (m->handle_power_key == HANDLE_IGNORE &&
231 m->handle_suspend_key == HANDLE_IGNORE &&
232 m->handle_hibernate_key == HANDLE_IGNORE &&
233 m->handle_lid_switch == HANDLE_IGNORE &&
234 m->handle_lid_switch_docked == HANDLE_IGNORE)
237 e = udev_enumerate_new(m->udev);
241 r = udev_enumerate_add_match_subsystem(e, "input");
245 r = udev_enumerate_add_match_tag(e, "power-switch");
249 r = udev_enumerate_add_match_is_initialized(e);
253 r = udev_enumerate_scan_devices(e);
257 first = udev_enumerate_get_list_entry(e);
258 udev_list_entry_foreach(item, first) {
259 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
262 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
266 k = manager_process_button_device(m, d);
274 static int manager_enumerate_seats(Manager *m) {
275 _cleanup_closedir_ DIR *d = NULL;
281 /* This loads data about seats stored on disk, but does not
282 * actually create any seats. Removes data of seats that no
285 d = opendir("/run/systemd/seats");
290 log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
294 FOREACH_DIRENT(de, d, return -errno) {
298 if (!dirent_is_file(de))
301 s = hashmap_get(m->seats, de->d_name);
303 unlinkat(dirfd(d), de->d_name, 0);
315 static int manager_enumerate_linger_users(Manager *m) {
316 _cleanup_closedir_ DIR *d = NULL;
322 d = opendir("/var/lib/systemd/linger");
327 log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
331 FOREACH_DIRENT(de, d, return -errno) {
334 if (!dirent_is_file(de))
337 k = manager_add_user_by_name(m, de->d_name, NULL);
339 log_notice_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
347 static int manager_enumerate_users(Manager *m) {
348 _cleanup_closedir_ DIR *d = NULL;
354 /* Add lingering users */
355 r = manager_enumerate_linger_users(m);
357 /* Read in user data stored on disk */
358 d = opendir("/run/systemd/users");
363 log_error_errno(errno, "Failed to open /run/systemd/users: %m");
367 FOREACH_DIRENT(de, d, return -errno) {
370 if (!dirent_is_file(de))
373 k = manager_add_user_by_name(m, de->d_name, &u);
375 log_error_errno(k, "Failed to add user by file name %s: %m", de->d_name);
381 user_add_to_gc_queue(u);
391 static int manager_enumerate_sessions(Manager *m) {
392 _cleanup_closedir_ DIR *d = NULL;
398 /* Read in session data stored on disk */
399 d = opendir("/run/systemd/sessions");
404 log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
408 FOREACH_DIRENT(de, d, return -errno) {
412 if (!dirent_is_file(de))
415 if (!session_id_valid(de->d_name)) {
416 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
421 k = manager_add_session(m, de->d_name, &s);
423 log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
429 session_add_to_gc_queue(s);
439 static int manager_enumerate_inhibitors(Manager *m) {
440 _cleanup_closedir_ DIR *d = NULL;
446 d = opendir("/run/systemd/inhibit");
451 log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
455 FOREACH_DIRENT(de, d, return -errno) {
459 if (!dirent_is_file(de))
462 k = manager_add_inhibitor(m, de->d_name, &i);
464 log_notice_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
469 k = inhibitor_load(i);
477 static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
478 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
479 Manager *m = userdata;
483 d = udev_monitor_receive_device(m->udev_seat_monitor);
487 manager_process_seat_device(m, d);
491 static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
492 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
493 Manager *m = userdata;
497 d = udev_monitor_receive_device(m->udev_device_monitor);
501 manager_process_seat_device(m, d);
505 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
506 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
507 Manager *m = userdata;
512 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
516 name = udev_device_get_sysname(d);
518 /* Whenever a VCSA device is removed try to reallocate our
519 * VTs, to make sure our auto VTs never go away. */
521 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
522 seat_preallocate_vts(m->seat0);
527 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
528 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
529 Manager *m = userdata;
533 d = udev_monitor_receive_device(m->udev_button_monitor);
537 manager_process_button_device(m, d);
541 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
542 Manager *m = userdata;
546 assert(m->console_active_fd == fd);
548 seat_read_active_vt(m->seat0);
552 static int manager_reserve_vt(Manager *m) {
553 _cleanup_free_ char *p = NULL;
557 if (m->reserve_vt <= 0)
560 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
563 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
564 if (m->reserve_vt_fd < 0) {
566 /* Don't complain on VT-less systems */
568 log_warning_errno(errno, "Failed to pin reserved VT: %m");
575 static int manager_connect_bus(Manager *m) {
576 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
582 r = sd_bus_default_system(&m->bus);
584 return log_error_errno(r, "Failed to connect to system bus: %m");
586 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
588 return log_error_errno(r, "Failed to add manager object vtable: %m");
590 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
592 return log_error_errno(r, "Failed to add seat object vtable: %m");
594 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
596 return log_error_errno(r, "Failed to add seat enumerator: %m");
598 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
600 return log_error_errno(r, "Failed to add session object vtable: %m");
602 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
604 return log_error_errno(r, "Failed to add session enumerator: %m");
606 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
608 return log_error_errno(r, "Failed to add user object vtable: %m");
610 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
612 return log_error_errno(r, "Failed to add user enumerator: %m");
614 r = sd_bus_add_match(m->bus,
617 "sender='org.freedesktop.DBus',"
618 "interface='org.freedesktop.DBus',"
619 "member='NameOwnerChanged',"
620 "path='/org/freedesktop/DBus'",
621 match_name_owner_changed, m);
623 return log_error_errno(r, "Failed to add match for NameOwnerChanged: %m");
625 r = sd_bus_add_match(m->bus,
628 "sender='org.freedesktop.systemd1',"
629 "interface='org.freedesktop.systemd1.Manager',"
630 "member='JobRemoved',"
631 "path='/org/freedesktop/systemd1'",
632 match_job_removed, m);
634 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
636 r = sd_bus_add_match(m->bus,
639 "sender='org.freedesktop.systemd1',"
640 "interface='org.freedesktop.systemd1.Manager',"
641 "member='UnitRemoved',"
642 "path='/org/freedesktop/systemd1'",
643 match_unit_removed, m);
645 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
647 r = sd_bus_add_match(m->bus,
650 "sender='org.freedesktop.systemd1',"
651 "interface='org.freedesktop.DBus.Properties',"
652 "member='PropertiesChanged'",
653 match_properties_changed, m);
655 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
657 r = sd_bus_add_match(m->bus,
660 "sender='org.freedesktop.systemd1',"
661 "interface='org.freedesktop.systemd1.Manager',"
662 "member='Reloading',"
663 "path='/org/freedesktop/systemd1'",
666 return log_error_errno(r, "Failed to add match for Reloading: %m");
668 r = sd_bus_call_method(
670 "org.freedesktop.systemd1",
671 "/org/freedesktop/systemd1",
672 "org.freedesktop.systemd1.Manager",
677 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
681 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
683 return log_error_errno(r, "Failed to register name: %m");
685 r = sd_bus_attach_event(m->bus, m->event, 0);
687 return log_error_errno(r, "Failed to attach bus to event loop: %m");
692 static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
694 Session *active, *iter;
697 * We got a VT-switch signal and we have to acknowledge it immediately.
698 * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
699 * old user-space might run multiple sessions on a single VT, *sigh*.
700 * Therefore, we have to iterate all sessions and find one with a vtfd
701 * on the requested VT.
702 * As only VTs with active controllers have VT_PROCESS set, our current
703 * notion of the active VT might be wrong (for instance if the switch
704 * happens while we setup VT_PROCESS). Therefore, read the current VT
705 * first and then use s->active->vtnr as reference. Note that this is
706 * not racy, as no further VT-switch can happen as long as we're in
707 * synchronous VT_PROCESS mode.
711 seat_read_active_vt(m->seat0);
713 active = m->seat0->active;
714 if (!active || active->vtnr < 1) {
715 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
719 if (active->vtfd >= 0) {
720 session_leave_vt(active);
722 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
723 if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
724 session_leave_vt(iter);
733 static int manager_connect_console(Manager *m) {
737 assert(m->console_active_fd < 0);
739 /* On certain architectures (S390 and Xen, and containers),
740 /dev/tty0 does not exist, so don't fail if we can't open
742 if (access("/dev/tty0", F_OK) < 0)
745 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
746 if (m->console_active_fd < 0) {
748 /* On some systems the device node /dev/tty0 may exist
749 * even though /sys/class/tty/tty0 does not. */
753 log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
757 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
759 log_error("Failed to watch foreground console");
764 * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
765 * as VT-acquire signal. We ignore any acquire-events (yes, we still
766 * have to provide a valid signal-number for it!) and acknowledge all
767 * release events immediately.
770 if (SIGRTMIN + 1 > SIGRTMAX) {
771 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
775 r = ignore_signals(SIGRTMIN + 1, -1);
777 return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m");
779 r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
781 return log_error_errno(r, "Cannot block SIGRTMIN: %m");
783 r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
790 static int manager_connect_udev(Manager *m) {
794 assert(!m->udev_seat_monitor);
795 assert(!m->udev_device_monitor);
796 assert(!m->udev_vcsa_monitor);
797 assert(!m->udev_button_monitor);
799 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
800 if (!m->udev_seat_monitor)
803 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
807 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
811 r = sd_event_add_io(m->event, &m->udev_seat_event_source, udev_monitor_get_fd(m->udev_seat_monitor), EPOLLIN, manager_dispatch_seat_udev, m);
815 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
816 if (!m->udev_device_monitor)
819 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
823 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
827 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
831 r = udev_monitor_enable_receiving(m->udev_device_monitor);
835 r = sd_event_add_io(m->event, &m->udev_device_event_source, udev_monitor_get_fd(m->udev_device_monitor), EPOLLIN, manager_dispatch_device_udev, m);
839 /* Don't watch keys if nobody cares */
840 if (m->handle_power_key != HANDLE_IGNORE ||
841 m->handle_suspend_key != HANDLE_IGNORE ||
842 m->handle_hibernate_key != HANDLE_IGNORE ||
843 m->handle_lid_switch != HANDLE_IGNORE ||
844 m->handle_lid_switch_docked != HANDLE_IGNORE) {
846 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
847 if (!m->udev_button_monitor)
850 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
854 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
858 r = udev_monitor_enable_receiving(m->udev_button_monitor);
862 r = sd_event_add_io(m->event, &m->udev_button_event_source, udev_monitor_get_fd(m->udev_button_monitor), EPOLLIN, manager_dispatch_button_udev, m);
867 /* Don't bother watching VCSA devices, if nobody cares */
868 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
870 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
871 if (!m->udev_vcsa_monitor)
874 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
878 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
882 r = sd_event_add_io(m->event, &m->udev_vcsa_event_source, udev_monitor_get_fd(m->udev_vcsa_monitor), EPOLLIN, manager_dispatch_vcsa_udev, m);
890 void manager_gc(Manager *m, bool drop_not_started) {
897 while ((seat = m->seat_gc_queue)) {
898 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
899 seat->in_gc_queue = false;
901 if (!seat_check_gc(seat, drop_not_started)) {
902 seat_stop(seat, false);
907 while ((session = m->session_gc_queue)) {
908 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
909 session->in_gc_queue = false;
911 /* First, if we are not closing yet, initiate stopping */
912 if (!session_check_gc(session, drop_not_started) &&
913 session_get_state(session) != SESSION_CLOSING)
914 session_stop(session, false);
916 /* Normally, this should make the session busy again,
917 * if it doesn't then let's get rid of it
919 if (!session_check_gc(session, drop_not_started)) {
920 session_finalize(session);
921 session_free(session);
925 while ((user = m->user_gc_queue)) {
926 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
927 user->in_gc_queue = false;
929 /* First step: queue stop jobs */
930 if (!user_check_gc(user, drop_not_started))
931 user_stop(user, false);
933 /* Second step: finalize user */
934 if (!user_check_gc(user, drop_not_started)) {
941 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
942 Manager *m = userdata;
943 struct dual_timestamp since;
949 if (m->idle_action == HANDLE_IGNORE ||
950 m->idle_action_usec <= 0)
953 n = now(CLOCK_MONOTONIC);
955 r = manager_get_idle_hint(m, &since);
957 /* Not idle. Let's check if after a timeout it might be idle then. */
958 elapse = n + m->idle_action_usec;
960 /* Idle! Let's see if it's time to do something, or if
961 * we shall sleep for longer. */
963 if (n >= since.monotonic + m->idle_action_usec &&
964 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
965 log_info("System idle. Taking action.");
967 manager_handle_action(m, 0, m->idle_action, false, false);
968 m->idle_action_not_before_usec = n;
971 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
974 if (!m->idle_action_event_source) {
976 r = sd_event_add_time(
978 &m->idle_action_event_source,
980 elapse, USEC_PER_SEC*30,
981 manager_dispatch_idle_action, m);
983 return log_error_errno(r, "Failed to add idle event source: %m");
985 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
987 return log_error_errno(r, "Failed to set idle event source priority: %m");
989 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
991 return log_error_errno(r, "Failed to set idle event timer: %m");
993 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
995 return log_error_errno(r, "Failed to enable idle event timer: %m");
1001 int manager_startup(Manager *m) {
1007 Inhibitor *inhibitor;
1012 /* Connect to console */
1013 r = manager_connect_console(m);
1017 /* Connect to udev */
1018 r = manager_connect_udev(m);
1020 return log_error_errno(r, "Failed to create udev watchers: %m");
1022 /* Connect to the bus */
1023 r = manager_connect_bus(m);
1027 /* Instantiate magic seat 0 */
1028 r = manager_add_seat(m, "seat0", &m->seat0);
1030 return log_error_errno(r, "Failed to add seat0: %m");
1032 r = manager_set_lid_switch_ignore(m, 0 + IGNORE_LID_SWITCH_STARTUP_USEC);
1034 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
1036 /* Deserialize state */
1037 r = manager_enumerate_devices(m);
1039 log_warning_errno(r, "Device enumeration failed: %m");
1041 r = manager_enumerate_seats(m);
1043 log_warning_errno(r, "Seat enumeration failed: %m");
1045 r = manager_enumerate_users(m);
1047 log_warning_errno(r, "User enumeration failed: %m");
1049 r = manager_enumerate_sessions(m);
1051 log_warning_errno(r, "Session enumeration failed: %m");
1053 r = manager_enumerate_inhibitors(m);
1055 log_warning_errno(r, "Inhibitor enumeration failed: %m");
1057 r = manager_enumerate_buttons(m);
1059 log_warning_errno(r, "Button enumeration failed: %m");
1061 /* Remove stale objects before we start them */
1062 manager_gc(m, false);
1064 /* Reserve the special reserved VT */
1065 manager_reserve_vt(m);
1067 /* And start everything */
1068 HASHMAP_FOREACH(seat, m->seats, i)
1071 HASHMAP_FOREACH(user, m->users, i)
1074 HASHMAP_FOREACH(session, m->sessions, i)
1075 session_start(session);
1077 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1078 inhibitor_start(inhibitor);
1080 HASHMAP_FOREACH(button, m->buttons, i)
1081 button_check_switches(button);
1083 manager_dispatch_idle_action(NULL, 0, m);
1088 int manager_run(Manager *m) {
1094 usec_t us = (uint64_t) -1;
1096 r = sd_event_get_state(m->event);
1099 if (r == SD_EVENT_FINISHED)
1102 manager_gc(m, true);
1104 if (manager_dispatch_delayed(m) > 0)
1107 if (m->action_what != 0 && !m->action_job) {
1110 x = now(CLOCK_MONOTONIC);
1111 y = m->action_timestamp + m->inhibit_delay_max;
1113 us = x >= y ? 0 : y - x;
1116 r = sd_event_run(m->event, us);
1122 static int manager_parse_config_file(Manager *m) {
1125 return config_parse_many("/etc/systemd/logind.conf",
1126 CONF_DIRS_NULSTR("systemd/logind.conf"),
1128 config_item_perf_lookup, logind_gperf_lookup,
1132 int main(int argc, char *argv[]) {
1136 log_set_target(LOG_TARGET_AUTO);
1137 log_set_facility(LOG_AUTH);
1138 log_parse_environment();
1144 log_error("This program takes no arguments.");
1149 /* Always create the directories people can create inotify
1150 * watches in. Note that some applications might check for the
1151 * existence of /run/systemd/seats/ to determine whether
1152 * logind is available, so please always make sure this check
1154 mkdir_label("/run/systemd/seats", 0755);
1155 mkdir_label("/run/systemd/users", 0755);
1156 mkdir_label("/run/systemd/sessions", 0755);
1164 manager_parse_config_file(m);
1166 r = manager_startup(m);
1168 log_error_errno(r, "Failed to fully start up daemon: %m");
1172 log_debug("systemd-logind running as pid "PID_FMT, getpid());
1176 "STATUS=Processing requests...");
1180 log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
1185 "STATUS=Shutting down...");
1190 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;