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