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