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