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