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