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