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 "bus-error.h"
32 #include "conf-parser.h"
33 #include "dirent-util.h"
35 #include "formats-util.h"
37 #include "signal-util.h"
39 #include "udev-util.h"
41 static void manager_free(Manager
*m
);
43 static Manager
*manager_new(void) {
51 m
->console_active_fd
= -1;
52 m
->reserve_vt_fd
= -1;
57 m
->inhibit_delay_max
= 5 * USEC_PER_SEC
;
58 m
->handle_power_key
= HANDLE_POWEROFF
;
59 m
->handle_suspend_key
= HANDLE_SUSPEND
;
60 m
->handle_hibernate_key
= HANDLE_HIBERNATE
;
61 m
->handle_lid_switch
= HANDLE_SUSPEND
;
62 m
->handle_lid_switch_docked
= HANDLE_IGNORE
;
63 m
->lid_switch_ignore_inhibited
= true;
64 m
->holdoff_timeout_usec
= 30 * USEC_PER_SEC
;
66 m
->idle_action_usec
= 30 * USEC_PER_MINUTE
;
67 m
->idle_action
= HANDLE_IGNORE
;
68 m
->idle_action_not_before_usec
= now(CLOCK_MONOTONIC
);
70 m
->runtime_dir_size
= PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
72 m
->devices
= hashmap_new(&string_hash_ops
);
73 m
->seats
= hashmap_new(&string_hash_ops
);
74 m
->sessions
= hashmap_new(&string_hash_ops
);
75 m
->users
= hashmap_new(NULL
);
76 m
->inhibitors
= hashmap_new(&string_hash_ops
);
77 m
->buttons
= hashmap_new(&string_hash_ops
);
79 m
->user_units
= hashmap_new(&string_hash_ops
);
80 m
->session_units
= hashmap_new(&string_hash_ops
);
82 if (!m
->devices
|| !m
->seats
|| !m
->sessions
|| !m
->users
|| !m
->inhibitors
|| !m
->buttons
|| !m
->user_units
|| !m
->session_units
)
85 m
->kill_exclude_users
= strv_new("root", NULL
);
86 if (!m
->kill_exclude_users
)
93 r
= sd_event_default(&m
->event
);
97 sd_event_set_watchdog(m
->event
, true);
106 static void manager_free(Manager
*m
) {
116 while ((session
= hashmap_first(m
->sessions
)))
117 session_free(session
);
119 while ((u
= hashmap_first(m
->users
)))
122 while ((d
= hashmap_first(m
->devices
)))
125 while ((s
= hashmap_first(m
->seats
)))
128 while ((i
= hashmap_first(m
->inhibitors
)))
131 while ((b
= hashmap_first(m
->buttons
)))
134 hashmap_free(m
->devices
);
135 hashmap_free(m
->seats
);
136 hashmap_free(m
->sessions
);
137 hashmap_free(m
->users
);
138 hashmap_free(m
->inhibitors
);
139 hashmap_free(m
->buttons
);
141 hashmap_free(m
->user_units
);
142 hashmap_free(m
->session_units
);
144 sd_event_source_unref(m
->idle_action_event_source
);
145 sd_event_source_unref(m
->inhibit_timeout_source
);
146 sd_event_source_unref(m
->scheduled_shutdown_timeout_source
);
147 sd_event_source_unref(m
->nologin_timeout_source
);
148 sd_event_source_unref(m
->wall_message_timeout_source
);
150 sd_event_source_unref(m
->console_active_event_source
);
151 sd_event_source_unref(m
->udev_seat_event_source
);
152 sd_event_source_unref(m
->udev_device_event_source
);
153 sd_event_source_unref(m
->udev_vcsa_event_source
);
154 sd_event_source_unref(m
->udev_button_event_source
);
155 sd_event_source_unref(m
->lid_switch_ignore_event_source
);
157 safe_close(m
->console_active_fd
);
159 udev_monitor_unref(m
->udev_seat_monitor
);
160 udev_monitor_unref(m
->udev_device_monitor
);
161 udev_monitor_unref(m
->udev_vcsa_monitor
);
162 udev_monitor_unref(m
->udev_button_monitor
);
166 if (m
->unlink_nologin
)
167 (void) unlink("/run/nologin");
169 bus_verify_polkit_async_registry_free(m
->polkit_registry
);
171 sd_bus_unref(m
->bus
);
172 sd_event_unref(m
->event
);
174 safe_close(m
->reserve_vt_fd
);
176 strv_free(m
->kill_only_users
);
177 strv_free(m
->kill_exclude_users
);
179 free(m
->scheduled_shutdown_type
);
180 free(m
->scheduled_shutdown_tty
);
181 free(m
->wall_message
);
186 static int manager_enumerate_devices(Manager
*m
) {
187 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
188 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
193 /* Loads devices from udev and creates seats for them as
196 e
= udev_enumerate_new(m
->udev
);
200 r
= udev_enumerate_add_match_tag(e
, "master-of-seat");
204 r
= udev_enumerate_add_match_is_initialized(e
);
208 r
= udev_enumerate_scan_devices(e
);
212 first
= udev_enumerate_get_list_entry(e
);
213 udev_list_entry_foreach(item
, first
) {
214 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
217 d
= udev_device_new_from_syspath(m
->udev
, udev_list_entry_get_name(item
));
221 k
= manager_process_seat_device(m
, d
);
229 static int manager_enumerate_buttons(Manager
*m
) {
230 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
231 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
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
&&
242 m
->handle_lid_switch_docked
== HANDLE_IGNORE
)
245 e
= udev_enumerate_new(m
->udev
);
249 r
= udev_enumerate_add_match_subsystem(e
, "input");
253 r
= udev_enumerate_add_match_tag(e
, "power-switch");
257 r
= udev_enumerate_add_match_is_initialized(e
);
261 r
= udev_enumerate_scan_devices(e
);
265 first
= udev_enumerate_get_list_entry(e
);
266 udev_list_entry_foreach(item
, first
) {
267 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
270 d
= udev_device_new_from_syspath(m
->udev
, udev_list_entry_get_name(item
));
274 k
= manager_process_button_device(m
, d
);
282 static int manager_enumerate_seats(Manager
*m
) {
283 _cleanup_closedir_
DIR *d
= NULL
;
289 /* This loads data about seats stored on disk, but does not
290 * actually create any seats. Removes data of seats that no
293 d
= opendir("/run/systemd/seats");
298 log_error_errno(errno
, "Failed to open /run/systemd/seats: %m");
302 FOREACH_DIRENT(de
, d
, return -errno
) {
306 if (!dirent_is_file(de
))
309 s
= hashmap_get(m
->seats
, de
->d_name
);
311 unlinkat(dirfd(d
), de
->d_name
, 0);
323 static int manager_enumerate_linger_users(Manager
*m
) {
324 _cleanup_closedir_
DIR *d
= NULL
;
330 d
= opendir("/var/lib/systemd/linger");
335 log_error_errno(errno
, "Failed to open /var/lib/systemd/linger/: %m");
339 FOREACH_DIRENT(de
, d
, return -errno
) {
342 if (!dirent_is_file(de
))
345 k
= manager_add_user_by_name(m
, de
->d_name
, NULL
);
347 log_notice_errno(k
, "Couldn't add lingering user %s: %m", de
->d_name
);
355 static int manager_enumerate_users(Manager
*m
) {
356 _cleanup_closedir_
DIR *d
= NULL
;
362 /* Add lingering users */
363 r
= manager_enumerate_linger_users(m
);
365 /* Read in user data stored on disk */
366 d
= opendir("/run/systemd/users");
371 log_error_errno(errno
, "Failed to open /run/systemd/users: %m");
375 FOREACH_DIRENT(de
, d
, return -errno
) {
378 if (!dirent_is_file(de
))
381 k
= manager_add_user_by_name(m
, de
->d_name
, &u
);
383 log_error_errno(k
, "Failed to add user by file name %s: %m", de
->d_name
);
389 user_add_to_gc_queue(u
);
399 static int manager_enumerate_sessions(Manager
*m
) {
400 _cleanup_closedir_
DIR *d
= NULL
;
406 /* Read in session data stored on disk */
407 d
= opendir("/run/systemd/sessions");
412 log_error_errno(errno
, "Failed to open /run/systemd/sessions: %m");
416 FOREACH_DIRENT(de
, d
, return -errno
) {
420 if (!dirent_is_file(de
))
423 if (!session_id_valid(de
->d_name
)) {
424 log_warning("Invalid session file name '%s', ignoring.", de
->d_name
);
429 k
= manager_add_session(m
, de
->d_name
, &s
);
431 log_error_errno(k
, "Failed to add session by file name %s: %m", de
->d_name
);
437 session_add_to_gc_queue(s
);
447 static int manager_enumerate_inhibitors(Manager
*m
) {
448 _cleanup_closedir_
DIR *d
= NULL
;
454 d
= opendir("/run/systemd/inhibit");
459 log_error_errno(errno
, "Failed to open /run/systemd/inhibit: %m");
463 FOREACH_DIRENT(de
, d
, return -errno
) {
467 if (!dirent_is_file(de
))
470 k
= manager_add_inhibitor(m
, de
->d_name
, &i
);
472 log_notice_errno(k
, "Couldn't add inhibitor %s: %m", de
->d_name
);
477 k
= inhibitor_load(i
);
485 static int manager_dispatch_seat_udev(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
486 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
487 Manager
*m
= userdata
;
491 d
= udev_monitor_receive_device(m
->udev_seat_monitor
);
495 manager_process_seat_device(m
, d
);
499 static int manager_dispatch_device_udev(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
500 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
501 Manager
*m
= userdata
;
505 d
= udev_monitor_receive_device(m
->udev_device_monitor
);
509 manager_process_seat_device(m
, d
);
513 static int manager_dispatch_vcsa_udev(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
514 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
515 Manager
*m
= userdata
;
520 d
= udev_monitor_receive_device(m
->udev_vcsa_monitor
);
524 name
= udev_device_get_sysname(d
);
526 /* Whenever a VCSA device is removed try to reallocate our
527 * VTs, to make sure our auto VTs never go away. */
529 if (name
&& startswith(name
, "vcsa") && streq_ptr(udev_device_get_action(d
), "remove"))
530 seat_preallocate_vts(m
->seat0
);
535 static int manager_dispatch_button_udev(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
536 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
537 Manager
*m
= userdata
;
541 d
= udev_monitor_receive_device(m
->udev_button_monitor
);
545 manager_process_button_device(m
, d
);
549 static int manager_dispatch_console(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
550 Manager
*m
= userdata
;
554 assert(m
->console_active_fd
== fd
);
556 seat_read_active_vt(m
->seat0
);
560 static int manager_reserve_vt(Manager
*m
) {
561 _cleanup_free_
char *p
= NULL
;
565 if (m
->reserve_vt
<= 0)
568 if (asprintf(&p
, "/dev/tty%u", m
->reserve_vt
) < 0)
571 m
->reserve_vt_fd
= open(p
, O_RDWR
|O_NOCTTY
|O_CLOEXEC
|O_NONBLOCK
);
572 if (m
->reserve_vt_fd
< 0) {
574 /* Don't complain on VT-less systems */
576 log_warning_errno(errno
, "Failed to pin reserved VT: %m");
583 static int manager_connect_bus(Manager
*m
) {
584 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
590 r
= sd_bus_default_system(&m
->bus
);
592 return log_error_errno(r
, "Failed to connect to system bus: %m");
594 r
= sd_bus_add_object_vtable(m
->bus
, NULL
, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable
, m
);
596 return log_error_errno(r
, "Failed to add manager object vtable: %m");
598 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable
, seat_object_find
, m
);
600 return log_error_errno(r
, "Failed to add seat object vtable: %m");
602 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/login1/seat", seat_node_enumerator
, m
);
604 return log_error_errno(r
, "Failed to add seat enumerator: %m");
606 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable
, session_object_find
, m
);
608 return log_error_errno(r
, "Failed to add session object vtable: %m");
610 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/login1/session", session_node_enumerator
, m
);
612 return log_error_errno(r
, "Failed to add session enumerator: %m");
614 r
= sd_bus_add_fallback_vtable(m
->bus
, NULL
, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable
, user_object_find
, m
);
616 return log_error_errno(r
, "Failed to add user object vtable: %m");
618 r
= sd_bus_add_node_enumerator(m
->bus
, NULL
, "/org/freedesktop/login1/user", user_node_enumerator
, m
);
620 return log_error_errno(r
, "Failed to add user enumerator: %m");
622 r
= sd_bus_add_match(m
->bus
,
625 "sender='org.freedesktop.systemd1',"
626 "interface='org.freedesktop.systemd1.Manager',"
627 "member='JobRemoved',"
628 "path='/org/freedesktop/systemd1'",
629 match_job_removed
, m
);
631 return log_error_errno(r
, "Failed to add match for JobRemoved: %m");
633 r
= sd_bus_add_match(m
->bus
,
636 "sender='org.freedesktop.systemd1',"
637 "interface='org.freedesktop.systemd1.Manager',"
638 "member='UnitRemoved',"
639 "path='/org/freedesktop/systemd1'",
640 match_unit_removed
, m
);
642 return log_error_errno(r
, "Failed to add match for UnitRemoved: %m");
644 r
= sd_bus_add_match(m
->bus
,
647 "sender='org.freedesktop.systemd1',"
648 "interface='org.freedesktop.DBus.Properties',"
649 "member='PropertiesChanged'",
650 match_properties_changed
, m
);
652 return log_error_errno(r
, "Failed to add match for PropertiesChanged: %m");
654 r
= sd_bus_add_match(m
->bus
,
657 "sender='org.freedesktop.systemd1',"
658 "interface='org.freedesktop.systemd1.Manager',"
659 "member='Reloading',"
660 "path='/org/freedesktop/systemd1'",
663 return log_error_errno(r
, "Failed to add match for Reloading: %m");
665 r
= sd_bus_call_method(
667 "org.freedesktop.systemd1",
668 "/org/freedesktop/systemd1",
669 "org.freedesktop.systemd1.Manager",
674 log_error("Failed to enable subscription: %s", bus_error_message(&error
, r
));
678 r
= sd_bus_request_name(m
->bus
, "org.freedesktop.login1", 0);
680 return log_error_errno(r
, "Failed to register name: %m");
682 r
= sd_bus_attach_event(m
->bus
, m
->event
, 0);
684 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
689 static int manager_vt_switch(sd_event_source
*src
, const struct signalfd_siginfo
*si
, void *data
) {
691 Session
*active
, *iter
;
694 * We got a VT-switch signal and we have to acknowledge it immediately.
695 * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
696 * old user-space might run multiple sessions on a single VT, *sigh*.
697 * Therefore, we have to iterate all sessions and find one with a vtfd
698 * on the requested VT.
699 * As only VTs with active controllers have VT_PROCESS set, our current
700 * notion of the active VT might be wrong (for instance if the switch
701 * happens while we setup VT_PROCESS). Therefore, read the current VT
702 * first and then use s->active->vtnr as reference. Note that this is
703 * not racy, as no further VT-switch can happen as long as we're in
704 * synchronous VT_PROCESS mode.
708 seat_read_active_vt(m
->seat0
);
710 active
= m
->seat0
->active
;
711 if (!active
|| active
->vtnr
< 1) {
712 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
716 if (active
->vtfd
>= 0) {
717 session_leave_vt(active
);
719 LIST_FOREACH(sessions_by_seat
, iter
, m
->seat0
->sessions
) {
720 if (iter
->vtnr
== active
->vtnr
&& iter
->vtfd
>= 0) {
721 session_leave_vt(iter
);
730 static int manager_connect_console(Manager
*m
) {
734 assert(m
->console_active_fd
< 0);
736 /* On certain architectures (S390 and Xen, and containers),
737 /dev/tty0 does not exist, so don't fail if we can't open
739 if (access("/dev/tty0", F_OK
) < 0)
742 m
->console_active_fd
= open("/sys/class/tty/tty0/active", O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
743 if (m
->console_active_fd
< 0) {
745 /* On some systems the device node /dev/tty0 may exist
746 * even though /sys/class/tty/tty0 does not. */
750 log_error_errno(errno
, "Failed to open /sys/class/tty/tty0/active: %m");
754 r
= sd_event_add_io(m
->event
, &m
->console_active_event_source
, m
->console_active_fd
, 0, manager_dispatch_console
, m
);
756 log_error("Failed to watch foreground console");
761 * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
762 * as VT-acquire signal. We ignore any acquire-events (yes, we still
763 * have to provide a valid signal-number for it!) and acknowledge all
764 * release events immediately.
767 if (SIGRTMIN
+ 1 > SIGRTMAX
) {
768 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN
, SIGRTMAX
);
772 assert_se(ignore_signals(SIGRTMIN
+ 1, -1) >= 0);
773 assert_se(sigprocmask_many(SIG_BLOCK
, NULL
, SIGRTMIN
, -1) >= 0);
775 r
= sd_event_add_signal(m
->event
, NULL
, SIGRTMIN
, manager_vt_switch
, m
);
782 static int manager_connect_udev(Manager
*m
) {
786 assert(!m
->udev_seat_monitor
);
787 assert(!m
->udev_device_monitor
);
788 assert(!m
->udev_vcsa_monitor
);
789 assert(!m
->udev_button_monitor
);
791 m
->udev_seat_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev");
792 if (!m
->udev_seat_monitor
)
795 r
= udev_monitor_filter_add_match_tag(m
->udev_seat_monitor
, "master-of-seat");
799 r
= udev_monitor_enable_receiving(m
->udev_seat_monitor
);
803 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
);
807 m
->udev_device_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev");
808 if (!m
->udev_device_monitor
)
811 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_device_monitor
, "input", NULL
);
815 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_device_monitor
, "graphics", NULL
);
819 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_device_monitor
, "drm", NULL
);
823 r
= udev_monitor_enable_receiving(m
->udev_device_monitor
);
827 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
);
831 /* Don't watch keys if nobody cares */
832 if (m
->handle_power_key
!= HANDLE_IGNORE
||
833 m
->handle_suspend_key
!= HANDLE_IGNORE
||
834 m
->handle_hibernate_key
!= HANDLE_IGNORE
||
835 m
->handle_lid_switch
!= HANDLE_IGNORE
||
836 m
->handle_lid_switch_docked
!= HANDLE_IGNORE
) {
838 m
->udev_button_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev");
839 if (!m
->udev_button_monitor
)
842 r
= udev_monitor_filter_add_match_tag(m
->udev_button_monitor
, "power-switch");
846 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_button_monitor
, "input", NULL
);
850 r
= udev_monitor_enable_receiving(m
->udev_button_monitor
);
854 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
);
859 /* Don't bother watching VCSA devices, if nobody cares */
860 if (m
->n_autovts
> 0 && m
->console_active_fd
>= 0) {
862 m
->udev_vcsa_monitor
= udev_monitor_new_from_netlink(m
->udev
, "udev");
863 if (!m
->udev_vcsa_monitor
)
866 r
= udev_monitor_filter_add_match_subsystem_devtype(m
->udev_vcsa_monitor
, "vc", NULL
);
870 r
= udev_monitor_enable_receiving(m
->udev_vcsa_monitor
);
874 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
);
882 static void manager_gc(Manager
*m
, bool drop_not_started
) {
889 while ((seat
= m
->seat_gc_queue
)) {
890 LIST_REMOVE(gc_queue
, m
->seat_gc_queue
, seat
);
891 seat
->in_gc_queue
= false;
893 if (!seat_check_gc(seat
, drop_not_started
)) {
894 seat_stop(seat
, false);
899 while ((session
= m
->session_gc_queue
)) {
900 LIST_REMOVE(gc_queue
, m
->session_gc_queue
, session
);
901 session
->in_gc_queue
= false;
903 /* First, if we are not closing yet, initiate stopping */
904 if (!session_check_gc(session
, drop_not_started
) &&
905 session_get_state(session
) != SESSION_CLOSING
)
906 session_stop(session
, false);
908 /* Normally, this should make the session referenced
909 * again, if it doesn't then let's get rid of it
911 if (!session_check_gc(session
, drop_not_started
)) {
912 session_finalize(session
);
913 session_free(session
);
917 while ((user
= m
->user_gc_queue
)) {
918 LIST_REMOVE(gc_queue
, m
->user_gc_queue
, user
);
919 user
->in_gc_queue
= false;
921 /* First step: queue stop jobs */
922 if (!user_check_gc(user
, drop_not_started
))
923 user_stop(user
, false);
925 /* Second step: finalize user */
926 if (!user_check_gc(user
, drop_not_started
)) {
933 static int manager_dispatch_idle_action(sd_event_source
*s
, uint64_t t
, void *userdata
) {
934 Manager
*m
= userdata
;
935 struct dual_timestamp since
;
941 if (m
->idle_action
== HANDLE_IGNORE
||
942 m
->idle_action_usec
<= 0)
945 n
= now(CLOCK_MONOTONIC
);
947 r
= manager_get_idle_hint(m
, &since
);
949 /* Not idle. Let's check if after a timeout it might be idle then. */
950 elapse
= n
+ m
->idle_action_usec
;
952 /* Idle! Let's see if it's time to do something, or if
953 * we shall sleep for longer. */
955 if (n
>= since
.monotonic
+ m
->idle_action_usec
&&
956 (m
->idle_action_not_before_usec
<= 0 || n
>= m
->idle_action_not_before_usec
+ m
->idle_action_usec
)) {
957 log_info("System idle. Taking action.");
959 manager_handle_action(m
, 0, m
->idle_action
, false, false);
960 m
->idle_action_not_before_usec
= n
;
963 elapse
= MAX(since
.monotonic
, m
->idle_action_not_before_usec
) + m
->idle_action_usec
;
966 if (!m
->idle_action_event_source
) {
968 r
= sd_event_add_time(
970 &m
->idle_action_event_source
,
972 elapse
, USEC_PER_SEC
*30,
973 manager_dispatch_idle_action
, m
);
975 return log_error_errno(r
, "Failed to add idle event source: %m");
977 r
= sd_event_source_set_priority(m
->idle_action_event_source
, SD_EVENT_PRIORITY_IDLE
+10);
979 return log_error_errno(r
, "Failed to set idle event source priority: %m");
981 r
= sd_event_source_set_time(m
->idle_action_event_source
, elapse
);
983 return log_error_errno(r
, "Failed to set idle event timer: %m");
985 r
= sd_event_source_set_enabled(m
->idle_action_event_source
, SD_EVENT_ONESHOT
);
987 return log_error_errno(r
, "Failed to enable idle event timer: %m");
993 static int manager_startup(Manager
*m
) {
999 Inhibitor
*inhibitor
;
1004 /* Connect to console */
1005 r
= manager_connect_console(m
);
1009 /* Connect to udev */
1010 r
= manager_connect_udev(m
);
1012 return log_error_errno(r
, "Failed to create udev watchers: %m");
1014 /* Connect to the bus */
1015 r
= manager_connect_bus(m
);
1019 /* Instantiate magic seat 0 */
1020 r
= manager_add_seat(m
, "seat0", &m
->seat0
);
1022 return log_error_errno(r
, "Failed to add seat0: %m");
1024 r
= manager_set_lid_switch_ignore(m
, 0 + m
->holdoff_timeout_usec
);
1026 log_warning_errno(r
, "Failed to set up lid switch ignore event source: %m");
1028 /* Deserialize state */
1029 r
= manager_enumerate_devices(m
);
1031 log_warning_errno(r
, "Device enumeration failed: %m");
1033 r
= manager_enumerate_seats(m
);
1035 log_warning_errno(r
, "Seat enumeration failed: %m");
1037 r
= manager_enumerate_users(m
);
1039 log_warning_errno(r
, "User enumeration failed: %m");
1041 r
= manager_enumerate_sessions(m
);
1043 log_warning_errno(r
, "Session enumeration failed: %m");
1045 r
= manager_enumerate_inhibitors(m
);
1047 log_warning_errno(r
, "Inhibitor enumeration failed: %m");
1049 r
= manager_enumerate_buttons(m
);
1051 log_warning_errno(r
, "Button enumeration failed: %m");
1053 /* Remove stale objects before we start them */
1054 manager_gc(m
, false);
1056 /* Reserve the special reserved VT */
1057 manager_reserve_vt(m
);
1059 /* And start everything */
1060 HASHMAP_FOREACH(seat
, m
->seats
, i
)
1063 HASHMAP_FOREACH(user
, m
->users
, i
)
1066 HASHMAP_FOREACH(session
, m
->sessions
, i
)
1067 session_start(session
);
1069 HASHMAP_FOREACH(inhibitor
, m
->inhibitors
, i
)
1070 inhibitor_start(inhibitor
);
1072 HASHMAP_FOREACH(button
, m
->buttons
, i
)
1073 button_check_switches(button
);
1075 manager_dispatch_idle_action(NULL
, 0, m
);
1080 static int manager_run(Manager
*m
) {
1086 r
= sd_event_get_state(m
->event
);
1089 if (r
== SD_EVENT_FINISHED
)
1092 manager_gc(m
, true);
1094 r
= manager_dispatch_delayed(m
, false);
1100 r
= sd_event_run(m
->event
, (uint64_t) -1);
1106 static int manager_parse_config_file(Manager
*m
) {
1109 return config_parse_many("/etc/systemd/logind.conf",
1110 CONF_DIRS_NULSTR("systemd/logind.conf"),
1112 config_item_perf_lookup
, logind_gperf_lookup
,
1116 int main(int argc
, char *argv
[]) {
1120 log_set_target(LOG_TARGET_AUTO
);
1121 log_set_facility(LOG_AUTH
);
1122 log_parse_environment();
1128 log_error("This program takes no arguments.");
1133 /* Always create the directories people can create inotify
1134 * watches in. Note that some applications might check for the
1135 * existence of /run/systemd/seats/ to determine whether
1136 * logind is available, so please always make sure this check
1138 mkdir_label("/run/systemd/seats", 0755);
1139 mkdir_label("/run/systemd/users", 0755);
1140 mkdir_label("/run/systemd/sessions", 0755);
1148 manager_parse_config_file(m
);
1150 r
= manager_startup(m
);
1152 log_error_errno(r
, "Failed to fully start up daemon: %m");
1156 log_debug("systemd-logind running as pid "PID_FMT
, getpid());
1160 "STATUS=Processing requests...");
1164 log_debug("systemd-logind stopped as pid "PID_FMT
, getpid());
1169 "STATUS=Shutting down...");
1173 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;