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