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