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