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