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