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