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