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"
38 Manager *manager_new(void) {
46 m->console_active_fd = -1;
47 m->reserve_vt_fd = -1;
51 m->inhibit_delay_max = 5 * USEC_PER_SEC;
52 m->handle_power_key = HANDLE_POWEROFF;
53 m->handle_suspend_key = HANDLE_SUSPEND;
54 m->handle_hibernate_key = HANDLE_HIBERNATE;
55 m->handle_lid_switch = HANDLE_SUSPEND;
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->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_units = hashmap_new(string_hash_func, string_compare_func);
70 m->session_units = hashmap_new(string_hash_func, string_compare_func);
72 m->busnames = set_new(string_hash_func, string_compare_func);
74 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
75 !m->user_units || !m->session_units ||
81 m->kill_exclude_users = strv_new("root", NULL);
82 if (!m->kill_exclude_users) {
93 r = sd_event_new(&m->event);
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);
150 if (m->console_active_fd >= 0)
151 close_nointr_nofail(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->bus, m->polkit_registry);
167 sd_bus_unref(m->bus);
168 sd_event_unref(m->event);
170 if (m->reserve_vt_fd >= 0)
171 close_nointr_nofail(m->reserve_vt_fd);
173 strv_free(m->kill_only_users);
174 strv_free(m->kill_exclude_users);
180 int manager_enumerate_devices(Manager *m) {
181 struct udev_list_entry *item = NULL, *first = NULL;
182 struct udev_enumerate *e;
187 /* Loads devices from udev and creates seats for them as
190 e = udev_enumerate_new(m->udev);
196 r = udev_enumerate_add_match_tag(e, "master-of-seat");
200 r = udev_enumerate_scan_devices(e);
204 first = udev_enumerate_get_list_entry(e);
205 udev_list_entry_foreach(item, first) {
206 struct udev_device *d;
209 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
215 k = manager_process_seat_device(m, d);
216 udev_device_unref(d);
224 udev_enumerate_unref(e);
229 int manager_enumerate_buttons(Manager *m) {
230 struct udev_list_entry *item = NULL, *first = NULL;
231 struct udev_enumerate *e;
236 /* Loads buttons from udev */
238 if (m->handle_power_key == HANDLE_IGNORE &&
239 m->handle_suspend_key == HANDLE_IGNORE &&
240 m->handle_hibernate_key == HANDLE_IGNORE &&
241 m->handle_lid_switch == HANDLE_IGNORE)
244 e = udev_enumerate_new(m->udev);
250 r = udev_enumerate_add_match_subsystem(e, "input");
254 r = udev_enumerate_add_match_tag(e, "power-switch");
258 r = udev_enumerate_scan_devices(e);
262 first = udev_enumerate_get_list_entry(e);
263 udev_list_entry_foreach(item, first) {
264 struct udev_device *d;
267 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
273 k = manager_process_button_device(m, d);
274 udev_device_unref(d);
282 udev_enumerate_unref(e);
287 int manager_enumerate_seats(Manager *m) {
288 _cleanup_closedir_ DIR *d = NULL;
294 /* This loads data about seats stored on disk, but does not
295 * actually create any seats. Removes data of seats that no
298 d = opendir("/run/systemd/seats");
303 log_error("Failed to open /run/systemd/seats: %m");
307 FOREACH_DIRENT(de, d, return -errno) {
311 if (!dirent_is_file(de))
314 s = hashmap_get(m->seats, de->d_name);
316 unlinkat(dirfd(d), de->d_name, 0);
328 static int manager_enumerate_linger_users(Manager *m) {
329 _cleanup_closedir_ DIR *d = NULL;
335 d = opendir("/var/lib/systemd/linger");
340 log_error("Failed to open /var/lib/systemd/linger/: %m");
344 FOREACH_DIRENT(de, d, return -errno) {
347 if (!dirent_is_file(de))
350 k = manager_add_user_by_name(m, de->d_name, NULL);
352 log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
360 int manager_enumerate_users(Manager *m) {
361 _cleanup_closedir_ DIR *d = NULL;
367 /* Add lingering users */
368 r = manager_enumerate_linger_users(m);
370 /* Read in user data stored on disk */
371 d = opendir("/run/systemd/users");
376 log_error("Failed to open /run/systemd/users: %m");
380 FOREACH_DIRENT(de, d, return -errno) {
383 if (!dirent_is_file(de))
386 k = manager_add_user_by_name(m, de->d_name, &u);
388 log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
394 user_add_to_gc_queue(u);
404 int manager_enumerate_sessions(Manager *m) {
405 _cleanup_closedir_ DIR *d = NULL;
411 /* Read in session data stored on disk */
412 d = opendir("/run/systemd/sessions");
417 log_error("Failed to open /run/systemd/sessions: %m");
421 FOREACH_DIRENT(de, d, return -errno) {
425 if (!dirent_is_file(de))
428 if (!session_id_valid(de->d_name)) {
429 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
434 k = manager_add_session(m, de->d_name, &s);
436 log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
442 session_add_to_gc_queue(s);
452 int manager_enumerate_inhibitors(Manager *m) {
453 _cleanup_closedir_ DIR *d = NULL;
459 d = opendir("/run/systemd/inhibit");
464 log_error("Failed to open /run/systemd/inhibit: %m");
468 FOREACH_DIRENT(de, d, return -errno) {
472 if (!dirent_is_file(de))
475 k = manager_add_inhibitor(m, de->d_name, &i);
477 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
482 k = inhibitor_load(i);
490 static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
491 Manager *m = userdata;
492 struct udev_device *d;
497 d = udev_monitor_receive_device(m->udev_seat_monitor);
501 r = manager_process_seat_device(m, d);
502 udev_device_unref(d);
507 static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
508 Manager *m = userdata;
509 struct udev_device *d;
514 d = udev_monitor_receive_device(m->udev_device_monitor);
518 r = manager_process_seat_device(m, d);
519 udev_device_unref(d);
524 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
525 Manager *m = userdata;
526 struct udev_device *d;
532 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
536 name = udev_device_get_sysname(d);
538 /* Whenever a VCSA device is removed try to reallocate our
539 * VTs, to make sure our auto VTs never go away. */
541 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
542 r = seat_preallocate_vts(m->seat0);
544 udev_device_unref(d);
549 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
550 Manager *m = userdata;
551 struct udev_device *d;
556 d = udev_monitor_receive_device(m->udev_button_monitor);
560 r = manager_process_button_device(m, d);
561 udev_device_unref(d);
566 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
567 Manager *m = userdata;
571 assert(m->console_active_fd == fd);
573 seat_read_active_vt(m->seat0);
578 static int manager_reserve_vt(Manager *m) {
579 _cleanup_free_ char *p = NULL;
583 if (m->reserve_vt <= 0)
586 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
589 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
590 if (m->reserve_vt_fd < 0) {
592 /* Don't complain on VT-less systems */
594 log_warning("Failed to pin reserved VT: %m");
601 static int manager_connect_bus(Manager *m) {
602 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
608 r = sd_bus_open_system(&m->bus);
610 log_error("Failed to connect to system bus: %s", strerror(-r));
614 r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
616 log_error("Failed to add manager object vtable: %s", strerror(-r));
620 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
622 log_error("Failed to add seat object vtable: %s", strerror(-r));
626 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
628 log_error("Failed to add seat enumerator: %s", strerror(-r));
632 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
634 log_error("Failed to add session object vtable: %s", strerror(-r));
638 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/session", session_node_enumerator, m);
640 log_error("Failed to add session enumerator: %s", strerror(-r));
644 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
646 log_error("Failed to add user object vtable: %s", strerror(-r));
650 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/user", user_node_enumerator, m);
652 log_error("Failed to add user enumerator: %s", strerror(-r));
656 r = sd_bus_add_match(m->bus,
658 "sender='org.freedesktop.DBus',"
659 "interface='org.freedesktop.DBus',"
660 "member='NameOwnerChanged',"
661 "path='/org/freedesktop/DBus'",
662 match_name_owner_changed, m);
664 log_error("Failed to add match for NameOwnerChanged: %s", strerror(-r));
668 r = sd_bus_add_match(m->bus,
670 "sender='org.freedesktop.systemd1',"
671 "interface='org.freedesktop.systemd1.Manager',"
672 "member='JobRemoved',"
673 "path='/org/freedesktop/systemd1'",
674 match_job_removed, m);
676 log_error("Failed to add match for JobRemoved: %s", strerror(-r));
680 r = sd_bus_add_match(m->bus,
682 "sender='org.freedesktop.systemd1',"
683 "interface='org.freedesktop.systemd1.Manager',"
684 "member='UnitRemoved',"
685 "path='/org/freedesktop/systemd1'",
686 match_unit_removed, m);
688 log_error("Failed to add match for UnitRemoved: %s", strerror(-r));
692 r = sd_bus_add_match(m->bus,
694 "sender='org.freedesktop.systemd1',"
695 "interface='org.freedesktop.DBus.Properties',"
696 "member='PropertiesChanged'",
697 match_properties_changed, m);
699 log_error("Failed to add match for PropertiesChanged: %s", strerror(-r));
703 r = sd_bus_add_match(m->bus,
705 "sender='org.freedesktop.systemd1',"
706 "interface='org.freedesktop.systemd1.Manager',"
707 "member='Reloading',"
708 "path='/org/freedesktop/systemd1'",
711 log_error("Failed to add match for Reloading: %s", strerror(-r));
715 r = sd_bus_call_method(
717 "org.freedesktop.systemd1",
718 "/org/freedesktop/systemd1",
719 "org.freedesktop.systemd1.Manager",
724 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
728 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", SD_BUS_NAME_DO_NOT_QUEUE);
730 log_error("Failed to register name: %s", strerror(-r));
734 if (r != SD_BUS_NAME_PRIMARY_OWNER) {
735 log_error("Failed to acquire name.");
739 r = sd_bus_attach_event(m->bus, m->event, 0);
741 log_error("Failed to attach bus to event loop: %s", strerror(-r));
748 static int manager_connect_console(Manager *m) {
752 assert(m->console_active_fd < 0);
754 /* On certain architectures (S390 and Xen, and containers),
755 /dev/tty0 does not exist, so don't fail if we can't open
757 if (access("/dev/tty0", F_OK) < 0)
760 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
761 if (m->console_active_fd < 0) {
763 /* On some systems the device node /dev/tty0 may exist
764 * even though /sys/class/tty/tty0 does not. */
768 log_error("Failed to open /sys/class/tty/tty0/active: %m");
772 r = sd_event_add_io(m->event, m->console_active_fd, 0, manager_dispatch_console, m, &m->console_active_event_source);
774 log_error("Failed to watch foreground console");
781 static int manager_connect_udev(Manager *m) {
785 assert(!m->udev_seat_monitor);
786 assert(!m->udev_device_monitor);
787 assert(!m->udev_vcsa_monitor);
788 assert(!m->udev_button_monitor);
790 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
791 if (!m->udev_seat_monitor)
794 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
798 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
802 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_seat_monitor), EPOLLIN, manager_dispatch_seat_udev, m, &m->udev_seat_event_source);
806 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
807 if (!m->udev_device_monitor)
810 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
814 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
818 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
822 r = udev_monitor_enable_receiving(m->udev_device_monitor);
826 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_device_monitor), EPOLLIN, manager_dispatch_device_udev, m, &m->udev_device_event_source);
830 /* Don't watch keys if nobody cares */
831 if (m->handle_power_key != HANDLE_IGNORE ||
832 m->handle_suspend_key != HANDLE_IGNORE ||
833 m->handle_hibernate_key != HANDLE_IGNORE ||
834 m->handle_lid_switch != HANDLE_IGNORE) {
836 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
837 if (!m->udev_button_monitor)
840 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
844 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
848 r = udev_monitor_enable_receiving(m->udev_button_monitor);
852 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_button_monitor), EPOLLIN, manager_dispatch_button_udev, m, &m->udev_button_event_source);
857 /* Don't bother watching VCSA devices, if nobody cares */
858 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
860 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
861 if (!m->udev_vcsa_monitor)
864 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
868 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
872 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_vcsa_monitor), EPOLLIN, manager_dispatch_vcsa_udev, m, &m->udev_vcsa_event_source);
880 void manager_gc(Manager *m, bool drop_not_started) {
887 while ((seat = m->seat_gc_queue)) {
888 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
889 seat->in_gc_queue = false;
891 if (!seat_check_gc(seat, drop_not_started)) {
897 while ((session = m->session_gc_queue)) {
898 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
899 session->in_gc_queue = false;
901 if (!session_check_gc(session, drop_not_started)) {
902 session_stop(session);
903 session_finalize(session);
904 session_free(session);
908 while ((user = m->user_gc_queue)) {
909 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
910 user->in_gc_queue = false;
912 if (!user_check_gc(user, drop_not_started)) {
920 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
921 Manager *m = userdata;
922 struct dual_timestamp since;
928 if (m->idle_action == HANDLE_IGNORE ||
929 m->idle_action_usec <= 0)
932 n = now(CLOCK_MONOTONIC);
934 r = manager_get_idle_hint(m, &since);
936 /* Not idle. Let's check if after a timeout it might be idle then. */
937 elapse = n + m->idle_action_usec;
939 /* Idle! Let's see if it's time to do something, or if
940 * we shall sleep for longer. */
942 if (n >= since.monotonic + m->idle_action_usec &&
943 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
944 log_info("System idle. Taking action.");
946 manager_handle_action(m, 0, m->idle_action, false, false);
947 m->idle_action_not_before_usec = n;
950 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
953 if (!m->idle_action_event_source) {
955 r = sd_event_add_monotonic(m->event, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m, &m->idle_action_event_source);
957 log_error("Failed to add idle event source: %s", strerror(-r));
961 r = sd_event_source_set_priority(m->idle_action_event_source, SD_PRIORITY_IDLE+10);
963 log_error("Failed to set idle event source priority: %s", strerror(-r));
967 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
969 log_error("Failed to set idle event timer: %s", strerror(-r));
973 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
975 log_error("Failed to enable idle event timer: %s", strerror(-r));
983 int manager_startup(Manager *m) {
988 Inhibitor *inhibitor;
993 /* Connect to console */
994 r = manager_connect_console(m);
998 /* Connect to udev */
999 r = manager_connect_udev(m);
1001 log_error("Failed to create udev watchers: %s", strerror(-r));
1005 /* Connect to the bus */
1006 r = manager_connect_bus(m);
1010 /* Instantiate magic seat 0 */
1011 r = manager_add_seat(m, "seat0", &m->seat0);
1013 log_error("Failed to add seat0: %s", strerror(-r));
1017 /* Deserialize state */
1018 r = manager_enumerate_devices(m);
1020 log_warning("Device enumeration failed: %s", strerror(-r));
1022 r = manager_enumerate_seats(m);
1024 log_warning("Seat enumeration failed: %s", strerror(-r));
1026 r = manager_enumerate_users(m);
1028 log_warning("User enumeration failed: %s", strerror(-r));
1030 r = manager_enumerate_sessions(m);
1032 log_warning("Session enumeration failed: %s", strerror(-r));
1034 r = manager_enumerate_inhibitors(m);
1036 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1038 r = manager_enumerate_buttons(m);
1040 log_warning("Button enumeration failed: %s", strerror(-r));
1042 /* Remove stale objects before we start them */
1043 manager_gc(m, false);
1045 /* Reserve the special reserved VT */
1046 manager_reserve_vt(m);
1048 /* And start everything */
1049 HASHMAP_FOREACH(seat, m->seats, i)
1052 HASHMAP_FOREACH(user, m->users, i)
1055 HASHMAP_FOREACH(session, m->sessions, i)
1056 session_start(session);
1058 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1059 inhibitor_start(inhibitor);
1061 manager_dispatch_idle_action(NULL, 0, m);
1066 static int manager_recheck_buttons(Manager *m) {
1073 HASHMAP_FOREACH(b, m->buttons, i) {
1076 q = button_recheck(b);
1086 int manager_run(Manager *m) {
1092 usec_t us = (uint64_t) -1;
1094 r = sd_event_get_state(m->event);
1097 if (r == SD_EVENT_FINISHED)
1100 manager_gc(m, true);
1102 if (manager_dispatch_delayed(m) > 0)
1105 if (manager_recheck_buttons(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);
1125 static int manager_parse_config_file(Manager *m) {
1126 static const char fn[] = "/etc/systemd/logind.conf";
1127 _cleanup_fclose_ FILE *f = NULL;
1132 f = fopen(fn, "re");
1134 if (errno == ENOENT)
1137 log_warning("Failed to open configuration file %s: %m", fn);
1141 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1142 (void*) logind_gperf_lookup, false, false, m);
1144 log_warning("Failed to parse configuration file: %s", strerror(-r));
1149 int main(int argc, char *argv[]) {
1153 log_set_target(LOG_TARGET_AUTO);
1154 log_set_facility(LOG_AUTH);
1155 log_parse_environment();
1161 log_error("This program takes no arguments.");
1166 /* Always create the directories people can create inotify
1167 * watches in. Note that some applications might check for the
1168 * existence of /run/systemd/seats/ to determine whether
1169 * logind is available, so please always make sure this check
1171 mkdir_label("/run/systemd/seats", 0755);
1172 mkdir_label("/run/systemd/users", 0755);
1173 mkdir_label("/run/systemd/sessions", 0755);
1181 manager_parse_config_file(m);
1183 r = manager_startup(m);
1185 log_error("Failed to fully start up daemon: %s", strerror(-r));
1189 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1193 "STATUS=Processing requests...");
1197 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1201 "STATUS=Shutting down...");
1206 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;