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;
57 m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
59 m->idle_action_usec = 30 * USEC_PER_MINUTE;
60 m->idle_action = HANDLE_IGNORE;
61 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
63 m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
65 m->devices = hashmap_new(&string_hash_ops);
66 m->seats = hashmap_new(&string_hash_ops);
67 m->sessions = hashmap_new(&string_hash_ops);
68 m->users = hashmap_new(NULL);
69 m->inhibitors = hashmap_new(&string_hash_ops);
70 m->buttons = hashmap_new(&string_hash_ops);
72 m->user_units = hashmap_new(&string_hash_ops);
73 m->session_units = hashmap_new(&string_hash_ops);
75 m->busnames = set_new(&string_hash_ops);
77 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
78 !m->user_units || !m->session_units)
81 m->kill_exclude_users = strv_new("root", NULL);
82 if (!m->kill_exclude_users)
89 r = sd_event_default(&m->event);
93 sd_event_set_watchdog(m->event, true);
102 void manager_free(Manager *m) {
112 while ((session = hashmap_first(m->sessions)))
113 session_free(session);
115 while ((u = hashmap_first(m->users)))
118 while ((d = hashmap_first(m->devices)))
121 while ((s = hashmap_first(m->seats)))
124 while ((i = hashmap_first(m->inhibitors)))
127 while ((b = hashmap_first(m->buttons)))
130 hashmap_free(m->devices);
131 hashmap_free(m->seats);
132 hashmap_free(m->sessions);
133 hashmap_free(m->users);
134 hashmap_free(m->inhibitors);
135 hashmap_free(m->buttons);
137 hashmap_free(m->user_units);
138 hashmap_free(m->session_units);
140 set_free_free(m->busnames);
142 sd_event_source_unref(m->idle_action_event_source);
144 sd_event_source_unref(m->console_active_event_source);
145 sd_event_source_unref(m->udev_seat_event_source);
146 sd_event_source_unref(m->udev_device_event_source);
147 sd_event_source_unref(m->udev_vcsa_event_source);
148 sd_event_source_unref(m->udev_button_event_source);
149 sd_event_source_unref(m->lid_switch_ignore_event_source);
151 safe_close(m->console_active_fd);
153 if (m->udev_seat_monitor)
154 udev_monitor_unref(m->udev_seat_monitor);
155 if (m->udev_device_monitor)
156 udev_monitor_unref(m->udev_device_monitor);
157 if (m->udev_vcsa_monitor)
158 udev_monitor_unref(m->udev_vcsa_monitor);
159 if (m->udev_button_monitor)
160 udev_monitor_unref(m->udev_button_monitor);
165 bus_verify_polkit_async_registry_free(m->polkit_registry);
167 sd_bus_unref(m->bus);
168 sd_event_unref(m->event);
170 safe_close(m->reserve_vt_fd);
172 strv_free(m->kill_only_users);
173 strv_free(m->kill_exclude_users);
179 static int manager_enumerate_devices(Manager *m) {
180 struct udev_list_entry *item = NULL, *first = NULL;
181 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
186 /* Loads devices from udev and creates seats for them as
189 e = udev_enumerate_new(m->udev);
193 r = udev_enumerate_add_match_tag(e, "master-of-seat");
197 r = udev_enumerate_add_match_is_initialized(e);
201 r = udev_enumerate_scan_devices(e);
205 first = udev_enumerate_get_list_entry(e);
206 udev_list_entry_foreach(item, first) {
207 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
210 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
214 k = manager_process_seat_device(m, d);
222 static int manager_enumerate_buttons(Manager *m) {
223 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
224 struct udev_list_entry *item = NULL, *first = NULL;
229 /* Loads buttons from udev */
231 if (m->handle_power_key == HANDLE_IGNORE &&
232 m->handle_suspend_key == HANDLE_IGNORE &&
233 m->handle_hibernate_key == HANDLE_IGNORE &&
234 m->handle_lid_switch == HANDLE_IGNORE &&
235 m->handle_lid_switch_docked == HANDLE_IGNORE)
238 e = udev_enumerate_new(m->udev);
242 r = udev_enumerate_add_match_subsystem(e, "input");
246 r = udev_enumerate_add_match_tag(e, "power-switch");
250 r = udev_enumerate_add_match_is_initialized(e);
254 r = udev_enumerate_scan_devices(e);
258 first = udev_enumerate_get_list_entry(e);
259 udev_list_entry_foreach(item, first) {
260 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
263 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
267 k = manager_process_button_device(m, d);
275 static int manager_enumerate_seats(Manager *m) {
276 _cleanup_closedir_ DIR *d = NULL;
282 /* This loads data about seats stored on disk, but does not
283 * actually create any seats. Removes data of seats that no
286 d = opendir("/run/systemd/seats");
291 log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
295 FOREACH_DIRENT(de, d, return -errno) {
299 if (!dirent_is_file(de))
302 s = hashmap_get(m->seats, de->d_name);
304 unlinkat(dirfd(d), de->d_name, 0);
316 static int manager_enumerate_linger_users(Manager *m) {
317 _cleanup_closedir_ DIR *d = NULL;
323 d = opendir("/var/lib/systemd/linger");
328 log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
332 FOREACH_DIRENT(de, d, return -errno) {
335 if (!dirent_is_file(de))
338 k = manager_add_user_by_name(m, de->d_name, NULL);
340 log_notice_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
348 static int manager_enumerate_users(Manager *m) {
349 _cleanup_closedir_ DIR *d = NULL;
355 /* Add lingering users */
356 r = manager_enumerate_linger_users(m);
358 /* Read in user data stored on disk */
359 d = opendir("/run/systemd/users");
364 log_error_errno(errno, "Failed to open /run/systemd/users: %m");
368 FOREACH_DIRENT(de, d, return -errno) {
371 if (!dirent_is_file(de))
374 k = manager_add_user_by_name(m, de->d_name, &u);
376 log_error_errno(k, "Failed to add user by file name %s: %m", de->d_name);
382 user_add_to_gc_queue(u);
392 static int manager_enumerate_sessions(Manager *m) {
393 _cleanup_closedir_ DIR *d = NULL;
399 /* Read in session data stored on disk */
400 d = opendir("/run/systemd/sessions");
405 log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
409 FOREACH_DIRENT(de, d, return -errno) {
413 if (!dirent_is_file(de))
416 if (!session_id_valid(de->d_name)) {
417 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
422 k = manager_add_session(m, de->d_name, &s);
424 log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
430 session_add_to_gc_queue(s);
440 static int manager_enumerate_inhibitors(Manager *m) {
441 _cleanup_closedir_ DIR *d = NULL;
447 d = opendir("/run/systemd/inhibit");
452 log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
456 FOREACH_DIRENT(de, d, return -errno) {
460 if (!dirent_is_file(de))
463 k = manager_add_inhibitor(m, de->d_name, &i);
465 log_notice_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
470 k = inhibitor_load(i);
478 static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
479 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
480 Manager *m = userdata;
484 d = udev_monitor_receive_device(m->udev_seat_monitor);
488 manager_process_seat_device(m, d);
492 static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
493 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
494 Manager *m = userdata;
498 d = udev_monitor_receive_device(m->udev_device_monitor);
502 manager_process_seat_device(m, d);
506 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
507 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
508 Manager *m = userdata;
513 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
517 name = udev_device_get_sysname(d);
519 /* Whenever a VCSA device is removed try to reallocate our
520 * VTs, to make sure our auto VTs never go away. */
522 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
523 seat_preallocate_vts(m->seat0);
528 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
529 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
530 Manager *m = userdata;
534 d = udev_monitor_receive_device(m->udev_button_monitor);
538 manager_process_button_device(m, d);
542 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
543 Manager *m = userdata;
547 assert(m->console_active_fd == fd);
549 seat_read_active_vt(m->seat0);
553 static int manager_reserve_vt(Manager *m) {
554 _cleanup_free_ char *p = NULL;
558 if (m->reserve_vt <= 0)
561 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
564 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
565 if (m->reserve_vt_fd < 0) {
567 /* Don't complain on VT-less systems */
569 log_warning_errno(errno, "Failed to pin reserved VT: %m");
576 static int manager_connect_bus(Manager *m) {
577 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
583 r = sd_bus_default_system(&m->bus);
585 return log_error_errno(r, "Failed to connect to system bus: %m");
587 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
589 return log_error_errno(r, "Failed to add manager object vtable: %m");
591 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
593 return log_error_errno(r, "Failed to add seat object vtable: %m");
595 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
597 return log_error_errno(r, "Failed to add seat enumerator: %m");
599 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
601 return log_error_errno(r, "Failed to add session object vtable: %m");
603 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
605 return log_error_errno(r, "Failed to add session enumerator: %m");
607 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
609 return log_error_errno(r, "Failed to add user object vtable: %m");
611 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
613 return log_error_errno(r, "Failed to add user enumerator: %m");
615 r = sd_bus_add_match(m->bus,
618 "sender='org.freedesktop.DBus',"
619 "interface='org.freedesktop.DBus',"
620 "member='NameOwnerChanged',"
621 "path='/org/freedesktop/DBus'",
622 match_name_owner_changed, m);
624 return log_error_errno(r, "Failed to add match for NameOwnerChanged: %m");
626 r = sd_bus_add_match(m->bus,
629 "sender='org.freedesktop.systemd1',"
630 "interface='org.freedesktop.systemd1.Manager',"
631 "member='JobRemoved',"
632 "path='/org/freedesktop/systemd1'",
633 match_job_removed, m);
635 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
637 r = sd_bus_add_match(m->bus,
640 "sender='org.freedesktop.systemd1',"
641 "interface='org.freedesktop.systemd1.Manager',"
642 "member='UnitRemoved',"
643 "path='/org/freedesktop/systemd1'",
644 match_unit_removed, m);
646 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
648 r = sd_bus_add_match(m->bus,
651 "sender='org.freedesktop.systemd1',"
652 "interface='org.freedesktop.DBus.Properties',"
653 "member='PropertiesChanged'",
654 match_properties_changed, m);
656 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
658 r = sd_bus_add_match(m->bus,
661 "sender='org.freedesktop.systemd1',"
662 "interface='org.freedesktop.systemd1.Manager',"
663 "member='Reloading',"
664 "path='/org/freedesktop/systemd1'",
667 return log_error_errno(r, "Failed to add match for Reloading: %m");
669 r = sd_bus_call_method(
671 "org.freedesktop.systemd1",
672 "/org/freedesktop/systemd1",
673 "org.freedesktop.systemd1.Manager",
678 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
682 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
684 return log_error_errno(r, "Failed to register name: %m");
686 r = sd_bus_attach_event(m->bus, m->event, 0);
688 return log_error_errno(r, "Failed to attach bus to event loop: %m");
693 static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
695 Session *active, *iter;
698 * We got a VT-switch signal and we have to acknowledge it immediately.
699 * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
700 * old user-space might run multiple sessions on a single VT, *sigh*.
701 * Therefore, we have to iterate all sessions and find one with a vtfd
702 * on the requested VT.
703 * As only VTs with active controllers have VT_PROCESS set, our current
704 * notion of the active VT might be wrong (for instance if the switch
705 * happens while we setup VT_PROCESS). Therefore, read the current VT
706 * first and then use s->active->vtnr as reference. Note that this is
707 * not racy, as no further VT-switch can happen as long as we're in
708 * synchronous VT_PROCESS mode.
712 seat_read_active_vt(m->seat0);
714 active = m->seat0->active;
715 if (!active || active->vtnr < 1) {
716 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
720 if (active->vtfd >= 0) {
721 session_leave_vt(active);
723 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
724 if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
725 session_leave_vt(iter);
734 static int manager_connect_console(Manager *m) {
738 assert(m->console_active_fd < 0);
740 /* On certain architectures (S390 and Xen, and containers),
741 /dev/tty0 does not exist, so don't fail if we can't open
743 if (access("/dev/tty0", F_OK) < 0)
746 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
747 if (m->console_active_fd < 0) {
749 /* On some systems the device node /dev/tty0 may exist
750 * even though /sys/class/tty/tty0 does not. */
754 log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
758 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
760 log_error("Failed to watch foreground console");
765 * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
766 * as VT-acquire signal. We ignore any acquire-events (yes, we still
767 * have to provide a valid signal-number for it!) and acknowledge all
768 * release events immediately.
771 if (SIGRTMIN + 1 > SIGRTMAX) {
772 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
776 r = ignore_signals(SIGRTMIN + 1, -1);
778 return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m");
780 r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
782 return log_error_errno(r, "Cannot block SIGRTMIN: %m");
784 r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
791 static int manager_connect_udev(Manager *m) {
795 assert(!m->udev_seat_monitor);
796 assert(!m->udev_device_monitor);
797 assert(!m->udev_vcsa_monitor);
798 assert(!m->udev_button_monitor);
800 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
801 if (!m->udev_seat_monitor)
804 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
808 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
812 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);
816 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
817 if (!m->udev_device_monitor)
820 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
824 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
828 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
832 r = udev_monitor_enable_receiving(m->udev_device_monitor);
836 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);
840 /* Don't watch keys if nobody cares */
841 if (m->handle_power_key != HANDLE_IGNORE ||
842 m->handle_suspend_key != HANDLE_IGNORE ||
843 m->handle_hibernate_key != HANDLE_IGNORE ||
844 m->handle_lid_switch != HANDLE_IGNORE ||
845 m->handle_lid_switch_docked != HANDLE_IGNORE) {
847 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
848 if (!m->udev_button_monitor)
851 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
855 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
859 r = udev_monitor_enable_receiving(m->udev_button_monitor);
863 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);
868 /* Don't bother watching VCSA devices, if nobody cares */
869 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
871 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
872 if (!m->udev_vcsa_monitor)
875 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
879 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
883 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);
891 void manager_gc(Manager *m, bool drop_not_started) {
898 while ((seat = m->seat_gc_queue)) {
899 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
900 seat->in_gc_queue = false;
902 if (!seat_check_gc(seat, drop_not_started)) {
903 seat_stop(seat, false);
908 while ((session = m->session_gc_queue)) {
909 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
910 session->in_gc_queue = false;
912 /* First, if we are not closing yet, initiate stopping */
913 if (!session_check_gc(session, drop_not_started) &&
914 session_get_state(session) != SESSION_CLOSING)
915 session_stop(session, false);
917 /* Normally, this should make the session busy again,
918 * if it doesn't then let's get rid of it
920 if (!session_check_gc(session, drop_not_started)) {
921 session_finalize(session);
922 session_free(session);
926 while ((user = m->user_gc_queue)) {
927 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
928 user->in_gc_queue = false;
930 /* First step: queue stop jobs */
931 if (!user_check_gc(user, drop_not_started))
932 user_stop(user, false);
934 /* Second step: finalize user */
935 if (!user_check_gc(user, drop_not_started)) {
942 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
943 Manager *m = userdata;
944 struct dual_timestamp since;
950 if (m->idle_action == HANDLE_IGNORE ||
951 m->idle_action_usec <= 0)
954 n = now(CLOCK_MONOTONIC);
956 r = manager_get_idle_hint(m, &since);
958 /* Not idle. Let's check if after a timeout it might be idle then. */
959 elapse = n + m->idle_action_usec;
961 /* Idle! Let's see if it's time to do something, or if
962 * we shall sleep for longer. */
964 if (n >= since.monotonic + m->idle_action_usec &&
965 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
966 log_info("System idle. Taking action.");
968 manager_handle_action(m, 0, m->idle_action, false, false);
969 m->idle_action_not_before_usec = n;
972 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
975 if (!m->idle_action_event_source) {
977 r = sd_event_add_time(
979 &m->idle_action_event_source,
981 elapse, USEC_PER_SEC*30,
982 manager_dispatch_idle_action, m);
984 return log_error_errno(r, "Failed to add idle event source: %m");
986 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
988 return log_error_errno(r, "Failed to set idle event source priority: %m");
990 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
992 return log_error_errno(r, "Failed to set idle event timer: %m");
994 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
996 return log_error_errno(r, "Failed to enable idle event timer: %m");
1002 int manager_startup(Manager *m) {
1008 Inhibitor *inhibitor;
1013 /* Connect to console */
1014 r = manager_connect_console(m);
1018 /* Connect to udev */
1019 r = manager_connect_udev(m);
1021 return log_error_errno(r, "Failed to create udev watchers: %m");
1023 /* Connect to the bus */
1024 r = manager_connect_bus(m);
1028 /* Instantiate magic seat 0 */
1029 r = manager_add_seat(m, "seat0", &m->seat0);
1031 return log_error_errno(r, "Failed to add seat0: %m");
1033 r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
1035 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
1037 /* Deserialize state */
1038 r = manager_enumerate_devices(m);
1040 log_warning_errno(r, "Device enumeration failed: %m");
1042 r = manager_enumerate_seats(m);
1044 log_warning_errno(r, "Seat enumeration failed: %m");
1046 r = manager_enumerate_users(m);
1048 log_warning_errno(r, "User enumeration failed: %m");
1050 r = manager_enumerate_sessions(m);
1052 log_warning_errno(r, "Session enumeration failed: %m");
1054 r = manager_enumerate_inhibitors(m);
1056 log_warning_errno(r, "Inhibitor enumeration failed: %m");
1058 r = manager_enumerate_buttons(m);
1060 log_warning_errno(r, "Button enumeration failed: %m");
1062 /* Remove stale objects before we start them */
1063 manager_gc(m, false);
1065 /* Reserve the special reserved VT */
1066 manager_reserve_vt(m);
1068 /* And start everything */
1069 HASHMAP_FOREACH(seat, m->seats, i)
1072 HASHMAP_FOREACH(user, m->users, i)
1075 HASHMAP_FOREACH(session, m->sessions, i)
1076 session_start(session);
1078 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1079 inhibitor_start(inhibitor);
1081 HASHMAP_FOREACH(button, m->buttons, i)
1082 button_check_switches(button);
1084 manager_dispatch_idle_action(NULL, 0, m);
1089 int manager_run(Manager *m) {
1095 usec_t us = (uint64_t) -1;
1097 r = sd_event_get_state(m->event);
1100 if (r == SD_EVENT_FINISHED)
1103 manager_gc(m, true);
1105 if (manager_dispatch_delayed(m) > 0)
1108 if (m->action_what != 0 && !m->action_job) {
1111 x = now(CLOCK_MONOTONIC);
1112 y = m->action_timestamp + m->inhibit_delay_max;
1114 us = x >= y ? 0 : y - x;
1117 r = sd_event_run(m->event, us);
1123 static int manager_parse_config_file(Manager *m) {
1126 return config_parse_many("/etc/systemd/logind.conf",
1127 CONF_DIRS_NULSTR("systemd/logind.conf"),
1129 config_item_perf_lookup, logind_gperf_lookup,
1133 int main(int argc, char *argv[]) {
1137 log_set_target(LOG_TARGET_AUTO);
1138 log_set_facility(LOG_AUTH);
1139 log_parse_environment();
1145 log_error("This program takes no arguments.");
1150 /* Always create the directories people can create inotify
1151 * watches in. Note that some applications might check for the
1152 * existence of /run/systemd/seats/ to determine whether
1153 * logind is available, so please always make sure this check
1155 mkdir_label("/run/systemd/seats", 0755);
1156 mkdir_label("/run/systemd/users", 0755);
1157 mkdir_label("/run/systemd/sessions", 0755);
1165 manager_parse_config_file(m);
1167 r = manager_startup(m);
1169 log_error_errno(r, "Failed to fully start up daemon: %m");
1173 log_debug("systemd-logind running as pid "PID_FMT, getpid());
1177 "STATUS=Processing requests...");
1181 log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
1186 "STATUS=Shutting down...");
1191 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;