]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind.c
logind: add code for UTMP wall messages
[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 sd_event_source_unref(m->wall_message_timeout_source);
149
150 sd_event_source_unref(m->console_active_event_source);
151 sd_event_source_unref(m->udev_seat_event_source);
152 sd_event_source_unref(m->udev_device_event_source);
153 sd_event_source_unref(m->udev_vcsa_event_source);
154 sd_event_source_unref(m->udev_button_event_source);
155 sd_event_source_unref(m->lid_switch_ignore_event_source);
156
157 safe_close(m->console_active_fd);
158
159 if (m->udev_seat_monitor)
160 udev_monitor_unref(m->udev_seat_monitor);
161 if (m->udev_device_monitor)
162 udev_monitor_unref(m->udev_device_monitor);
163 if (m->udev_vcsa_monitor)
164 udev_monitor_unref(m->udev_vcsa_monitor);
165 if (m->udev_button_monitor)
166 udev_monitor_unref(m->udev_button_monitor);
167
168 if (m->udev)
169 udev_unref(m->udev);
170
171 bus_verify_polkit_async_registry_free(m->polkit_registry);
172
173 sd_bus_unref(m->bus);
174 sd_event_unref(m->event);
175
176 safe_close(m->reserve_vt_fd);
177
178 strv_free(m->kill_only_users);
179 strv_free(m->kill_exclude_users);
180
181 free(m->scheduled_shutdown_type);
182 free(m->scheduled_shutdown_tty);
183 free(m->wall_message);
184 free(m->action_job);
185 free(m);
186 }
187
188 static int manager_enumerate_devices(Manager *m) {
189 struct udev_list_entry *item = NULL, *first = NULL;
190 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
191 int r;
192
193 assert(m);
194
195 /* Loads devices from udev and creates seats for them as
196 * necessary */
197
198 e = udev_enumerate_new(m->udev);
199 if (!e)
200 return -ENOMEM;
201
202 r = udev_enumerate_add_match_tag(e, "master-of-seat");
203 if (r < 0)
204 return r;
205
206 r = udev_enumerate_add_match_is_initialized(e);
207 if (r < 0)
208 return r;
209
210 r = udev_enumerate_scan_devices(e);
211 if (r < 0)
212 return r;
213
214 first = udev_enumerate_get_list_entry(e);
215 udev_list_entry_foreach(item, first) {
216 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
217 int k;
218
219 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
220 if (!d)
221 return -ENOMEM;
222
223 k = manager_process_seat_device(m, d);
224 if (k < 0)
225 r = k;
226 }
227
228 return r;
229 }
230
231 static int manager_enumerate_buttons(Manager *m) {
232 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
233 struct udev_list_entry *item = NULL, *first = NULL;
234 int r;
235
236 assert(m);
237
238 /* Loads buttons from udev */
239
240 if (m->handle_power_key == HANDLE_IGNORE &&
241 m->handle_suspend_key == HANDLE_IGNORE &&
242 m->handle_hibernate_key == HANDLE_IGNORE &&
243 m->handle_lid_switch == HANDLE_IGNORE &&
244 m->handle_lid_switch_docked == HANDLE_IGNORE)
245 return 0;
246
247 e = udev_enumerate_new(m->udev);
248 if (!e)
249 return -ENOMEM;
250
251 r = udev_enumerate_add_match_subsystem(e, "input");
252 if (r < 0)
253 return r;
254
255 r = udev_enumerate_add_match_tag(e, "power-switch");
256 if (r < 0)
257 return r;
258
259 r = udev_enumerate_add_match_is_initialized(e);
260 if (r < 0)
261 return r;
262
263 r = udev_enumerate_scan_devices(e);
264 if (r < 0)
265 return r;
266
267 first = udev_enumerate_get_list_entry(e);
268 udev_list_entry_foreach(item, first) {
269 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
270 int k;
271
272 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
273 if (!d)
274 return -ENOMEM;
275
276 k = manager_process_button_device(m, d);
277 if (k < 0)
278 r = k;
279 }
280
281 return r;
282 }
283
284 static int manager_enumerate_seats(Manager *m) {
285 _cleanup_closedir_ DIR *d = NULL;
286 struct dirent *de;
287 int r = 0;
288
289 assert(m);
290
291 /* This loads data about seats stored on disk, but does not
292 * actually create any seats. Removes data of seats that no
293 * longer exist. */
294
295 d = opendir("/run/systemd/seats");
296 if (!d) {
297 if (errno == ENOENT)
298 return 0;
299
300 log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
301 return -errno;
302 }
303
304 FOREACH_DIRENT(de, d, return -errno) {
305 Seat *s;
306 int k;
307
308 if (!dirent_is_file(de))
309 continue;
310
311 s = hashmap_get(m->seats, de->d_name);
312 if (!s) {
313 unlinkat(dirfd(d), de->d_name, 0);
314 continue;
315 }
316
317 k = seat_load(s);
318 if (k < 0)
319 r = k;
320 }
321
322 return r;
323 }
324
325 static int manager_enumerate_linger_users(Manager *m) {
326 _cleanup_closedir_ DIR *d = NULL;
327 struct dirent *de;
328 int r = 0;
329
330 assert(m);
331
332 d = opendir("/var/lib/systemd/linger");
333 if (!d) {
334 if (errno == ENOENT)
335 return 0;
336
337 log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
338 return -errno;
339 }
340
341 FOREACH_DIRENT(de, d, return -errno) {
342 int k;
343
344 if (!dirent_is_file(de))
345 continue;
346
347 k = manager_add_user_by_name(m, de->d_name, NULL);
348 if (k < 0) {
349 log_notice_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
350 r = k;
351 }
352 }
353
354 return r;
355 }
356
357 static int manager_enumerate_users(Manager *m) {
358 _cleanup_closedir_ DIR *d = NULL;
359 struct dirent *de;
360 int r, k;
361
362 assert(m);
363
364 /* Add lingering users */
365 r = manager_enumerate_linger_users(m);
366
367 /* Read in user data stored on disk */
368 d = opendir("/run/systemd/users");
369 if (!d) {
370 if (errno == ENOENT)
371 return 0;
372
373 log_error_errno(errno, "Failed to open /run/systemd/users: %m");
374 return -errno;
375 }
376
377 FOREACH_DIRENT(de, d, return -errno) {
378 User *u;
379
380 if (!dirent_is_file(de))
381 continue;
382
383 k = manager_add_user_by_name(m, de->d_name, &u);
384 if (k < 0) {
385 log_error_errno(k, "Failed to add user by file name %s: %m", de->d_name);
386
387 r = k;
388 continue;
389 }
390
391 user_add_to_gc_queue(u);
392
393 k = user_load(u);
394 if (k < 0)
395 r = k;
396 }
397
398 return r;
399 }
400
401 static int manager_enumerate_sessions(Manager *m) {
402 _cleanup_closedir_ DIR *d = NULL;
403 struct dirent *de;
404 int r = 0;
405
406 assert(m);
407
408 /* Read in session data stored on disk */
409 d = opendir("/run/systemd/sessions");
410 if (!d) {
411 if (errno == ENOENT)
412 return 0;
413
414 log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
415 return -errno;
416 }
417
418 FOREACH_DIRENT(de, d, return -errno) {
419 struct Session *s;
420 int k;
421
422 if (!dirent_is_file(de))
423 continue;
424
425 if (!session_id_valid(de->d_name)) {
426 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
427 r = -EINVAL;
428 continue;
429 }
430
431 k = manager_add_session(m, de->d_name, &s);
432 if (k < 0) {
433 log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
434
435 r = k;
436 continue;
437 }
438
439 session_add_to_gc_queue(s);
440
441 k = session_load(s);
442 if (k < 0)
443 r = k;
444 }
445
446 return r;
447 }
448
449 static int manager_enumerate_inhibitors(Manager *m) {
450 _cleanup_closedir_ DIR *d = NULL;
451 struct dirent *de;
452 int r = 0;
453
454 assert(m);
455
456 d = opendir("/run/systemd/inhibit");
457 if (!d) {
458 if (errno == ENOENT)
459 return 0;
460
461 log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
462 return -errno;
463 }
464
465 FOREACH_DIRENT(de, d, return -errno) {
466 int k;
467 Inhibitor *i;
468
469 if (!dirent_is_file(de))
470 continue;
471
472 k = manager_add_inhibitor(m, de->d_name, &i);
473 if (k < 0) {
474 log_notice_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
475 r = k;
476 continue;
477 }
478
479 k = inhibitor_load(i);
480 if (k < 0)
481 r = k;
482 }
483
484 return r;
485 }
486
487 static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
488 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
489 Manager *m = userdata;
490
491 assert(m);
492
493 d = udev_monitor_receive_device(m->udev_seat_monitor);
494 if (!d)
495 return -ENOMEM;
496
497 manager_process_seat_device(m, d);
498 return 0;
499 }
500
501 static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
502 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
503 Manager *m = userdata;
504
505 assert(m);
506
507 d = udev_monitor_receive_device(m->udev_device_monitor);
508 if (!d)
509 return -ENOMEM;
510
511 manager_process_seat_device(m, d);
512 return 0;
513 }
514
515 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
516 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
517 Manager *m = userdata;
518 const char *name;
519
520 assert(m);
521
522 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
523 if (!d)
524 return -ENOMEM;
525
526 name = udev_device_get_sysname(d);
527
528 /* Whenever a VCSA device is removed try to reallocate our
529 * VTs, to make sure our auto VTs never go away. */
530
531 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
532 seat_preallocate_vts(m->seat0);
533
534 return 0;
535 }
536
537 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
538 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
539 Manager *m = userdata;
540
541 assert(m);
542
543 d = udev_monitor_receive_device(m->udev_button_monitor);
544 if (!d)
545 return -ENOMEM;
546
547 manager_process_button_device(m, d);
548 return 0;
549 }
550
551 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
552 Manager *m = userdata;
553
554 assert(m);
555 assert(m->seat0);
556 assert(m->console_active_fd == fd);
557
558 seat_read_active_vt(m->seat0);
559 return 0;
560 }
561
562 static int manager_reserve_vt(Manager *m) {
563 _cleanup_free_ char *p = NULL;
564
565 assert(m);
566
567 if (m->reserve_vt <= 0)
568 return 0;
569
570 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
571 return log_oom();
572
573 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
574 if (m->reserve_vt_fd < 0) {
575
576 /* Don't complain on VT-less systems */
577 if (errno != ENOENT)
578 log_warning_errno(errno, "Failed to pin reserved VT: %m");
579 return -errno;
580 }
581
582 return 0;
583 }
584
585 static int manager_connect_bus(Manager *m) {
586 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
587 int r;
588
589 assert(m);
590 assert(!m->bus);
591
592 r = sd_bus_default_system(&m->bus);
593 if (r < 0)
594 return log_error_errno(r, "Failed to connect to system bus: %m");
595
596 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
597 if (r < 0)
598 return log_error_errno(r, "Failed to add manager object vtable: %m");
599
600 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
601 if (r < 0)
602 return log_error_errno(r, "Failed to add seat object vtable: %m");
603
604 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
605 if (r < 0)
606 return log_error_errno(r, "Failed to add seat enumerator: %m");
607
608 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
609 if (r < 0)
610 return log_error_errno(r, "Failed to add session object vtable: %m");
611
612 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
613 if (r < 0)
614 return log_error_errno(r, "Failed to add session enumerator: %m");
615
616 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
617 if (r < 0)
618 return log_error_errno(r, "Failed to add user object vtable: %m");
619
620 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
621 if (r < 0)
622 return log_error_errno(r, "Failed to add user enumerator: %m");
623
624 r = sd_bus_add_match(m->bus,
625 NULL,
626 "type='signal',"
627 "sender='org.freedesktop.DBus',"
628 "interface='org.freedesktop.DBus',"
629 "member='NameOwnerChanged',"
630 "path='/org/freedesktop/DBus'",
631 match_name_owner_changed, m);
632 if (r < 0)
633 return log_error_errno(r, "Failed to add match for NameOwnerChanged: %m");
634
635 r = sd_bus_add_match(m->bus,
636 NULL,
637 "type='signal',"
638 "sender='org.freedesktop.systemd1',"
639 "interface='org.freedesktop.systemd1.Manager',"
640 "member='JobRemoved',"
641 "path='/org/freedesktop/systemd1'",
642 match_job_removed, m);
643 if (r < 0)
644 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
645
646 r = sd_bus_add_match(m->bus,
647 NULL,
648 "type='signal',"
649 "sender='org.freedesktop.systemd1',"
650 "interface='org.freedesktop.systemd1.Manager',"
651 "member='UnitRemoved',"
652 "path='/org/freedesktop/systemd1'",
653 match_unit_removed, m);
654 if (r < 0)
655 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
656
657 r = sd_bus_add_match(m->bus,
658 NULL,
659 "type='signal',"
660 "sender='org.freedesktop.systemd1',"
661 "interface='org.freedesktop.DBus.Properties',"
662 "member='PropertiesChanged'",
663 match_properties_changed, m);
664 if (r < 0)
665 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
666
667 r = sd_bus_add_match(m->bus,
668 NULL,
669 "type='signal',"
670 "sender='org.freedesktop.systemd1',"
671 "interface='org.freedesktop.systemd1.Manager',"
672 "member='Reloading',"
673 "path='/org/freedesktop/systemd1'",
674 match_reloading, m);
675 if (r < 0)
676 return log_error_errno(r, "Failed to add match for Reloading: %m");
677
678 r = sd_bus_call_method(
679 m->bus,
680 "org.freedesktop.systemd1",
681 "/org/freedesktop/systemd1",
682 "org.freedesktop.systemd1.Manager",
683 "Subscribe",
684 &error,
685 NULL, NULL);
686 if (r < 0) {
687 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
688 return r;
689 }
690
691 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
692 if (r < 0)
693 return log_error_errno(r, "Failed to register name: %m");
694
695 r = sd_bus_attach_event(m->bus, m->event, 0);
696 if (r < 0)
697 return log_error_errno(r, "Failed to attach bus to event loop: %m");
698
699 return 0;
700 }
701
702 static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
703 Manager *m = data;
704 Session *active, *iter;
705
706 /*
707 * We got a VT-switch signal and we have to acknowledge it immediately.
708 * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
709 * old user-space might run multiple sessions on a single VT, *sigh*.
710 * Therefore, we have to iterate all sessions and find one with a vtfd
711 * on the requested VT.
712 * As only VTs with active controllers have VT_PROCESS set, our current
713 * notion of the active VT might be wrong (for instance if the switch
714 * happens while we setup VT_PROCESS). Therefore, read the current VT
715 * first and then use s->active->vtnr as reference. Note that this is
716 * not racy, as no further VT-switch can happen as long as we're in
717 * synchronous VT_PROCESS mode.
718 */
719
720 assert(m->seat0);
721 seat_read_active_vt(m->seat0);
722
723 active = m->seat0->active;
724 if (!active || active->vtnr < 1) {
725 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
726 return 0;
727 }
728
729 if (active->vtfd >= 0) {
730 session_leave_vt(active);
731 } else {
732 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
733 if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
734 session_leave_vt(iter);
735 break;
736 }
737 }
738 }
739
740 return 0;
741 }
742
743 static int manager_connect_console(Manager *m) {
744 int r;
745
746 assert(m);
747 assert(m->console_active_fd < 0);
748
749 /* On certain architectures (S390 and Xen, and containers),
750 /dev/tty0 does not exist, so don't fail if we can't open
751 it. */
752 if (access("/dev/tty0", F_OK) < 0)
753 return 0;
754
755 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
756 if (m->console_active_fd < 0) {
757
758 /* On some systems the device node /dev/tty0 may exist
759 * even though /sys/class/tty/tty0 does not. */
760 if (errno == ENOENT)
761 return 0;
762
763 log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
764 return -errno;
765 }
766
767 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
768 if (r < 0) {
769 log_error("Failed to watch foreground console");
770 return r;
771 }
772
773 /*
774 * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
775 * as VT-acquire signal. We ignore any acquire-events (yes, we still
776 * have to provide a valid signal-number for it!) and acknowledge all
777 * release events immediately.
778 */
779
780 if (SIGRTMIN + 1 > SIGRTMAX) {
781 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
782 return -EINVAL;
783 }
784
785 r = ignore_signals(SIGRTMIN + 1, -1);
786 if (r < 0)
787 return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m");
788
789 r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
790 if (r < 0)
791 return log_error_errno(r, "Cannot block SIGRTMIN: %m");
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 = sd_event_run(m->event, (uint64_t) -1);
1113 if (r < 0)
1114 return r;
1115 }
1116 }
1117
1118 static int manager_parse_config_file(Manager *m) {
1119 assert(m);
1120
1121 return config_parse_many("/etc/systemd/logind.conf",
1122 CONF_DIRS_NULSTR("systemd/logind.conf"),
1123 "Login\0",
1124 config_item_perf_lookup, logind_gperf_lookup,
1125 false, m);
1126 }
1127
1128 int main(int argc, char *argv[]) {
1129 Manager *m = NULL;
1130 int r;
1131
1132 log_set_target(LOG_TARGET_AUTO);
1133 log_set_facility(LOG_AUTH);
1134 log_parse_environment();
1135 log_open();
1136
1137 umask(0022);
1138
1139 if (argc != 1) {
1140 log_error("This program takes no arguments.");
1141 r = -EINVAL;
1142 goto finish;
1143 }
1144
1145 /* Always create the directories people can create inotify
1146 * watches in. Note that some applications might check for the
1147 * existence of /run/systemd/seats/ to determine whether
1148 * logind is available, so please always make sure this check
1149 * stays in. */
1150 mkdir_label("/run/systemd/seats", 0755);
1151 mkdir_label("/run/systemd/users", 0755);
1152 mkdir_label("/run/systemd/sessions", 0755);
1153
1154 m = manager_new();
1155 if (!m) {
1156 r = log_oom();
1157 goto finish;
1158 }
1159
1160 manager_parse_config_file(m);
1161
1162 r = manager_startup(m);
1163 if (r < 0) {
1164 log_error_errno(r, "Failed to fully start up daemon: %m");
1165 goto finish;
1166 }
1167
1168 log_debug("systemd-logind running as pid "PID_FMT, getpid());
1169
1170 sd_notify(false,
1171 "READY=1\n"
1172 "STATUS=Processing requests...");
1173
1174 r = manager_run(m);
1175
1176 log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
1177
1178 finish:
1179 sd_notify(false,
1180 "STOPPING=1\n"
1181 "STATUS=Shutting down...");
1182
1183 if (m)
1184 manager_free(m);
1185
1186 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1187 }