]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/logind.c
log: minimize includes in log.h
[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"
3ffd4af2 38#include "logind.h"
dccca82b 39#include "process-util.h"
4b51966c 40#include "selinux-util.h"
24882e06 41#include "signal-util.h"
07630cea
LP
42#include "strv.h"
43#include "udev-util.h"
20263082 44
905f0a39
DM
45static void manager_free(Manager *m);
46
a2ed7077 47static void manager_reset_config(Manager *m) {
20263082 48 m->n_autovts = 6;
98a77df5 49 m->reserve_vt = 6;
66cdd0f2 50 m->remove_ipc = true;
eecd1362 51 m->inhibit_delay_max = 5 * USEC_PER_SEC;
beaafb2e 52 m->handle_power_key = HANDLE_POWEROFF;
8e7fd6ad
LP
53 m->handle_suspend_key = HANDLE_SUSPEND;
54 m->handle_hibernate_key = HANDLE_HIBERNATE;
beaafb2e 55 m->handle_lid_switch = HANDLE_SUSPEND;
3c56cab4 56 m->handle_lid_switch_docked = HANDLE_IGNORE;
a2ed7077
ZJS
57 m->power_key_ignore_inhibited = false;
58 m->suspend_key_ignore_inhibited = false;
59 m->hibernate_key_ignore_inhibited = false;
beaafb2e 60 m->lid_switch_ignore_inhibited = true;
a2ed7077 61
9d10cbee 62 m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
20263082 63
23406ce5
LP
64 m->idle_action_usec = 30 * USEC_PER_MINUTE;
65 m->idle_action = HANDLE_IGNORE;
23406ce5 66
d8cf2ac7 67 m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
f5058264 68 m->user_tasks_max = system_tasks_max_scale(DEFAULT_USER_TASKS_MAX_PERCENTAGE, 100U); /* 33% */
64b56896
LP
69 m->sessions_max = 8192;
70 m->inhibitors_max = 8192;
1c231f56 71
95365a57 72 m->kill_user_processes = KILL_USER_PROCESSES;
a2ed7077
ZJS
73
74 m->kill_only_users = strv_free(m->kill_only_users);
75 m->kill_exclude_users = strv_free(m->kill_exclude_users);
76}
77
78static Manager *manager_new(void) {
79 Manager *m;
80 int r;
81
82 m = new0(Manager, 1);
83 if (!m)
84 return NULL;
85
86 m->console_active_fd = -1;
87 m->reserve_vt_fd = -1;
88
89 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
90
d5099efc
MS
91 m->devices = hashmap_new(&string_hash_ops);
92 m->seats = hashmap_new(&string_hash_ops);
93 m->sessions = hashmap_new(&string_hash_ops);
94 m->users = hashmap_new(NULL);
95 m->inhibitors = hashmap_new(&string_hash_ops);
96 m->buttons = hashmap_new(&string_hash_ops);
f8e2fb7b 97
d5099efc
MS
98 m->user_units = hashmap_new(&string_hash_ops);
99 m->session_units = hashmap_new(&string_hash_ops);
8c8c4351 100
3cde9e8f 101 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
ed4ba7e4 102 goto fail;
25d93491 103
20263082 104 m->udev = udev_new();
ed4ba7e4
LP
105 if (!m->udev)
106 goto fail;
20263082 107
afc6adb5 108 r = sd_event_default(&m->event);
ed4ba7e4
LP
109 if (r < 0)
110 goto fail;
cc377381 111
cde93897
LP
112 sd_event_set_watchdog(m->event, true);
113
a2ed7077
ZJS
114 manager_reset_config(m);
115
20263082 116 return m;
ed4ba7e4
LP
117
118fail:
119 manager_free(m);
120 return NULL;
20263082
LP
121}
122
905f0a39 123static void manager_free(Manager *m) {
20263082
LP
124 Session *session;
125 User *u;
126 Device *d;
127 Seat *s;
f8e2fb7b 128 Inhibitor *i;
069cfc85 129 Button *b;
20263082 130
84a4e660
LP
131 if (!m)
132 return;
20263082
LP
133
134 while ((session = hashmap_first(m->sessions)))
135 session_free(session);
136
137 while ((u = hashmap_first(m->users)))
138 user_free(u);
139
140 while ((d = hashmap_first(m->devices)))
141 device_free(d);
142
143 while ((s = hashmap_first(m->seats)))
144 seat_free(s);
145
f8e2fb7b
LP
146 while ((i = hashmap_first(m->inhibitors)))
147 inhibitor_free(i);
148
069cfc85
LP
149 while ((b = hashmap_first(m->buttons)))
150 button_free(b);
151
20263082
LP
152 hashmap_free(m->devices);
153 hashmap_free(m->seats);
f8e2fb7b
LP
154 hashmap_free(m->sessions);
155 hashmap_free(m->users);
156 hashmap_free(m->inhibitors);
069cfc85 157 hashmap_free(m->buttons);
f8e2fb7b 158
fb6becb4
LP
159 hashmap_free(m->user_units);
160 hashmap_free(m->session_units);
8c8c4351 161
cc377381 162 sd_event_source_unref(m->idle_action_event_source);
c0f32805 163 sd_event_source_unref(m->inhibit_timeout_source);
8aaa023a 164 sd_event_source_unref(m->scheduled_shutdown_timeout_source);
867c37f6 165 sd_event_source_unref(m->nologin_timeout_source);
e2fa5721 166 sd_event_source_unref(m->wall_message_timeout_source);
cc377381
LP
167
168 sd_event_source_unref(m->console_active_event_source);
169 sd_event_source_unref(m->udev_seat_event_source);
170 sd_event_source_unref(m->udev_device_event_source);
171 sd_event_source_unref(m->udev_vcsa_event_source);
172 sd_event_source_unref(m->udev_button_event_source);
f9cd6be1 173 sd_event_source_unref(m->lid_switch_ignore_event_source);
20263082 174
03e334a1 175 safe_close(m->console_active_fd);
20263082 176
3e044c49
ME
177 udev_monitor_unref(m->udev_seat_monitor);
178 udev_monitor_unref(m->udev_device_monitor);
179 udev_monitor_unref(m->udev_vcsa_monitor);
180 udev_monitor_unref(m->udev_button_monitor);
181
182 udev_unref(m->udev);
20263082 183
867c37f6 184 if (m->unlink_nologin)
a790812c 185 (void) unlink("/run/nologin");
867c37f6 186
36e34057 187 bus_verify_polkit_async_registry_free(m->polkit_registry);
20263082 188
cc377381
LP
189 sd_bus_unref(m->bus);
190 sd_event_unref(m->event);
20263082 191
03e334a1 192 safe_close(m->reserve_vt_fd);
98a77df5 193
193197e8
LP
194 strv_free(m->kill_only_users);
195 strv_free(m->kill_exclude_users);
196
8aaa023a 197 free(m->scheduled_shutdown_type);
e2fa5721
DM
198 free(m->scheduled_shutdown_tty);
199 free(m->wall_message);
af9792ac 200 free(m->action_job);
20263082
LP
201 free(m);
202}
203
9588bc32 204static int manager_enumerate_devices(Manager *m) {
20263082 205 struct udev_list_entry *item = NULL, *first = NULL;
bf5332d2 206 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
14c3baca 207 int r;
20263082
LP
208
209 assert(m);
210
211 /* Loads devices from udev and creates seats for them as
212 * necessary */
213
214 e = udev_enumerate_new(m->udev);
bf5332d2
LP
215 if (!e)
216 return -ENOMEM;
20263082 217
2d96536d 218 r = udev_enumerate_add_match_tag(e, "master-of-seat");
14c3baca 219 if (r < 0)
bf5332d2 220 return r;
20263082 221
e1202047
LP
222 r = udev_enumerate_add_match_is_initialized(e);
223 if (r < 0)
224 return r;
225
14c3baca
LP
226 r = udev_enumerate_scan_devices(e);
227 if (r < 0)
bf5332d2 228 return r;
20263082
LP
229
230 first = udev_enumerate_get_list_entry(e);
231 udev_list_entry_foreach(item, first) {
bf5332d2 232 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
20263082
LP
233 int k;
234
235 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
bf5332d2
LP
236 if (!d)
237 return -ENOMEM;
20263082 238
bf5332d2 239 k = manager_process_seat_device(m, d);
20263082
LP
240 if (k < 0)
241 r = k;
242 }
243
20263082
LP
244 return r;
245}
246
9588bc32 247static int manager_enumerate_buttons(Manager *m) {
bf5332d2 248 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
069cfc85 249 struct udev_list_entry *item = NULL, *first = NULL;
069cfc85
LP
250 int r;
251
252 assert(m);
253
254 /* Loads buttons from udev */
255
beaafb2e 256 if (m->handle_power_key == HANDLE_IGNORE &&
8e7fd6ad
LP
257 m->handle_suspend_key == HANDLE_IGNORE &&
258 m->handle_hibernate_key == HANDLE_IGNORE &&
3c56cab4
BW
259 m->handle_lid_switch == HANDLE_IGNORE &&
260 m->handle_lid_switch_docked == HANDLE_IGNORE)
6de0e0e5
LP
261 return 0;
262
069cfc85 263 e = udev_enumerate_new(m->udev);
bf5332d2
LP
264 if (!e)
265 return -ENOMEM;
069cfc85
LP
266
267 r = udev_enumerate_add_match_subsystem(e, "input");
268 if (r < 0)
bf5332d2 269 return r;
069cfc85
LP
270
271 r = udev_enumerate_add_match_tag(e, "power-switch");
272 if (r < 0)
bf5332d2 273 return r;
069cfc85 274
e1202047
LP
275 r = udev_enumerate_add_match_is_initialized(e);
276 if (r < 0)
277 return r;
278
069cfc85
LP
279 r = udev_enumerate_scan_devices(e);
280 if (r < 0)
bf5332d2 281 return r;
069cfc85
LP
282
283 first = udev_enumerate_get_list_entry(e);
284 udev_list_entry_foreach(item, first) {
bf5332d2 285 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
069cfc85
LP
286 int k;
287
288 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
bf5332d2
LP
289 if (!d)
290 return -ENOMEM;
069cfc85 291
bf5332d2 292 k = manager_process_button_device(m, d);
069cfc85
LP
293 if (k < 0)
294 r = k;
295 }
296
069cfc85
LP
297 return r;
298}
299
9588bc32 300static int manager_enumerate_seats(Manager *m) {
9444b1f2 301 _cleanup_closedir_ DIR *d = NULL;
20263082
LP
302 struct dirent *de;
303 int r = 0;
304
305 assert(m);
306
307 /* This loads data about seats stored on disk, but does not
308 * actually create any seats. Removes data of seats that no
309 * longer exist. */
310
311 d = opendir("/run/systemd/seats");
312 if (!d) {
313 if (errno == ENOENT)
314 return 0;
315
e1427b13 316 return log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
20263082
LP
317 }
318
9444b1f2 319 FOREACH_DIRENT(de, d, return -errno) {
20263082
LP
320 Seat *s;
321 int k;
322
323 if (!dirent_is_file(de))
324 continue;
325
326 s = hashmap_get(m->seats, de->d_name);
327 if (!s) {
328 unlinkat(dirfd(d), de->d_name, 0);
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 */
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}