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