]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind.c
hibernate-resume: add resumeflags= kernel option
[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 #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 = new(Manager, 1);
41 if (!m)
42 return -ENOMEM;
43
44 *m = (Manager) {
45 .console_active_fd = -1,
46 .reserve_vt_fd = -1,
47 };
48
49 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
50
51 m->devices = hashmap_new(&string_hash_ops);
52 m->seats = hashmap_new(&string_hash_ops);
53 m->sessions = hashmap_new(&string_hash_ops);
54 m->sessions_by_leader = hashmap_new(NULL);
55 m->users = hashmap_new(NULL);
56 m->inhibitors = hashmap_new(&string_hash_ops);
57 m->buttons = hashmap_new(&string_hash_ops);
58
59 m->user_units = hashmap_new(&string_hash_ops);
60 m->session_units = hashmap_new(&string_hash_ops);
61
62 if (!m->devices || !m->seats || !m->sessions || !m->sessions_by_leader || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
63 return -ENOMEM;
64
65 r = sd_event_default(&m->event);
66 if (r < 0)
67 return r;
68
69 r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
70 if (r < 0)
71 return r;
72
73 r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
74 if (r < 0)
75 return r;
76
77 (void) sd_event_set_watchdog(m->event, true);
78
79 manager_reset_config(m);
80
81 *ret = TAKE_PTR(m);
82 return 0;
83 }
84
85 static Manager* manager_unref(Manager *m) {
86 Session *session;
87 User *u;
88 Device *d;
89 Seat *s;
90 Inhibitor *i;
91 Button *b;
92
93 if (!m)
94 return NULL;
95
96 while ((session = hashmap_first(m->sessions)))
97 session_free(session);
98
99 while ((u = hashmap_first(m->users)))
100 user_free(u);
101
102 while ((d = hashmap_first(m->devices)))
103 device_free(d);
104
105 while ((s = hashmap_first(m->seats)))
106 seat_free(s);
107
108 while ((i = hashmap_first(m->inhibitors)))
109 inhibitor_free(i);
110
111 while ((b = hashmap_first(m->buttons)))
112 button_free(b);
113
114 hashmap_free(m->devices);
115 hashmap_free(m->seats);
116 hashmap_free(m->sessions);
117 hashmap_free(m->sessions_by_leader);
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->lid_switch_ignore_event_source);
133
134 #if ENABLE_UTMP
135 sd_event_source_unref(m->utmp_event_source);
136 #endif
137
138 safe_close(m->console_active_fd);
139
140 sd_device_monitor_unref(m->device_seat_monitor);
141 sd_device_monitor_unref(m->device_monitor);
142 sd_device_monitor_unref(m->device_vcsa_monitor);
143 sd_device_monitor_unref(m->device_button_monitor);
144
145 if (m->unlink_nologin)
146 (void) unlink_or_warn("/run/nologin");
147
148 bus_verify_polkit_async_registry_free(m->polkit_registry);
149
150 sd_bus_flush_close_unref(m->bus);
151 sd_event_unref(m->event);
152
153 safe_close(m->reserve_vt_fd);
154
155 strv_free(m->kill_only_users);
156 strv_free(m->kill_exclude_users);
157
158 free(m->scheduled_shutdown_type);
159 free(m->scheduled_shutdown_tty);
160 free(m->wall_message);
161 free(m->action_job);
162
163 return mfree(m);
164 }
165
166 static int manager_enumerate_devices(Manager *m) {
167 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
168 sd_device *d;
169 int r;
170
171 assert(m);
172
173 /* Loads devices from udev and creates seats for them as
174 * necessary */
175
176 r = sd_device_enumerator_new(&e);
177 if (r < 0)
178 return r;
179
180 r = sd_device_enumerator_add_match_tag(e, "master-of-seat");
181 if (r < 0)
182 return r;
183
184 FOREACH_DEVICE(e, d) {
185 int k;
186
187 k = manager_process_seat_device(m, d);
188 if (k < 0)
189 r = k;
190 }
191
192 return r;
193 }
194
195 static int manager_enumerate_buttons(Manager *m) {
196 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
197 sd_device *d;
198 int r;
199
200 assert(m);
201
202 /* Loads buttons from udev */
203
204 if (manager_all_buttons_ignored(m))
205 return 0;
206
207 r = sd_device_enumerator_new(&e);
208 if (r < 0)
209 return r;
210
211 r = sd_device_enumerator_add_match_subsystem(e, "input", true);
212 if (r < 0)
213 return r;
214
215 r = sd_device_enumerator_add_match_tag(e, "power-switch");
216 if (r < 0)
217 return r;
218
219 FOREACH_DEVICE(e, d) {
220 int k;
221
222 k = manager_process_button_device(m, d);
223 if (k < 0)
224 r = k;
225 }
226
227 return r;
228 }
229
230 static int manager_enumerate_seats(Manager *m) {
231 _cleanup_closedir_ DIR *d = NULL;
232 struct dirent *de;
233 int r = 0;
234
235 assert(m);
236
237 /* This loads data about seats stored on disk, but does not
238 * actually create any seats. Removes data of seats that no
239 * longer exist. */
240
241 d = opendir("/run/systemd/seats");
242 if (!d) {
243 if (errno == ENOENT)
244 return 0;
245
246 return log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
247 }
248
249 FOREACH_DIRENT(de, d, return -errno) {
250 Seat *s;
251 int k;
252
253 if (!dirent_is_file(de))
254 continue;
255
256 s = hashmap_get(m->seats, de->d_name);
257 if (!s) {
258 if (unlinkat(dirfd(d), de->d_name, 0) < 0)
259 log_warning("Failed to remove /run/systemd/seats/%s: %m",
260 de->d_name);
261 continue;
262 }
263
264 k = seat_load(s);
265 if (k < 0)
266 r = k;
267 }
268
269 return r;
270 }
271
272 static int manager_enumerate_linger_users(Manager *m) {
273 _cleanup_closedir_ DIR *d = NULL;
274 struct dirent *de;
275 int r = 0;
276
277 assert(m);
278
279 d = opendir("/var/lib/systemd/linger");
280 if (!d) {
281 if (errno == ENOENT)
282 return 0;
283
284 return log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
285 }
286
287 FOREACH_DIRENT(de, d, return -errno) {
288 int k;
289
290 if (!dirent_is_file(de))
291 continue;
292
293 k = manager_add_user_by_name(m, de->d_name, NULL);
294 if (k < 0) {
295 log_notice_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
296 r = k;
297 }
298 }
299
300 return r;
301 }
302
303 static int manager_enumerate_users(Manager *m) {
304 _cleanup_closedir_ DIR *d = NULL;
305 struct dirent *de;
306 int r, k;
307
308 assert(m);
309
310 /* Add lingering users */
311 r = manager_enumerate_linger_users(m);
312
313 /* Read in user data stored on disk */
314 d = opendir("/run/systemd/users");
315 if (!d) {
316 if (errno == ENOENT)
317 return 0;
318
319 return log_error_errno(errno, "Failed to open /run/systemd/users: %m");
320 }
321
322 FOREACH_DIRENT(de, d, return -errno) {
323 User *u;
324
325 if (!dirent_is_file(de))
326 continue;
327
328 k = manager_add_user_by_name(m, de->d_name, &u);
329 if (k < 0) {
330 log_error_errno(k, "Failed to add user by file name %s: %m", de->d_name);
331
332 r = k;
333 continue;
334 }
335
336 user_add_to_gc_queue(u);
337
338 k = user_load(u);
339 if (k < 0)
340 r = k;
341 }
342
343 return r;
344 }
345
346 static int parse_fdname(const char *fdname, char **session_id, dev_t *dev) {
347 _cleanup_strv_free_ char **parts = NULL;
348 _cleanup_free_ char *id = NULL;
349 unsigned major, minor;
350 int r;
351
352 parts = strv_split(fdname, "-");
353 if (!parts)
354 return -ENOMEM;
355 if (strv_length(parts) != 5)
356 return -EINVAL;
357
358 if (!streq(parts[0], "session"))
359 return -EINVAL;
360
361 id = strdup(parts[1]);
362 if (!id)
363 return -ENOMEM;
364
365 if (!streq(parts[2], "device"))
366 return -EINVAL;
367
368 r = safe_atou(parts[3], &major);
369 if (r < 0)
370 return r;
371 r = safe_atou(parts[4], &minor);
372 if (r < 0)
373 return r;
374
375 *dev = makedev(major, minor);
376 *session_id = TAKE_PTR(id);
377
378 return 0;
379 }
380
381 static int deliver_fd(Manager *m, const char *fdname, int fd) {
382 _cleanup_free_ char *id = NULL;
383 SessionDevice *sd;
384 struct stat st;
385 Session *s;
386 dev_t dev;
387 int r;
388
389 assert(m);
390 assert(fd >= 0);
391
392 r = parse_fdname(fdname, &id, &dev);
393 if (r < 0)
394 return log_debug_errno(r, "Failed to parse fd name %s: %m", fdname);
395
396 s = hashmap_get(m->sessions, id);
397 if (!s)
398 /* If the session doesn't exist anymore, the associated session device attached to this fd
399 * doesn't either. Let's simply close this fd. */
400 return log_debug_errno(SYNTHETIC_ERRNO(ENXIO), "Failed to attach fd for unknown session: %s", id);
401
402 if (fstat(fd, &st) < 0)
403 /* The device is allowed to go away at a random point, in which case fstat() failing is
404 * expected. */
405 return log_debug_errno(errno, "Failed to stat device fd for session %s: %m", id);
406
407 if (!S_ISCHR(st.st_mode) || st.st_rdev != dev)
408 return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "Device fd doesn't point to the expected character device node");
409
410 sd = hashmap_get(s->devices, &dev);
411 if (!sd)
412 /* Weird, we got an fd for a session device which wasn't recorded in the session state
413 * file... */
414 return log_warning_errno(SYNTHETIC_ERRNO(ENODEV), "Got fd for missing session device [%u:%u] in session %s",
415 major(dev), minor(dev), s->id);
416
417 log_debug("Attaching fd to session device [%u:%u] for session %s",
418 major(dev), minor(dev), s->id);
419
420 session_device_attach_fd(sd, fd, s->was_active);
421 return 0;
422 }
423
424 static int manager_attach_fds(Manager *m) {
425 _cleanup_strv_free_ char **fdnames = NULL;
426 int n;
427
428 /* Upon restart, PID1 will send us back all fds of session devices that we previously opened. Each
429 * file descriptor is associated with a given session. The session ids are passed through FDNAMES. */
430
431 n = sd_listen_fds_with_names(true, &fdnames);
432 if (n < 0)
433 return log_warning_errno(n, "Failed to acquire passed fd list: %m");
434 if (n == 0)
435 return 0;
436
437 for (int i = 0; i < n; i++) {
438 int fd = SD_LISTEN_FDS_START + i;
439
440 if (deliver_fd(m, fdnames[i], fd) >= 0)
441 continue;
442
443 /* Hmm, we couldn't deliver the fd to any session device object? If so, let's close the fd */
444 safe_close(fd);
445
446 /* Remove from fdstore as well */
447 (void) sd_notifyf(false,
448 "FDSTOREREMOVE=1\n"
449 "FDNAME=%s", fdnames[i]);
450 }
451
452 return 0;
453 }
454
455 static int manager_enumerate_sessions(Manager *m) {
456 _cleanup_closedir_ DIR *d = NULL;
457 struct dirent *de;
458 int r = 0, k;
459
460 assert(m);
461
462 /* Read in session data stored on disk */
463 d = opendir("/run/systemd/sessions");
464 if (!d) {
465 if (errno == ENOENT)
466 return 0;
467
468 return log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
469 }
470
471 FOREACH_DIRENT(de, d, return -errno) {
472 struct Session *s;
473
474 if (!dirent_is_file(de))
475 continue;
476
477 if (!session_id_valid(de->d_name)) {
478 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
479 r = -EINVAL;
480 continue;
481 }
482
483 k = manager_add_session(m, de->d_name, &s);
484 if (k < 0) {
485 log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
486 r = k;
487 continue;
488 }
489
490 session_add_to_gc_queue(s);
491
492 k = session_load(s);
493 if (k < 0)
494 r = k;
495 }
496
497 /* We might be restarted and PID1 could have sent us back the session device fds we previously
498 * saved. */
499 (void) manager_attach_fds(m);
500
501 return r;
502 }
503
504 static int manager_enumerate_inhibitors(Manager *m) {
505 _cleanup_closedir_ DIR *d = NULL;
506 struct dirent *de;
507 int r = 0;
508
509 assert(m);
510
511 d = opendir("/run/systemd/inhibit");
512 if (!d) {
513 if (errno == ENOENT)
514 return 0;
515
516 return log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
517 }
518
519 FOREACH_DIRENT(de, d, return -errno) {
520 int k;
521 Inhibitor *i;
522
523 if (!dirent_is_file(de))
524 continue;
525
526 k = manager_add_inhibitor(m, de->d_name, &i);
527 if (k < 0) {
528 log_notice_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
529 r = k;
530 continue;
531 }
532
533 k = inhibitor_load(i);
534 if (k < 0)
535 r = k;
536 }
537
538 return r;
539 }
540
541 static int manager_dispatch_seat_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
542 Manager *m = userdata;
543
544 assert(m);
545 assert(device);
546
547 manager_process_seat_device(m, device);
548 return 0;
549 }
550
551 static int manager_dispatch_device_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
552 Manager *m = userdata;
553
554 assert(m);
555 assert(device);
556
557 manager_process_seat_device(m, device);
558 return 0;
559 }
560
561 static int manager_dispatch_vcsa_udev(sd_device_monitor *monitor, sd_device *device, void *userdata) {
562 Manager *m = userdata;
563 const char *name;
564
565 assert(m);
566 assert(device);
567
568 /* Whenever a VCSA device is removed try to reallocate our
569 * VTs, to make sure our auto VTs never go away. */
570
571 if (sd_device_get_sysname(device, &name) >= 0 &&
572 startswith(name, "vcsa") &&
573 device_for_action(device, DEVICE_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 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
829 "Not enough real-time signals available: %u-%u",
830 SIGRTMIN, SIGRTMAX);
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);