]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind.c
util: split out signal-util.[ch] from util.[ch]
[thirdparty/systemd.git] / src / login / logind.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <errno.h>
23 #include <libudev.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include "sd-daemon.h"
29 #include "strv.h"
30 #include "conf-parser.h"
31 #include "bus-util.h"
32 #include "bus-error.h"
33 #include "udev-util.h"
34 #include "formats-util.h"
35 #include "signal-util.h"
36 #include "logind.h"
37
38 static void manager_free(Manager *m);
39
40 static Manager *manager_new(void) {
41 Manager *m;
42 int r;
43
44 m = new0(Manager, 1);
45 if (!m)
46 return NULL;
47
48 m->console_active_fd = -1;
49 m->reserve_vt_fd = -1;
50
51 m->n_autovts = 6;
52 m->reserve_vt = 6;
53 m->remove_ipc = true;
54 m->inhibit_delay_max = 5 * USEC_PER_SEC;
55 m->handle_power_key = HANDLE_POWEROFF;
56 m->handle_suspend_key = HANDLE_SUSPEND;
57 m->handle_hibernate_key = HANDLE_HIBERNATE;
58 m->handle_lid_switch = HANDLE_SUSPEND;
59 m->handle_lid_switch_docked = HANDLE_IGNORE;
60 m->lid_switch_ignore_inhibited = true;
61 m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
62
63 m->idle_action_usec = 30 * USEC_PER_MINUTE;
64 m->idle_action = HANDLE_IGNORE;
65 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
66
67 m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
68
69 m->devices = hashmap_new(&string_hash_ops);
70 m->seats = hashmap_new(&string_hash_ops);
71 m->sessions = hashmap_new(&string_hash_ops);
72 m->users = hashmap_new(NULL);
73 m->inhibitors = hashmap_new(&string_hash_ops);
74 m->buttons = hashmap_new(&string_hash_ops);
75
76 m->user_units = hashmap_new(&string_hash_ops);
77 m->session_units = hashmap_new(&string_hash_ops);
78
79 m->busnames = set_new(&string_hash_ops);
80
81 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
82 !m->user_units || !m->session_units)
83 goto fail;
84
85 m->kill_exclude_users = strv_new("root", NULL);
86 if (!m->kill_exclude_users)
87 goto fail;
88
89 m->udev = udev_new();
90 if (!m->udev)
91 goto fail;
92
93 r = sd_event_default(&m->event);
94 if (r < 0)
95 goto fail;
96
97 sd_event_set_watchdog(m->event, true);
98
99 return m;
100
101 fail:
102 manager_free(m);
103 return NULL;
104 }
105
106 static void manager_free(Manager *m) {
107 Session *session;
108 User *u;
109 Device *d;
110 Seat *s;
111 Inhibitor *i;
112 Button *b;
113
114 assert(m);
115
116 while ((session = hashmap_first(m->sessions)))
117 session_free(session);
118
119 while ((u = hashmap_first(m->users)))
120 user_free(u);
121
122 while ((d = hashmap_first(m->devices)))
123 device_free(d);
124
125 while ((s = hashmap_first(m->seats)))
126 seat_free(s);
127
128 while ((i = hashmap_first(m->inhibitors)))
129 inhibitor_free(i);
130
131 while ((b = hashmap_first(m->buttons)))
132 button_free(b);
133
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);
140
141 hashmap_free(m->user_units);
142 hashmap_free(m->session_units);
143
144 set_free_free(m->busnames);
145
146 sd_event_source_unref(m->idle_action_event_source);
147 sd_event_source_unref(m->inhibit_timeout_source);
148 sd_event_source_unref(m->scheduled_shutdown_timeout_source);
149 sd_event_source_unref(m->nologin_timeout_source);
150 sd_event_source_unref(m->wall_message_timeout_source);
151
152 sd_event_source_unref(m->console_active_event_source);
153 sd_event_source_unref(m->udev_seat_event_source);
154 sd_event_source_unref(m->udev_device_event_source);
155 sd_event_source_unref(m->udev_vcsa_event_source);
156 sd_event_source_unref(m->udev_button_event_source);
157 sd_event_source_unref(m->lid_switch_ignore_event_source);
158
159 safe_close(m->console_active_fd);
160
161 if (m->udev_seat_monitor)
162 udev_monitor_unref(m->udev_seat_monitor);
163 if (m->udev_device_monitor)
164 udev_monitor_unref(m->udev_device_monitor);
165 if (m->udev_vcsa_monitor)
166 udev_monitor_unref(m->udev_vcsa_monitor);
167 if (m->udev_button_monitor)
168 udev_monitor_unref(m->udev_button_monitor);
169
170 if (m->udev)
171 udev_unref(m->udev);
172
173 if (m->unlink_nologin)
174 (void) unlink("/run/nologin");
175
176 bus_verify_polkit_async_registry_free(m->polkit_registry);
177
178 sd_bus_unref(m->bus);
179 sd_event_unref(m->event);
180
181 safe_close(m->reserve_vt_fd);
182
183 strv_free(m->kill_only_users);
184 strv_free(m->kill_exclude_users);
185
186 free(m->scheduled_shutdown_type);
187 free(m->scheduled_shutdown_tty);
188 free(m->wall_message);
189 free(m->action_job);
190 free(m);
191 }
192
193 static int manager_enumerate_devices(Manager *m) {
194 struct udev_list_entry *item = NULL, *first = NULL;
195 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
196 int r;
197
198 assert(m);
199
200 /* Loads devices from udev and creates seats for them as
201 * necessary */
202
203 e = udev_enumerate_new(m->udev);
204 if (!e)
205 return -ENOMEM;
206
207 r = udev_enumerate_add_match_tag(e, "master-of-seat");
208 if (r < 0)
209 return r;
210
211 r = udev_enumerate_add_match_is_initialized(e);
212 if (r < 0)
213 return r;
214
215 r = udev_enumerate_scan_devices(e);
216 if (r < 0)
217 return r;
218
219 first = udev_enumerate_get_list_entry(e);
220 udev_list_entry_foreach(item, first) {
221 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
222 int k;
223
224 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
225 if (!d)
226 return -ENOMEM;
227
228 k = manager_process_seat_device(m, d);
229 if (k < 0)
230 r = k;
231 }
232
233 return r;
234 }
235
236 static int manager_enumerate_buttons(Manager *m) {
237 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
238 struct udev_list_entry *item = NULL, *first = NULL;
239 int r;
240
241 assert(m);
242
243 /* Loads buttons from udev */
244
245 if (m->handle_power_key == HANDLE_IGNORE &&
246 m->handle_suspend_key == HANDLE_IGNORE &&
247 m->handle_hibernate_key == HANDLE_IGNORE &&
248 m->handle_lid_switch == HANDLE_IGNORE &&
249 m->handle_lid_switch_docked == HANDLE_IGNORE)
250 return 0;
251
252 e = udev_enumerate_new(m->udev);
253 if (!e)
254 return -ENOMEM;
255
256 r = udev_enumerate_add_match_subsystem(e, "input");
257 if (r < 0)
258 return r;
259
260 r = udev_enumerate_add_match_tag(e, "power-switch");
261 if (r < 0)
262 return r;
263
264 r = udev_enumerate_add_match_is_initialized(e);
265 if (r < 0)
266 return r;
267
268 r = udev_enumerate_scan_devices(e);
269 if (r < 0)
270 return r;
271
272 first = udev_enumerate_get_list_entry(e);
273 udev_list_entry_foreach(item, first) {
274 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
275 int k;
276
277 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
278 if (!d)
279 return -ENOMEM;
280
281 k = manager_process_button_device(m, d);
282 if (k < 0)
283 r = k;
284 }
285
286 return r;
287 }
288
289 static int manager_enumerate_seats(Manager *m) {
290 _cleanup_closedir_ DIR *d = NULL;
291 struct dirent *de;
292 int r = 0;
293
294 assert(m);
295
296 /* This loads data about seats stored on disk, but does not
297 * actually create any seats. Removes data of seats that no
298 * longer exist. */
299
300 d = opendir("/run/systemd/seats");
301 if (!d) {
302 if (errno == ENOENT)
303 return 0;
304
305 log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
306 return -errno;
307 }
308
309 FOREACH_DIRENT(de, d, return -errno) {
310 Seat *s;
311 int k;
312
313 if (!dirent_is_file(de))
314 continue;
315
316 s = hashmap_get(m->seats, de->d_name);
317 if (!s) {
318 unlinkat(dirfd(d), de->d_name, 0);
319 continue;
320 }
321
322 k = seat_load(s);
323 if (k < 0)
324 r = k;
325 }
326
327 return r;
328 }
329
330 static int manager_enumerate_linger_users(Manager *m) {
331 _cleanup_closedir_ DIR *d = NULL;
332 struct dirent *de;
333 int r = 0;
334
335 assert(m);
336
337 d = opendir("/var/lib/systemd/linger");
338 if (!d) {
339 if (errno == ENOENT)
340 return 0;
341
342 log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
343 return -errno;
344 }
345
346 FOREACH_DIRENT(de, d, return -errno) {
347 int k;
348
349 if (!dirent_is_file(de))
350 continue;
351
352 k = manager_add_user_by_name(m, de->d_name, NULL);
353 if (k < 0) {
354 log_notice_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
355 r = k;
356 }
357 }
358
359 return r;
360 }
361
362 static int manager_enumerate_users(Manager *m) {
363 _cleanup_closedir_ DIR *d = NULL;
364 struct dirent *de;
365 int r, k;
366
367 assert(m);
368
369 /* Add lingering users */
370 r = manager_enumerate_linger_users(m);
371
372 /* Read in user data stored on disk */
373 d = opendir("/run/systemd/users");
374 if (!d) {
375 if (errno == ENOENT)
376 return 0;
377
378 log_error_errno(errno, "Failed to open /run/systemd/users: %m");
379 return -errno;
380 }
381
382 FOREACH_DIRENT(de, d, return -errno) {
383 User *u;
384
385 if (!dirent_is_file(de))
386 continue;
387
388 k = manager_add_user_by_name(m, de->d_name, &u);
389 if (k < 0) {
390 log_error_errno(k, "Failed to add user by file name %s: %m", de->d_name);
391
392 r = k;
393 continue;
394 }
395
396 user_add_to_gc_queue(u);
397
398 k = user_load(u);
399 if (k < 0)
400 r = k;
401 }
402
403 return r;
404 }
405
406 static int manager_enumerate_sessions(Manager *m) {
407 _cleanup_closedir_ DIR *d = NULL;
408 struct dirent *de;
409 int r = 0;
410
411 assert(m);
412
413 /* Read in session data stored on disk */
414 d = opendir("/run/systemd/sessions");
415 if (!d) {
416 if (errno == ENOENT)
417 return 0;
418
419 log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
420 return -errno;
421 }
422
423 FOREACH_DIRENT(de, d, return -errno) {
424 struct Session *s;
425 int k;
426
427 if (!dirent_is_file(de))
428 continue;
429
430 if (!session_id_valid(de->d_name)) {
431 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
432 r = -EINVAL;
433 continue;
434 }
435
436 k = manager_add_session(m, de->d_name, &s);
437 if (k < 0) {
438 log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
439
440 r = k;
441 continue;
442 }
443
444 session_add_to_gc_queue(s);
445
446 k = session_load(s);
447 if (k < 0)
448 r = k;
449 }
450
451 return r;
452 }
453
454 static int manager_enumerate_inhibitors(Manager *m) {
455 _cleanup_closedir_ DIR *d = NULL;
456 struct dirent *de;
457 int r = 0;
458
459 assert(m);
460
461 d = opendir("/run/systemd/inhibit");
462 if (!d) {
463 if (errno == ENOENT)
464 return 0;
465
466 log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
467 return -errno;
468 }
469
470 FOREACH_DIRENT(de, d, return -errno) {
471 int k;
472 Inhibitor *i;
473
474 if (!dirent_is_file(de))
475 continue;
476
477 k = manager_add_inhibitor(m, de->d_name, &i);
478 if (k < 0) {
479 log_notice_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
480 r = k;
481 continue;
482 }
483
484 k = inhibitor_load(i);
485 if (k < 0)
486 r = k;
487 }
488
489 return r;
490 }
491
492 static int manager_dispatch_seat_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;
495
496 assert(m);
497
498 d = udev_monitor_receive_device(m->udev_seat_monitor);
499 if (!d)
500 return -ENOMEM;
501
502 manager_process_seat_device(m, d);
503 return 0;
504 }
505
506 static int manager_dispatch_device_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;
509
510 assert(m);
511
512 d = udev_monitor_receive_device(m->udev_device_monitor);
513 if (!d)
514 return -ENOMEM;
515
516 manager_process_seat_device(m, d);
517 return 0;
518 }
519
520 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
521 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
522 Manager *m = userdata;
523 const char *name;
524
525 assert(m);
526
527 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
528 if (!d)
529 return -ENOMEM;
530
531 name = udev_device_get_sysname(d);
532
533 /* Whenever a VCSA device is removed try to reallocate our
534 * VTs, to make sure our auto VTs never go away. */
535
536 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
537 seat_preallocate_vts(m->seat0);
538
539 return 0;
540 }
541
542 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
543 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
544 Manager *m = userdata;
545
546 assert(m);
547
548 d = udev_monitor_receive_device(m->udev_button_monitor);
549 if (!d)
550 return -ENOMEM;
551
552 manager_process_button_device(m, d);
553 return 0;
554 }
555
556 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
557 Manager *m = userdata;
558
559 assert(m);
560 assert(m->seat0);
561 assert(m->console_active_fd == fd);
562
563 seat_read_active_vt(m->seat0);
564 return 0;
565 }
566
567 static int manager_reserve_vt(Manager *m) {
568 _cleanup_free_ char *p = NULL;
569
570 assert(m);
571
572 if (m->reserve_vt <= 0)
573 return 0;
574
575 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
576 return log_oom();
577
578 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
579 if (m->reserve_vt_fd < 0) {
580
581 /* Don't complain on VT-less systems */
582 if (errno != ENOENT)
583 log_warning_errno(errno, "Failed to pin reserved VT: %m");
584 return -errno;
585 }
586
587 return 0;
588 }
589
590 static int manager_connect_bus(Manager *m) {
591 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
592 int r;
593
594 assert(m);
595 assert(!m->bus);
596
597 r = sd_bus_default_system(&m->bus);
598 if (r < 0)
599 return log_error_errno(r, "Failed to connect to system bus: %m");
600
601 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
602 if (r < 0)
603 return log_error_errno(r, "Failed to add manager object vtable: %m");
604
605 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
606 if (r < 0)
607 return log_error_errno(r, "Failed to add seat object vtable: %m");
608
609 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
610 if (r < 0)
611 return log_error_errno(r, "Failed to add seat enumerator: %m");
612
613 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
614 if (r < 0)
615 return log_error_errno(r, "Failed to add session object vtable: %m");
616
617 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
618 if (r < 0)
619 return log_error_errno(r, "Failed to add session enumerator: %m");
620
621 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
622 if (r < 0)
623 return log_error_errno(r, "Failed to add user object vtable: %m");
624
625 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
626 if (r < 0)
627 return log_error_errno(r, "Failed to add user enumerator: %m");
628
629 r = sd_bus_add_match(m->bus,
630 NULL,
631 "type='signal',"
632 "sender='org.freedesktop.DBus',"
633 "interface='org.freedesktop.DBus',"
634 "member='NameOwnerChanged',"
635 "path='/org/freedesktop/DBus'",
636 match_name_owner_changed, m);
637 if (r < 0)
638 return log_error_errno(r, "Failed to add match for NameOwnerChanged: %m");
639
640 r = sd_bus_add_match(m->bus,
641 NULL,
642 "type='signal',"
643 "sender='org.freedesktop.systemd1',"
644 "interface='org.freedesktop.systemd1.Manager',"
645 "member='JobRemoved',"
646 "path='/org/freedesktop/systemd1'",
647 match_job_removed, m);
648 if (r < 0)
649 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
650
651 r = sd_bus_add_match(m->bus,
652 NULL,
653 "type='signal',"
654 "sender='org.freedesktop.systemd1',"
655 "interface='org.freedesktop.systemd1.Manager',"
656 "member='UnitRemoved',"
657 "path='/org/freedesktop/systemd1'",
658 match_unit_removed, m);
659 if (r < 0)
660 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
661
662 r = sd_bus_add_match(m->bus,
663 NULL,
664 "type='signal',"
665 "sender='org.freedesktop.systemd1',"
666 "interface='org.freedesktop.DBus.Properties',"
667 "member='PropertiesChanged'",
668 match_properties_changed, m);
669 if (r < 0)
670 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
671
672 r = sd_bus_add_match(m->bus,
673 NULL,
674 "type='signal',"
675 "sender='org.freedesktop.systemd1',"
676 "interface='org.freedesktop.systemd1.Manager',"
677 "member='Reloading',"
678 "path='/org/freedesktop/systemd1'",
679 match_reloading, m);
680 if (r < 0)
681 return log_error_errno(r, "Failed to add match for Reloading: %m");
682
683 r = sd_bus_call_method(
684 m->bus,
685 "org.freedesktop.systemd1",
686 "/org/freedesktop/systemd1",
687 "org.freedesktop.systemd1.Manager",
688 "Subscribe",
689 &error,
690 NULL, NULL);
691 if (r < 0) {
692 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
693 return r;
694 }
695
696 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
697 if (r < 0)
698 return log_error_errno(r, "Failed to register name: %m");
699
700 r = sd_bus_attach_event(m->bus, m->event, 0);
701 if (r < 0)
702 return log_error_errno(r, "Failed to attach bus to event loop: %m");
703
704 return 0;
705 }
706
707 static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
708 Manager *m = data;
709 Session *active, *iter;
710
711 /*
712 * We got a VT-switch signal and we have to acknowledge it immediately.
713 * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
714 * old user-space might run multiple sessions on a single VT, *sigh*.
715 * Therefore, we have to iterate all sessions and find one with a vtfd
716 * on the requested VT.
717 * As only VTs with active controllers have VT_PROCESS set, our current
718 * notion of the active VT might be wrong (for instance if the switch
719 * happens while we setup VT_PROCESS). Therefore, read the current VT
720 * first and then use s->active->vtnr as reference. Note that this is
721 * not racy, as no further VT-switch can happen as long as we're in
722 * synchronous VT_PROCESS mode.
723 */
724
725 assert(m->seat0);
726 seat_read_active_vt(m->seat0);
727
728 active = m->seat0->active;
729 if (!active || active->vtnr < 1) {
730 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
731 return 0;
732 }
733
734 if (active->vtfd >= 0) {
735 session_leave_vt(active);
736 } else {
737 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
738 if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
739 session_leave_vt(iter);
740 break;
741 }
742 }
743 }
744
745 return 0;
746 }
747
748 static int manager_connect_console(Manager *m) {
749 int r;
750
751 assert(m);
752 assert(m->console_active_fd < 0);
753
754 /* On certain architectures (S390 and Xen, and containers),
755 /dev/tty0 does not exist, so don't fail if we can't open
756 it. */
757 if (access("/dev/tty0", F_OK) < 0)
758 return 0;
759
760 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
761 if (m->console_active_fd < 0) {
762
763 /* On some systems the device node /dev/tty0 may exist
764 * even though /sys/class/tty/tty0 does not. */
765 if (errno == ENOENT)
766 return 0;
767
768 log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
769 return -errno;
770 }
771
772 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
773 if (r < 0) {
774 log_error("Failed to watch foreground console");
775 return r;
776 }
777
778 /*
779 * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
780 * as VT-acquire signal. We ignore any acquire-events (yes, we still
781 * have to provide a valid signal-number for it!) and acknowledge all
782 * release events immediately.
783 */
784
785 if (SIGRTMIN + 1 > SIGRTMAX) {
786 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
787 return -EINVAL;
788 }
789
790 r = ignore_signals(SIGRTMIN + 1, -1);
791 if (r < 0)
792 return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m");
793
794 r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
795 if (r < 0)
796 return log_error_errno(r, "Cannot block SIGRTMIN: %m");
797
798 r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
799 if (r < 0)
800 return r;
801
802 return 0;
803 }
804
805 static int manager_connect_udev(Manager *m) {
806 int r;
807
808 assert(m);
809 assert(!m->udev_seat_monitor);
810 assert(!m->udev_device_monitor);
811 assert(!m->udev_vcsa_monitor);
812 assert(!m->udev_button_monitor);
813
814 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
815 if (!m->udev_seat_monitor)
816 return -ENOMEM;
817
818 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
819 if (r < 0)
820 return r;
821
822 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
823 if (r < 0)
824 return r;
825
826 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);
827 if (r < 0)
828 return r;
829
830 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
831 if (!m->udev_device_monitor)
832 return -ENOMEM;
833
834 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
835 if (r < 0)
836 return r;
837
838 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
839 if (r < 0)
840 return r;
841
842 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
843 if (r < 0)
844 return r;
845
846 r = udev_monitor_enable_receiving(m->udev_device_monitor);
847 if (r < 0)
848 return r;
849
850 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);
851 if (r < 0)
852 return r;
853
854 /* Don't watch keys if nobody cares */
855 if (m->handle_power_key != HANDLE_IGNORE ||
856 m->handle_suspend_key != HANDLE_IGNORE ||
857 m->handle_hibernate_key != HANDLE_IGNORE ||
858 m->handle_lid_switch != HANDLE_IGNORE ||
859 m->handle_lid_switch_docked != HANDLE_IGNORE) {
860
861 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
862 if (!m->udev_button_monitor)
863 return -ENOMEM;
864
865 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
866 if (r < 0)
867 return r;
868
869 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
870 if (r < 0)
871 return r;
872
873 r = udev_monitor_enable_receiving(m->udev_button_monitor);
874 if (r < 0)
875 return r;
876
877 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);
878 if (r < 0)
879 return r;
880 }
881
882 /* Don't bother watching VCSA devices, if nobody cares */
883 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
884
885 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
886 if (!m->udev_vcsa_monitor)
887 return -ENOMEM;
888
889 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
890 if (r < 0)
891 return r;
892
893 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
894 if (r < 0)
895 return r;
896
897 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);
898 if (r < 0)
899 return r;
900 }
901
902 return 0;
903 }
904
905 static void manager_gc(Manager *m, bool drop_not_started) {
906 Seat *seat;
907 Session *session;
908 User *user;
909
910 assert(m);
911
912 while ((seat = m->seat_gc_queue)) {
913 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
914 seat->in_gc_queue = false;
915
916 if (!seat_check_gc(seat, drop_not_started)) {
917 seat_stop(seat, false);
918 seat_free(seat);
919 }
920 }
921
922 while ((session = m->session_gc_queue)) {
923 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
924 session->in_gc_queue = false;
925
926 /* First, if we are not closing yet, initiate stopping */
927 if (!session_check_gc(session, drop_not_started) &&
928 session_get_state(session) != SESSION_CLOSING)
929 session_stop(session, false);
930
931 /* Normally, this should make the session busy again,
932 * if it doesn't then let's get rid of it
933 * immediately */
934 if (!session_check_gc(session, drop_not_started)) {
935 session_finalize(session);
936 session_free(session);
937 }
938 }
939
940 while ((user = m->user_gc_queue)) {
941 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
942 user->in_gc_queue = false;
943
944 /* First step: queue stop jobs */
945 if (!user_check_gc(user, drop_not_started))
946 user_stop(user, false);
947
948 /* Second step: finalize user */
949 if (!user_check_gc(user, drop_not_started)) {
950 user_finalize(user);
951 user_free(user);
952 }
953 }
954 }
955
956 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
957 Manager *m = userdata;
958 struct dual_timestamp since;
959 usec_t n, elapse;
960 int r;
961
962 assert(m);
963
964 if (m->idle_action == HANDLE_IGNORE ||
965 m->idle_action_usec <= 0)
966 return 0;
967
968 n = now(CLOCK_MONOTONIC);
969
970 r = manager_get_idle_hint(m, &since);
971 if (r <= 0)
972 /* Not idle. Let's check if after a timeout it might be idle then. */
973 elapse = n + m->idle_action_usec;
974 else {
975 /* Idle! Let's see if it's time to do something, or if
976 * we shall sleep for longer. */
977
978 if (n >= since.monotonic + m->idle_action_usec &&
979 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
980 log_info("System idle. Taking action.");
981
982 manager_handle_action(m, 0, m->idle_action, false, false);
983 m->idle_action_not_before_usec = n;
984 }
985
986 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
987 }
988
989 if (!m->idle_action_event_source) {
990
991 r = sd_event_add_time(
992 m->event,
993 &m->idle_action_event_source,
994 CLOCK_MONOTONIC,
995 elapse, USEC_PER_SEC*30,
996 manager_dispatch_idle_action, m);
997 if (r < 0)
998 return log_error_errno(r, "Failed to add idle event source: %m");
999
1000 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
1001 if (r < 0)
1002 return log_error_errno(r, "Failed to set idle event source priority: %m");
1003 } else {
1004 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
1005 if (r < 0)
1006 return log_error_errno(r, "Failed to set idle event timer: %m");
1007
1008 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
1009 if (r < 0)
1010 return log_error_errno(r, "Failed to enable idle event timer: %m");
1011 }
1012
1013 return 0;
1014 }
1015
1016 static int manager_startup(Manager *m) {
1017 int r;
1018 Seat *seat;
1019 Session *session;
1020 User *user;
1021 Button *button;
1022 Inhibitor *inhibitor;
1023 Iterator i;
1024
1025 assert(m);
1026
1027 /* Connect to console */
1028 r = manager_connect_console(m);
1029 if (r < 0)
1030 return r;
1031
1032 /* Connect to udev */
1033 r = manager_connect_udev(m);
1034 if (r < 0)
1035 return log_error_errno(r, "Failed to create udev watchers: %m");
1036
1037 /* Connect to the bus */
1038 r = manager_connect_bus(m);
1039 if (r < 0)
1040 return r;
1041
1042 /* Instantiate magic seat 0 */
1043 r = manager_add_seat(m, "seat0", &m->seat0);
1044 if (r < 0)
1045 return log_error_errno(r, "Failed to add seat0: %m");
1046
1047 r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
1048 if (r < 0)
1049 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
1050
1051 /* Deserialize state */
1052 r = manager_enumerate_devices(m);
1053 if (r < 0)
1054 log_warning_errno(r, "Device enumeration failed: %m");
1055
1056 r = manager_enumerate_seats(m);
1057 if (r < 0)
1058 log_warning_errno(r, "Seat enumeration failed: %m");
1059
1060 r = manager_enumerate_users(m);
1061 if (r < 0)
1062 log_warning_errno(r, "User enumeration failed: %m");
1063
1064 r = manager_enumerate_sessions(m);
1065 if (r < 0)
1066 log_warning_errno(r, "Session enumeration failed: %m");
1067
1068 r = manager_enumerate_inhibitors(m);
1069 if (r < 0)
1070 log_warning_errno(r, "Inhibitor enumeration failed: %m");
1071
1072 r = manager_enumerate_buttons(m);
1073 if (r < 0)
1074 log_warning_errno(r, "Button enumeration failed: %m");
1075
1076 /* Remove stale objects before we start them */
1077 manager_gc(m, false);
1078
1079 /* Reserve the special reserved VT */
1080 manager_reserve_vt(m);
1081
1082 /* And start everything */
1083 HASHMAP_FOREACH(seat, m->seats, i)
1084 seat_start(seat);
1085
1086 HASHMAP_FOREACH(user, m->users, i)
1087 user_start(user);
1088
1089 HASHMAP_FOREACH(session, m->sessions, i)
1090 session_start(session);
1091
1092 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1093 inhibitor_start(inhibitor);
1094
1095 HASHMAP_FOREACH(button, m->buttons, i)
1096 button_check_switches(button);
1097
1098 manager_dispatch_idle_action(NULL, 0, m);
1099
1100 return 0;
1101 }
1102
1103 static int manager_run(Manager *m) {
1104 int r;
1105
1106 assert(m);
1107
1108 for (;;) {
1109 r = sd_event_get_state(m->event);
1110 if (r < 0)
1111 return r;
1112 if (r == SD_EVENT_FINISHED)
1113 return 0;
1114
1115 manager_gc(m, true);
1116
1117 r = sd_event_run(m->event, (uint64_t) -1);
1118 if (r < 0)
1119 return r;
1120 }
1121 }
1122
1123 static int manager_parse_config_file(Manager *m) {
1124 assert(m);
1125
1126 return config_parse_many("/etc/systemd/logind.conf",
1127 CONF_DIRS_NULSTR("systemd/logind.conf"),
1128 "Login\0",
1129 config_item_perf_lookup, logind_gperf_lookup,
1130 false, m);
1131 }
1132
1133 int main(int argc, char *argv[]) {
1134 Manager *m = NULL;
1135 int r;
1136
1137 log_set_target(LOG_TARGET_AUTO);
1138 log_set_facility(LOG_AUTH);
1139 log_parse_environment();
1140 log_open();
1141
1142 umask(0022);
1143
1144 if (argc != 1) {
1145 log_error("This program takes no arguments.");
1146 r = -EINVAL;
1147 goto finish;
1148 }
1149
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
1154 * stays in. */
1155 mkdir_label("/run/systemd/seats", 0755);
1156 mkdir_label("/run/systemd/users", 0755);
1157 mkdir_label("/run/systemd/sessions", 0755);
1158
1159 m = manager_new();
1160 if (!m) {
1161 r = log_oom();
1162 goto finish;
1163 }
1164
1165 manager_parse_config_file(m);
1166
1167 r = manager_startup(m);
1168 if (r < 0) {
1169 log_error_errno(r, "Failed to fully start up daemon: %m");
1170 goto finish;
1171 }
1172
1173 log_debug("systemd-logind running as pid "PID_FMT, getpid());
1174
1175 sd_notify(false,
1176 "READY=1\n"
1177 "STATUS=Processing requests...");
1178
1179 r = manager_run(m);
1180
1181 log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
1182
1183 finish:
1184 sd_notify(false,
1185 "STOPPING=1\n"
1186 "STATUS=Shutting down...");
1187
1188 if (m)
1189 manager_free(m);
1190
1191 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1192 }