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