]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind.c
logind: automatically remove SysV + POSIX IPC objects when the users owning them...
[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 if (m->console_active_fd >= 0)
153 close_nointr_nofail(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->bus, m->polkit_registry);
168
169 sd_bus_unref(m->bus);
170 sd_event_unref(m->event);
171
172 if (m->reserve_vt_fd >= 0)
173 close_nointr_nofail(m->reserve_vt_fd);
174
175 strv_free(m->kill_only_users);
176 strv_free(m->kill_exclude_users);
177
178 free(m->action_job);
179 free(m);
180 }
181
182 static int manager_enumerate_devices(Manager *m) {
183 struct udev_list_entry *item = NULL, *first = NULL;
184 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
185 int r;
186
187 assert(m);
188
189 /* Loads devices from udev and creates seats for them as
190 * necessary */
191
192 e = udev_enumerate_new(m->udev);
193 if (!e)
194 return -ENOMEM;
195
196 r = udev_enumerate_add_match_tag(e, "master-of-seat");
197 if (r < 0)
198 return r;
199
200 r = udev_enumerate_add_match_is_initialized(e);
201 if (r < 0)
202 return r;
203
204 r = udev_enumerate_scan_devices(e);
205 if (r < 0)
206 return r;
207
208 first = udev_enumerate_get_list_entry(e);
209 udev_list_entry_foreach(item, first) {
210 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
211 int k;
212
213 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
214 if (!d)
215 return -ENOMEM;
216
217 k = manager_process_seat_device(m, d);
218 if (k < 0)
219 r = k;
220 }
221
222 return r;
223 }
224
225 static int manager_enumerate_buttons(Manager *m) {
226 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
227 struct udev_list_entry *item = NULL, *first = NULL;
228 int r;
229
230 assert(m);
231
232 /* Loads buttons from udev */
233
234 if (m->handle_power_key == HANDLE_IGNORE &&
235 m->handle_suspend_key == HANDLE_IGNORE &&
236 m->handle_hibernate_key == HANDLE_IGNORE &&
237 m->handle_lid_switch == 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("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("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("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
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("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("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
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("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("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
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("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("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
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("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 log_error("Failed to connect to system bus: %s", strerror(-r));
588 return r;
589 }
590
591 r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
592 if (r < 0) {
593 log_error("Failed to add manager object vtable: %s", strerror(-r));
594 return r;
595 }
596
597 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
598 if (r < 0) {
599 log_error("Failed to add seat object vtable: %s", strerror(-r));
600 return r;
601 }
602
603 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
604 if (r < 0) {
605 log_error("Failed to add seat enumerator: %s", strerror(-r));
606 return r;
607 }
608
609 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
610 if (r < 0) {
611 log_error("Failed to add session object vtable: %s", strerror(-r));
612 return r;
613 }
614
615 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/session", session_node_enumerator, m);
616 if (r < 0) {
617 log_error("Failed to add session enumerator: %s", strerror(-r));
618 return r;
619 }
620
621 r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
622 if (r < 0) {
623 log_error("Failed to add user object vtable: %s", strerror(-r));
624 return r;
625 }
626
627 r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/user", user_node_enumerator, m);
628 if (r < 0) {
629 log_error("Failed to add user enumerator: %s", strerror(-r));
630 return r;
631 }
632
633 r = sd_bus_add_match(m->bus,
634 "type='signal',"
635 "sender='org.freedesktop.DBus',"
636 "interface='org.freedesktop.DBus',"
637 "member='NameOwnerChanged',"
638 "path='/org/freedesktop/DBus'",
639 match_name_owner_changed, m);
640 if (r < 0) {
641 log_error("Failed to add match for NameOwnerChanged: %s", strerror(-r));
642 return r;
643 }
644
645 r = sd_bus_add_match(m->bus,
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 "type='signal',"
659 "sender='org.freedesktop.systemd1',"
660 "interface='org.freedesktop.systemd1.Manager',"
661 "member='UnitRemoved',"
662 "path='/org/freedesktop/systemd1'",
663 match_unit_removed, m);
664 if (r < 0) {
665 log_error("Failed to add match for UnitRemoved: %s", strerror(-r));
666 return r;
667 }
668
669 r = sd_bus_add_match(m->bus,
670 "type='signal',"
671 "sender='org.freedesktop.systemd1',"
672 "interface='org.freedesktop.DBus.Properties',"
673 "member='PropertiesChanged'",
674 match_properties_changed, m);
675 if (r < 0) {
676 log_error("Failed to add match for PropertiesChanged: %s", strerror(-r));
677 return r;
678 }
679
680 r = sd_bus_add_match(m->bus,
681 "type='signal',"
682 "sender='org.freedesktop.systemd1',"
683 "interface='org.freedesktop.systemd1.Manager',"
684 "member='Reloading',"
685 "path='/org/freedesktop/systemd1'",
686 match_reloading, m);
687 if (r < 0) {
688 log_error("Failed to add match for Reloading: %s", strerror(-r));
689 return r;
690 }
691
692 r = sd_bus_call_method(
693 m->bus,
694 "org.freedesktop.systemd1",
695 "/org/freedesktop/systemd1",
696 "org.freedesktop.systemd1.Manager",
697 "Subscribe",
698 &error,
699 NULL, NULL);
700 if (r < 0) {
701 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
702 return r;
703 }
704
705 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
706 if (r < 0) {
707 log_error("Failed to register name: %s", strerror(-r));
708 return r;
709 }
710
711 r = sd_bus_attach_event(m->bus, m->event, 0);
712 if (r < 0) {
713 log_error("Failed to attach bus to event loop: %s", strerror(-r));
714 return r;
715 }
716
717 return 0;
718 }
719
720 static int manager_connect_console(Manager *m) {
721 int r;
722
723 assert(m);
724 assert(m->console_active_fd < 0);
725
726 /* On certain architectures (S390 and Xen, and containers),
727 /dev/tty0 does not exist, so don't fail if we can't open
728 it. */
729 if (access("/dev/tty0", F_OK) < 0)
730 return 0;
731
732 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
733 if (m->console_active_fd < 0) {
734
735 /* On some systems the device node /dev/tty0 may exist
736 * even though /sys/class/tty/tty0 does not. */
737 if (errno == ENOENT)
738 return 0;
739
740 log_error("Failed to open /sys/class/tty/tty0/active: %m");
741 return -errno;
742 }
743
744 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
745 if (r < 0) {
746 log_error("Failed to watch foreground console");
747 return r;
748 }
749
750 return 0;
751 }
752
753 static int manager_connect_udev(Manager *m) {
754 int r;
755
756 assert(m);
757 assert(!m->udev_seat_monitor);
758 assert(!m->udev_device_monitor);
759 assert(!m->udev_vcsa_monitor);
760 assert(!m->udev_button_monitor);
761
762 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
763 if (!m->udev_seat_monitor)
764 return -ENOMEM;
765
766 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
767 if (r < 0)
768 return r;
769
770 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
771 if (r < 0)
772 return r;
773
774 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);
775 if (r < 0)
776 return r;
777
778 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
779 if (!m->udev_device_monitor)
780 return -ENOMEM;
781
782 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
783 if (r < 0)
784 return r;
785
786 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
787 if (r < 0)
788 return r;
789
790 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
791 if (r < 0)
792 return r;
793
794 r = udev_monitor_enable_receiving(m->udev_device_monitor);
795 if (r < 0)
796 return r;
797
798 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);
799 if (r < 0)
800 return r;
801
802 /* Don't watch keys if nobody cares */
803 if (m->handle_power_key != HANDLE_IGNORE ||
804 m->handle_suspend_key != HANDLE_IGNORE ||
805 m->handle_hibernate_key != HANDLE_IGNORE ||
806 m->handle_lid_switch != HANDLE_IGNORE) {
807
808 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
809 if (!m->udev_button_monitor)
810 return -ENOMEM;
811
812 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
813 if (r < 0)
814 return r;
815
816 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
817 if (r < 0)
818 return r;
819
820 r = udev_monitor_enable_receiving(m->udev_button_monitor);
821 if (r < 0)
822 return r;
823
824 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);
825 if (r < 0)
826 return r;
827 }
828
829 /* Don't bother watching VCSA devices, if nobody cares */
830 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
831
832 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
833 if (!m->udev_vcsa_monitor)
834 return -ENOMEM;
835
836 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
837 if (r < 0)
838 return r;
839
840 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
841 if (r < 0)
842 return r;
843
844 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);
845 if (r < 0)
846 return r;
847 }
848
849 return 0;
850 }
851
852 void manager_gc(Manager *m, bool drop_not_started) {
853 Seat *seat;
854 Session *session;
855 User *user;
856
857 assert(m);
858
859 while ((seat = m->seat_gc_queue)) {
860 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
861 seat->in_gc_queue = false;
862
863 if (!seat_check_gc(seat, drop_not_started)) {
864 seat_stop(seat, false);
865 seat_free(seat);
866 }
867 }
868
869 while ((session = m->session_gc_queue)) {
870 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
871 session->in_gc_queue = false;
872
873 /* First, if we are not closing yet, initiate stopping */
874 if (!session_check_gc(session, drop_not_started) &&
875 session_get_state(session) != SESSION_CLOSING)
876 session_stop(session, false);
877
878 /* Normally, this should make the session busy again,
879 * if it doesn't then let's get rid of it
880 * immediately */
881 if (!session_check_gc(session, drop_not_started)) {
882 session_finalize(session);
883 session_free(session);
884 }
885 }
886
887 while ((user = m->user_gc_queue)) {
888 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
889 user->in_gc_queue = false;
890
891 /* First step: queue stop jobs */
892 if (!user_check_gc(user, drop_not_started))
893 user_stop(user, false);
894
895 /* Second step: finalize user */
896 if (!user_check_gc(user, drop_not_started)) {
897 user_finalize(user);
898 user_free(user);
899 }
900 }
901 }
902
903 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
904 Manager *m = userdata;
905 struct dual_timestamp since;
906 usec_t n, elapse;
907 int r;
908
909 assert(m);
910
911 if (m->idle_action == HANDLE_IGNORE ||
912 m->idle_action_usec <= 0)
913 return 0;
914
915 n = now(CLOCK_MONOTONIC);
916
917 r = manager_get_idle_hint(m, &since);
918 if (r <= 0)
919 /* Not idle. Let's check if after a timeout it might be idle then. */
920 elapse = n + m->idle_action_usec;
921 else {
922 /* Idle! Let's see if it's time to do something, or if
923 * we shall sleep for longer. */
924
925 if (n >= since.monotonic + m->idle_action_usec &&
926 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
927 log_info("System idle. Taking action.");
928
929 manager_handle_action(m, 0, m->idle_action, false, false);
930 m->idle_action_not_before_usec = n;
931 }
932
933 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
934 }
935
936 if (!m->idle_action_event_source) {
937
938 r = sd_event_add_monotonic(m->event, &m->idle_action_event_source, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m);
939 if (r < 0) {
940 log_error("Failed to add idle event source: %s", strerror(-r));
941 return r;
942 }
943
944 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
945 if (r < 0) {
946 log_error("Failed to set idle event source priority: %s", strerror(-r));
947 return r;
948 }
949 } else {
950 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
951 if (r < 0) {
952 log_error("Failed to set idle event timer: %s", strerror(-r));
953 return r;
954 }
955
956 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
957 if (r < 0) {
958 log_error("Failed to enable idle event timer: %s", strerror(-r));
959 return r;
960 }
961 }
962
963 return 0;
964 }
965
966 int manager_startup(Manager *m) {
967 int r;
968 Seat *seat;
969 Session *session;
970 User *user;
971 Button *button;
972 Inhibitor *inhibitor;
973 Iterator i;
974
975 assert(m);
976
977 /* Connect to console */
978 r = manager_connect_console(m);
979 if (r < 0)
980 return r;
981
982 /* Connect to udev */
983 r = manager_connect_udev(m);
984 if (r < 0) {
985 log_error("Failed to create udev watchers: %s", strerror(-r));
986 return r;
987 }
988
989 /* Connect to the bus */
990 r = manager_connect_bus(m);
991 if (r < 0)
992 return r;
993
994 /* Instantiate magic seat 0 */
995 r = manager_add_seat(m, "seat0", &m->seat0);
996 if (r < 0) {
997 log_error("Failed to add seat0: %s", strerror(-r));
998 return r;
999 }
1000
1001 r = manager_set_lid_switch_ignore(m, 0 + IGNORE_LID_SWITCH_STARTUP_USEC);
1002 if (r < 0)
1003 log_warning("Failed to set up lid switch ignore event source: %s", strerror(-r));
1004
1005 /* Deserialize state */
1006 r = manager_enumerate_devices(m);
1007 if (r < 0)
1008 log_warning("Device enumeration failed: %s", strerror(-r));
1009
1010 r = manager_enumerate_seats(m);
1011 if (r < 0)
1012 log_warning("Seat enumeration failed: %s", strerror(-r));
1013
1014 r = manager_enumerate_users(m);
1015 if (r < 0)
1016 log_warning("User enumeration failed: %s", strerror(-r));
1017
1018 r = manager_enumerate_sessions(m);
1019 if (r < 0)
1020 log_warning("Session enumeration failed: %s", strerror(-r));
1021
1022 r = manager_enumerate_inhibitors(m);
1023 if (r < 0)
1024 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1025
1026 r = manager_enumerate_buttons(m);
1027 if (r < 0)
1028 log_warning("Button enumeration failed: %s", strerror(-r));
1029
1030 /* Remove stale objects before we start them */
1031 manager_gc(m, false);
1032
1033 /* Reserve the special reserved VT */
1034 manager_reserve_vt(m);
1035
1036 /* And start everything */
1037 HASHMAP_FOREACH(seat, m->seats, i)
1038 seat_start(seat);
1039
1040 HASHMAP_FOREACH(user, m->users, i)
1041 user_start(user);
1042
1043 HASHMAP_FOREACH(session, m->sessions, i)
1044 session_start(session);
1045
1046 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1047 inhibitor_start(inhibitor);
1048
1049 HASHMAP_FOREACH(button, m->buttons, i)
1050 button_check_switches(button);
1051
1052 manager_dispatch_idle_action(NULL, 0, m);
1053
1054 return 0;
1055 }
1056
1057 int manager_run(Manager *m) {
1058 int r;
1059
1060 assert(m);
1061
1062 for (;;) {
1063 usec_t us = (uint64_t) -1;
1064
1065 r = sd_event_get_state(m->event);
1066 if (r < 0)
1067 return r;
1068 if (r == SD_EVENT_FINISHED)
1069 return 0;
1070
1071 manager_gc(m, true);
1072
1073 if (manager_dispatch_delayed(m) > 0)
1074 continue;
1075
1076 if (m->action_what != 0 && !m->action_job) {
1077 usec_t x, y;
1078
1079 x = now(CLOCK_MONOTONIC);
1080 y = m->action_timestamp + m->inhibit_delay_max;
1081
1082 us = x >= y ? 0 : y - x;
1083 }
1084
1085 r = sd_event_run(m->event, us);
1086 if (r < 0)
1087 return r;
1088 }
1089 }
1090
1091 static int manager_parse_config_file(Manager *m) {
1092 static const char fn[] = "/etc/systemd/logind.conf";
1093 _cleanup_fclose_ FILE *f = NULL;
1094 int r;
1095
1096 assert(m);
1097
1098 f = fopen(fn, "re");
1099 if (!f) {
1100 if (errno == ENOENT)
1101 return 0;
1102
1103 log_warning("Failed to open configuration file %s: %m", fn);
1104 return -errno;
1105 }
1106
1107 r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1108 (void*) logind_gperf_lookup, false, false, m);
1109 if (r < 0)
1110 log_warning("Failed to parse configuration file: %s", strerror(-r));
1111
1112 return r;
1113 }
1114
1115 int main(int argc, char *argv[]) {
1116 Manager *m = NULL;
1117 int r;
1118
1119 log_set_target(LOG_TARGET_AUTO);
1120 log_set_facility(LOG_AUTH);
1121 log_parse_environment();
1122 log_open();
1123
1124 umask(0022);
1125
1126 if (argc != 1) {
1127 log_error("This program takes no arguments.");
1128 r = -EINVAL;
1129 goto finish;
1130 }
1131
1132 /* Always create the directories people can create inotify
1133 * watches in. Note that some applications might check for the
1134 * existence of /run/systemd/seats/ to determine whether
1135 * logind is available, so please always make sure this check
1136 * stays in. */
1137 mkdir_label("/run/systemd/seats", 0755);
1138 mkdir_label("/run/systemd/users", 0755);
1139 mkdir_label("/run/systemd/sessions", 0755);
1140
1141 m = manager_new();
1142 if (!m) {
1143 r = log_oom();
1144 goto finish;
1145 }
1146
1147 manager_parse_config_file(m);
1148
1149 r = manager_startup(m);
1150 if (r < 0) {
1151 log_error("Failed to fully start up daemon: %s", strerror(-r));
1152 goto finish;
1153 }
1154
1155 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1156
1157 sd_notify(false,
1158 "READY=1\n"
1159 "STATUS=Processing requests...");
1160
1161 r = manager_run(m);
1162
1163 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1164
1165 finish:
1166 sd_notify(false,
1167 "STATUS=Shutting down...");
1168
1169 if (m)
1170 manager_free(m);
1171
1172 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1173 }