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