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