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