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/timerfd.h>
30 #include "sd-daemon.h"
32 #include "conf-parser.h"
35 #include "bus-error.h"
37 #include "udev-util.h"
39 Manager *manager_new(void) {
47 m->console_active_fd = -1;
48 m->reserve_vt_fd = -1;
52 m->inhibit_delay_max = 5 * USEC_PER_SEC;
53 m->handle_power_key = HANDLE_POWEROFF;
54 m->handle_suspend_key = HANDLE_SUSPEND;
55 m->handle_hibernate_key = HANDLE_HIBERNATE;
56 m->handle_lid_switch = HANDLE_SUSPEND;
57 m->lid_switch_ignore_inhibited = true;
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->devices = hashmap_new(string_hash_func, string_compare_func);
64 m->seats = hashmap_new(string_hash_func, string_compare_func);
65 m->sessions = hashmap_new(string_hash_func, string_compare_func);
66 m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
67 m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
68 m->buttons = hashmap_new(string_hash_func, string_compare_func);
70 m->user_units = hashmap_new(string_hash_func, string_compare_func);
71 m->session_units = hashmap_new(string_hash_func, string_compare_func);
73 m->busnames = set_new(string_hash_func, string_compare_func);
75 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
76 !m->user_units || !m->session_units)
79 m->kill_exclude_users = strv_new("root", NULL);
80 if (!m->kill_exclude_users)
87 r = sd_event_default(&m->event);
91 sd_event_set_watchdog(m->event, true);
100 void manager_free(Manager *m) {
110 while ((session = hashmap_first(m->sessions)))
111 session_free(session);
113 while ((u = hashmap_first(m->users)))
116 while ((d = hashmap_first(m->devices)))
119 while ((s = hashmap_first(m->seats)))
122 while ((i = hashmap_first(m->inhibitors)))
125 while ((b = hashmap_first(m->buttons)))
128 hashmap_free(m->devices);
129 hashmap_free(m->seats);
130 hashmap_free(m->sessions);
131 hashmap_free(m->users);
132 hashmap_free(m->inhibitors);
133 hashmap_free(m->buttons);
135 hashmap_free(m->user_units);
136 hashmap_free(m->session_units);
138 set_free_free(m->busnames);
140 sd_event_source_unref(m->idle_action_event_source);
142 sd_event_source_unref(m->console_active_event_source);
143 sd_event_source_unref(m->udev_seat_event_source);
144 sd_event_source_unref(m->udev_device_event_source);
145 sd_event_source_unref(m->udev_vcsa_event_source);
146 sd_event_source_unref(m->udev_button_event_source);
147 sd_event_source_unref(m->lid_switch_ignore_event_source);
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_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->bus, m->polkit_registry);
166 sd_bus_unref(m->bus);
167 sd_event_unref(m->event);
169 if (m->reserve_vt_fd >= 0)
170 close_nointr_nofail(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)
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("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("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("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
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("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("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
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("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("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
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("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("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
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("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 log_error("Failed to connect to system bus: %s", strerror(-r));
588 r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
590 log_error("Failed to add manager object vtable: %s", strerror(-r));
594 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
596 log_error("Failed to add seat object vtable: %s", strerror(-r));
600 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
602 log_error("Failed to add seat enumerator: %s", strerror(-r));
606 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
608 log_error("Failed to add session object vtable: %s", strerror(-r));
612 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/session", session_node_enumerator, m);
614 log_error("Failed to add session enumerator: %s", strerror(-r));
618 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
620 log_error("Failed to add user object vtable: %s", strerror(-r));
624 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/user", user_node_enumerator, m);
626 log_error("Failed to add user enumerator: %s", strerror(-r));
630 r = sd_bus_add_match(m->bus,
632 "sender='org.freedesktop.DBus',"
633 "interface='org.freedesktop.DBus',"
634 "member='NameOwnerChanged',"
635 "path='/org/freedesktop/DBus'",
636 match_name_owner_changed, m);
638 log_error("Failed to add match for NameOwnerChanged: %s", strerror(-r));
642 r = sd_bus_add_match(m->bus,
644 "sender='org.freedesktop.systemd1',"
645 "interface='org.freedesktop.systemd1.Manager',"
646 "member='JobRemoved',"
647 "path='/org/freedesktop/systemd1'",
648 match_job_removed, m);
650 log_error("Failed to add match for JobRemoved: %s", strerror(-r));
654 r = sd_bus_add_match(m->bus,
656 "sender='org.freedesktop.systemd1',"
657 "interface='org.freedesktop.systemd1.Manager',"
658 "member='UnitRemoved',"
659 "path='/org/freedesktop/systemd1'",
660 match_unit_removed, m);
662 log_error("Failed to add match for UnitRemoved: %s", strerror(-r));
666 r = sd_bus_add_match(m->bus,
668 "sender='org.freedesktop.systemd1',"
669 "interface='org.freedesktop.DBus.Properties',"
670 "member='PropertiesChanged'",
671 match_properties_changed, m);
673 log_error("Failed to add match for PropertiesChanged: %s", strerror(-r));
677 r = sd_bus_add_match(m->bus,
679 "sender='org.freedesktop.systemd1',"
680 "interface='org.freedesktop.systemd1.Manager',"
681 "member='Reloading',"
682 "path='/org/freedesktop/systemd1'",
685 log_error("Failed to add match for Reloading: %s", strerror(-r));
689 r = sd_bus_call_method(
691 "org.freedesktop.systemd1",
692 "/org/freedesktop/systemd1",
693 "org.freedesktop.systemd1.Manager",
698 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
702 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
704 log_error("Failed to register name: %s", strerror(-r));
708 r = sd_bus_attach_event(m->bus, m->event, 0);
710 log_error("Failed to attach bus to event loop: %s", strerror(-r));
717 static int manager_connect_console(Manager *m) {
721 assert(m->console_active_fd < 0);
723 /* On certain architectures (S390 and Xen, and containers),
724 /dev/tty0 does not exist, so don't fail if we can't open
726 if (access("/dev/tty0", F_OK) < 0)
729 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
730 if (m->console_active_fd < 0) {
732 /* On some systems the device node /dev/tty0 may exist
733 * even though /sys/class/tty/tty0 does not. */
737 log_error("Failed to open /sys/class/tty/tty0/active: %m");
741 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
743 log_error("Failed to watch foreground console");
750 static int manager_connect_udev(Manager *m) {
754 assert(!m->udev_seat_monitor);
755 assert(!m->udev_device_monitor);
756 assert(!m->udev_vcsa_monitor);
757 assert(!m->udev_button_monitor);
759 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
760 if (!m->udev_seat_monitor)
763 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
767 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
771 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);
775 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
776 if (!m->udev_device_monitor)
779 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
783 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
787 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
791 r = udev_monitor_enable_receiving(m->udev_device_monitor);
795 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);
799 /* Don't watch keys if nobody cares */
800 if (m->handle_power_key != HANDLE_IGNORE ||
801 m->handle_suspend_key != HANDLE_IGNORE ||
802 m->handle_hibernate_key != HANDLE_IGNORE ||
803 m->handle_lid_switch != HANDLE_IGNORE) {
805 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
806 if (!m->udev_button_monitor)
809 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
813 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
817 r = udev_monitor_enable_receiving(m->udev_button_monitor);
821 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);
826 /* Don't bother watching VCSA devices, if nobody cares */
827 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
829 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
830 if (!m->udev_vcsa_monitor)
833 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
837 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
841 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);
849 void manager_gc(Manager *m, bool drop_not_started) {
856 while ((seat = m->seat_gc_queue)) {
857 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
858 seat->in_gc_queue = false;
860 if (!seat_check_gc(seat, drop_not_started)) {
861 seat_stop(seat, false);
866 while ((session = m->session_gc_queue)) {
867 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
868 session->in_gc_queue = false;
870 /* First, if we are not closing yet, initiate stopping */
871 if (!session_check_gc(session, drop_not_started) &&
872 session_get_state(session) != SESSION_CLOSING)
873 session_stop(session, false);
875 /* Normally, this should make the session busy again,
876 * if it doesn't then let's get rid of it
878 if (!session_check_gc(session, drop_not_started)) {
879 session_finalize(session);
880 session_free(session);
884 while ((user = m->user_gc_queue)) {
885 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
886 user->in_gc_queue = false;
888 /* First step: queue stop jobs */
889 if (!user_check_gc(user, drop_not_started))
890 user_stop(user, false);
892 /* Second step: finalize user */
893 if (!user_check_gc(user, drop_not_started)) {
900 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
901 Manager *m = userdata;
902 struct dual_timestamp since;
908 if (m->idle_action == HANDLE_IGNORE ||
909 m->idle_action_usec <= 0)
912 n = now(CLOCK_MONOTONIC);
914 r = manager_get_idle_hint(m, &since);
916 /* Not idle. Let's check if after a timeout it might be idle then. */
917 elapse = n + m->idle_action_usec;
919 /* Idle! Let's see if it's time to do something, or if
920 * we shall sleep for longer. */
922 if (n >= since.monotonic + m->idle_action_usec &&
923 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
924 log_info("System idle. Taking action.");
926 manager_handle_action(m, 0, m->idle_action, false, false);
927 m->idle_action_not_before_usec = n;
930 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
933 if (!m->idle_action_event_source) {
935 r = sd_event_add_monotonic(m->event, &m->idle_action_event_source, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m);
937 log_error("Failed to add idle event source: %s", strerror(-r));
941 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
943 log_error("Failed to set idle event source priority: %s", strerror(-r));
947 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
949 log_error("Failed to set idle event timer: %s", strerror(-r));
953 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
955 log_error("Failed to enable idle event timer: %s", strerror(-r));
963 static int lid_switch_ignore_handler(sd_event_source *e, uint64_t usec, void *userdata) {
964 Manager *m = userdata;
969 m->lid_switch_ignore_event_source = sd_event_source_unref(m->lid_switch_ignore_event_source);
973 int manager_set_lid_switch_ignore(Manager *m, usec_t until) {
978 if (until <= now(CLOCK_MONOTONIC))
981 /* We want to ignore the lid switch for a while after each
982 * suspend, and after boot-up. Hence let's install a timer for
983 * this. As long as the event source exists we ignore the lid
986 if (m->lid_switch_ignore_event_source) {
989 r = sd_event_source_get_time(m->lid_switch_ignore_event_source, &u);
996 r = sd_event_source_set_time(m->lid_switch_ignore_event_source, until);
998 r = sd_event_add_monotonic(m->event, &m->lid_switch_ignore_event_source, until, 0, lid_switch_ignore_handler, m);
1003 int manager_startup(Manager *m) {
1009 Inhibitor *inhibitor;
1014 /* Connect to console */
1015 r = manager_connect_console(m);
1019 /* Connect to udev */
1020 r = manager_connect_udev(m);
1022 log_error("Failed to create udev watchers: %s", strerror(-r));
1026 /* Connect to the bus */
1027 r = manager_connect_bus(m);
1031 /* Instantiate magic seat 0 */
1032 r = manager_add_seat(m, "seat0", &m->seat0);
1034 log_error("Failed to add seat0: %s", strerror(-r));
1038 r = manager_set_lid_switch_ignore(m, 0 + IGNORE_LID_SWITCH_STARTUP_USEC);
1040 log_warning("Failed to set up lid switch ignore event source: %s", strerror(-r));
1042 /* Deserialize state */
1043 r = manager_enumerate_devices(m);
1045 log_warning("Device enumeration failed: %s", strerror(-r));
1047 r = manager_enumerate_seats(m);
1049 log_warning("Seat enumeration failed: %s", strerror(-r));
1051 r = manager_enumerate_users(m);
1053 log_warning("User enumeration failed: %s", strerror(-r));
1055 r = manager_enumerate_sessions(m);
1057 log_warning("Session enumeration failed: %s", strerror(-r));
1059 r = manager_enumerate_inhibitors(m);
1061 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1063 r = manager_enumerate_buttons(m);
1065 log_warning("Button enumeration failed: %s", strerror(-r));
1067 /* Remove stale objects before we start them */
1068 manager_gc(m, false);
1070 /* Reserve the special reserved VT */
1071 manager_reserve_vt(m);
1073 /* And start everything */
1074 HASHMAP_FOREACH(seat, m->seats, i)
1077 HASHMAP_FOREACH(user, m->users, i)
1080 HASHMAP_FOREACH(session, m->sessions, i)
1081 session_start(session);
1083 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1084 inhibitor_start(inhibitor);
1086 HASHMAP_FOREACH(button, m->buttons, i)
1087 button_check_switches(button);
1089 manager_dispatch_idle_action(NULL, 0, m);
1094 int manager_run(Manager *m) {
1100 usec_t us = (uint64_t) -1;
1102 r = sd_event_get_state(m->event);
1105 if (r == SD_EVENT_FINISHED)
1108 manager_gc(m, true);
1110 if (manager_dispatch_delayed(m) > 0)
1113 if (m->action_what != 0 && !m->action_job) {
1116 x = now(CLOCK_MONOTONIC);
1117 y = m->action_timestamp + m->inhibit_delay_max;
1119 us = x >= y ? 0 : y - x;
1122 r = sd_event_run(m->event, us);
1128 static int manager_parse_config_file(Manager *m) {
1129 static const char fn[] = "/etc/systemd/logind.conf";
1130 _cleanup_fclose_ FILE *f = NULL;
1135 f = fopen(fn, "re");
1137 if (errno == ENOENT)
1140 log_warning("Failed to open configuration file %s: %m", fn);
1144 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1145 (void*) logind_gperf_lookup, false, false, m);
1147 log_warning("Failed to parse configuration file: %s", strerror(-r));
1152 int main(int argc, char *argv[]) {
1156 log_set_target(LOG_TARGET_AUTO);
1157 log_set_facility(LOG_AUTH);
1158 log_parse_environment();
1164 log_error("This program takes no arguments.");
1169 /* Always create the directories people can create inotify
1170 * watches in. Note that some applications might check for the
1171 * existence of /run/systemd/seats/ to determine whether
1172 * logind is available, so please always make sure this check
1174 mkdir_label("/run/systemd/seats", 0755);
1175 mkdir_label("/run/systemd/users", 0755);
1176 mkdir_label("/run/systemd/sessions", 0755);
1184 manager_parse_config_file(m);
1186 r = manager_startup(m);
1188 log_error("Failed to fully start up daemon: %s", strerror(-r));
1192 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1196 "STATUS=Processing requests...");
1200 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1204 "STATUS=Shutting down...");
1209 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;