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