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