]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind.c
Merge nss-myhostname
[thirdparty/systemd.git] / src / login / logind.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <pwd.h>
24 #include <libudev.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/epoll.h>
29 #include <sys/ioctl.h>
30 #include <linux/vt.h>
31 #include <sys/timerfd.h>
32
33 #include <systemd/sd-daemon.h>
34
35 #include "logind.h"
36 #include "dbus-common.h"
37 #include "dbus-loop.h"
38 #include "strv.h"
39 #include "conf-parser.h"
40
41 Manager *manager_new(void) {
42 Manager *m;
43
44 m = new0(Manager, 1);
45 if (!m)
46 return NULL;
47
48 m->console_active_fd = -1;
49 m->bus_fd = -1;
50 m->udev_seat_fd = -1;
51 m->udev_vcsa_fd = -1;
52 m->udev_button_fd = -1;
53 m->epoll_fd = -1;
54 m->reserve_vt_fd = -1;
55
56 m->n_autovts = 6;
57 m->reserve_vt = 6;
58 m->inhibit_delay_max = 5 * USEC_PER_SEC;
59 m->handle_power_key = HANDLE_POWEROFF;
60 m->handle_suspend_key = HANDLE_SUSPEND;
61 m->handle_hibernate_key = HANDLE_HIBERNATE;
62 m->handle_lid_switch = HANDLE_SUSPEND;
63 m->lid_switch_ignore_inhibited = true;
64
65 m->idle_action_fd = -1;
66 m->idle_action_usec = 30 * USEC_PER_MINUTE;
67 m->idle_action = HANDLE_IGNORE;
68 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
69
70 m->devices = hashmap_new(string_hash_func, string_compare_func);
71 m->seats = hashmap_new(string_hash_func, string_compare_func);
72 m->sessions = hashmap_new(string_hash_func, string_compare_func);
73 m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
74 m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
75 m->buttons = hashmap_new(string_hash_func, string_compare_func);
76
77 m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
78 m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
79
80 m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
81 m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
82 m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
83
84 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
85 !m->user_cgroups || !m->session_cgroups ||
86 !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
87 manager_free(m);
88 return NULL;
89 }
90
91 m->reset_controllers = strv_new("cpu", NULL);
92 m->kill_exclude_users = strv_new("root", NULL);
93 if (!m->reset_controllers || !m->kill_exclude_users) {
94 manager_free(m);
95 return NULL;
96 }
97
98 m->udev = udev_new();
99 if (!m->udev) {
100 manager_free(m);
101 return NULL;
102 }
103
104 if (cg_get_user_path(&m->cgroup_path) < 0) {
105 manager_free(m);
106 return NULL;
107 }
108
109 return m;
110 }
111
112 void manager_free(Manager *m) {
113 Session *session;
114 User *u;
115 Device *d;
116 Seat *s;
117 Inhibitor *i;
118 Button *b;
119
120 assert(m);
121
122 while ((session = hashmap_first(m->sessions)))
123 session_free(session);
124
125 while ((u = hashmap_first(m->users)))
126 user_free(u);
127
128 while ((d = hashmap_first(m->devices)))
129 device_free(d);
130
131 while ((s = hashmap_first(m->seats)))
132 seat_free(s);
133
134 while ((i = hashmap_first(m->inhibitors)))
135 inhibitor_free(i);
136
137 while ((b = hashmap_first(m->buttons)))
138 button_free(b);
139
140 hashmap_free(m->devices);
141 hashmap_free(m->seats);
142 hashmap_free(m->sessions);
143 hashmap_free(m->users);
144 hashmap_free(m->inhibitors);
145 hashmap_free(m->buttons);
146
147 hashmap_free(m->user_cgroups);
148 hashmap_free(m->session_cgroups);
149
150 hashmap_free(m->session_fds);
151 hashmap_free(m->inhibitor_fds);
152 hashmap_free(m->button_fds);
153
154 if (m->console_active_fd >= 0)
155 close_nointr_nofail(m->console_active_fd);
156
157 if (m->udev_seat_monitor)
158 udev_monitor_unref(m->udev_seat_monitor);
159 if (m->udev_vcsa_monitor)
160 udev_monitor_unref(m->udev_vcsa_monitor);
161 if (m->udev_button_monitor)
162 udev_monitor_unref(m->udev_button_monitor);
163
164 if (m->udev)
165 udev_unref(m->udev);
166
167 if (m->bus) {
168 dbus_connection_flush(m->bus);
169 dbus_connection_close(m->bus);
170 dbus_connection_unref(m->bus);
171 }
172
173 if (m->bus_fd >= 0)
174 close_nointr_nofail(m->bus_fd);
175
176 if (m->epoll_fd >= 0)
177 close_nointr_nofail(m->epoll_fd);
178
179 if (m->reserve_vt_fd >= 0)
180 close_nointr_nofail(m->reserve_vt_fd);
181
182 if (m->idle_action_fd >= 0)
183 close_nointr_nofail(m->idle_action_fd);
184
185 strv_free(m->controllers);
186 strv_free(m->reset_controllers);
187 strv_free(m->kill_only_users);
188 strv_free(m->kill_exclude_users);
189
190 free(m->cgroup_path);
191 free(m);
192 }
193
194 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
195 Device *d;
196
197 assert(m);
198 assert(sysfs);
199
200 d = hashmap_get(m->devices, sysfs);
201 if (d) {
202 if (_device)
203 *_device = d;
204
205 return 0;
206 }
207
208 d = device_new(m, sysfs);
209 if (!d)
210 return -ENOMEM;
211
212 if (_device)
213 *_device = d;
214
215 return 0;
216 }
217
218 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
219 Seat *s;
220
221 assert(m);
222 assert(id);
223
224 s = hashmap_get(m->seats, id);
225 if (s) {
226 if (_seat)
227 *_seat = s;
228
229 return 0;
230 }
231
232 s = seat_new(m, id);
233 if (!s)
234 return -ENOMEM;
235
236 if (_seat)
237 *_seat = s;
238
239 return 0;
240 }
241
242 int manager_add_session(Manager *m, User *u, const char *id, Session **_session) {
243 Session *s;
244
245 assert(m);
246 assert(id);
247
248 s = hashmap_get(m->sessions, id);
249 if (s) {
250 if (_session)
251 *_session = s;
252
253 return 0;
254 }
255
256 s = session_new(m, u, id);
257 if (!s)
258 return -ENOMEM;
259
260 if (_session)
261 *_session = s;
262
263 return 0;
264 }
265
266 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
267 User *u;
268
269 assert(m);
270 assert(name);
271
272 u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
273 if (u) {
274 if (_user)
275 *_user = u;
276
277 return 0;
278 }
279
280 u = user_new(m, uid, gid, name);
281 if (!u)
282 return -ENOMEM;
283
284 if (_user)
285 *_user = u;
286
287 return 0;
288 }
289
290 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
291 uid_t uid;
292 gid_t gid;
293 int r;
294
295 assert(m);
296 assert(name);
297
298 r = get_user_creds(&name, &uid, &gid, NULL, NULL);
299 if (r < 0)
300 return r;
301
302 return manager_add_user(m, uid, gid, name, _user);
303 }
304
305 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
306 struct passwd *p;
307
308 assert(m);
309
310 errno = 0;
311 p = getpwuid(uid);
312 if (!p)
313 return errno ? -errno : -ENOENT;
314
315 return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
316 }
317
318 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
319 Inhibitor *i;
320
321 assert(m);
322 assert(id);
323
324 i = hashmap_get(m->inhibitors, id);
325 if (i) {
326 if (_inhibitor)
327 *_inhibitor = i;
328
329 return 0;
330 }
331
332 i = inhibitor_new(m, id);
333 if (!i)
334 return -ENOMEM;
335
336 if (_inhibitor)
337 *_inhibitor = i;
338
339 return 0;
340 }
341
342 int manager_add_button(Manager *m, const char *name, Button **_button) {
343 Button *b;
344
345 assert(m);
346 assert(name);
347
348 b = hashmap_get(m->buttons, name);
349 if (b) {
350 if (_button)
351 *_button = b;
352
353 return 0;
354 }
355
356 b = button_new(m, name);
357 if (!b)
358 return -ENOMEM;
359
360 if (_button)
361 *_button = b;
362
363 return 0;
364 }
365
366 int manager_process_seat_device(Manager *m, struct udev_device *d) {
367 Device *device;
368 int r;
369
370 assert(m);
371
372 if (streq_ptr(udev_device_get_action(d), "remove")) {
373
374 device = hashmap_get(m->devices, udev_device_get_syspath(d));
375 if (!device)
376 return 0;
377
378 seat_add_to_gc_queue(device->seat);
379 device_free(device);
380
381 } else {
382 const char *sn;
383 Seat *seat;
384
385 sn = udev_device_get_property_value(d, "ID_SEAT");
386 if (isempty(sn))
387 sn = "seat0";
388
389 if (!seat_name_is_valid(sn)) {
390 log_warning("Device with invalid seat name %s found, ignoring.", sn);
391 return 0;
392 }
393
394 r = manager_add_device(m, udev_device_get_syspath(d), &device);
395 if (r < 0)
396 return r;
397
398 r = manager_add_seat(m, sn, &seat);
399 if (r < 0) {
400 if (!device->seat)
401 device_free(device);
402
403 return r;
404 }
405
406 device_attach(device, seat);
407 seat_start(seat);
408 }
409
410 return 0;
411 }
412
413 int manager_process_button_device(Manager *m, struct udev_device *d) {
414 Button *b;
415
416 int r;
417
418 assert(m);
419
420 if (streq_ptr(udev_device_get_action(d), "remove")) {
421
422 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
423 if (!b)
424 return 0;
425
426 button_free(b);
427
428 } else {
429 const char *sn;
430
431 r = manager_add_button(m, udev_device_get_sysname(d), &b);
432 if (r < 0)
433 return r;
434
435 sn = udev_device_get_property_value(d, "ID_SEAT");
436 if (isempty(sn))
437 sn = "seat0";
438
439 button_set_seat(b, sn);
440 button_open(b);
441 }
442
443 return 0;
444 }
445
446 int manager_enumerate_devices(Manager *m) {
447 struct udev_list_entry *item = NULL, *first = NULL;
448 struct udev_enumerate *e;
449 int r;
450
451 assert(m);
452
453 /* Loads devices from udev and creates seats for them as
454 * necessary */
455
456 e = udev_enumerate_new(m->udev);
457 if (!e) {
458 r = -ENOMEM;
459 goto finish;
460 }
461
462 r = udev_enumerate_add_match_subsystem(e, "graphics");
463 if (r < 0)
464 goto finish;
465
466 r = udev_enumerate_add_match_tag(e, "seat");
467 if (r < 0)
468 goto finish;
469
470 r = udev_enumerate_scan_devices(e);
471 if (r < 0)
472 goto finish;
473
474 first = udev_enumerate_get_list_entry(e);
475 udev_list_entry_foreach(item, first) {
476 struct udev_device *d;
477 int k;
478
479 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
480 if (!d) {
481 r = -ENOMEM;
482 goto finish;
483 }
484
485 k = manager_process_seat_device(m, d);
486 udev_device_unref(d);
487
488 if (k < 0)
489 r = k;
490 }
491
492 finish:
493 if (e)
494 udev_enumerate_unref(e);
495
496 return r;
497 }
498
499 int manager_enumerate_buttons(Manager *m) {
500 struct udev_list_entry *item = NULL, *first = NULL;
501 struct udev_enumerate *e;
502 int r;
503
504 assert(m);
505
506 /* Loads buttons from udev */
507
508 if (m->handle_power_key == HANDLE_IGNORE &&
509 m->handle_suspend_key == HANDLE_IGNORE &&
510 m->handle_hibernate_key == HANDLE_IGNORE &&
511 m->handle_lid_switch == HANDLE_IGNORE)
512 return 0;
513
514 e = udev_enumerate_new(m->udev);
515 if (!e) {
516 r = -ENOMEM;
517 goto finish;
518 }
519
520 r = udev_enumerate_add_match_subsystem(e, "input");
521 if (r < 0)
522 goto finish;
523
524 r = udev_enumerate_add_match_tag(e, "power-switch");
525 if (r < 0)
526 goto finish;
527
528 r = udev_enumerate_scan_devices(e);
529 if (r < 0)
530 goto finish;
531
532 first = udev_enumerate_get_list_entry(e);
533 udev_list_entry_foreach(item, first) {
534 struct udev_device *d;
535 int k;
536
537 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
538 if (!d) {
539 r = -ENOMEM;
540 goto finish;
541 }
542
543 k = manager_process_button_device(m, d);
544 udev_device_unref(d);
545
546 if (k < 0)
547 r = k;
548 }
549
550 finish:
551 if (e)
552 udev_enumerate_unref(e);
553
554 return r;
555 }
556
557 int manager_enumerate_seats(Manager *m) {
558 DIR *d;
559 struct dirent *de;
560 int r = 0;
561
562 assert(m);
563
564 /* This loads data about seats stored on disk, but does not
565 * actually create any seats. Removes data of seats that no
566 * longer exist. */
567
568 d = opendir("/run/systemd/seats");
569 if (!d) {
570 if (errno == ENOENT)
571 return 0;
572
573 log_error("Failed to open /run/systemd/seats: %m");
574 return -errno;
575 }
576
577 while ((de = readdir(d))) {
578 Seat *s;
579 int k;
580
581 if (!dirent_is_file(de))
582 continue;
583
584 s = hashmap_get(m->seats, de->d_name);
585 if (!s) {
586 unlinkat(dirfd(d), de->d_name, 0);
587 continue;
588 }
589
590 k = seat_load(s);
591 if (k < 0)
592 r = k;
593 }
594
595 closedir(d);
596
597 return r;
598 }
599
600 static int manager_enumerate_users_from_cgroup(Manager *m) {
601 int r = 0, k;
602 char *name;
603 DIR *d;
604
605 r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
606 if (r < 0) {
607 if (r == -ENOENT)
608 return 0;
609
610 log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
611 return r;
612 }
613
614 while ((k = cg_read_subgroup(d, &name)) > 0) {
615 User *user;
616
617 k = manager_add_user_by_name(m, name, &user);
618 if (k < 0) {
619 free(name);
620 r = k;
621 continue;
622 }
623
624 user_add_to_gc_queue(user);
625
626 if (!user->cgroup_path)
627 if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) {
628 r = -ENOMEM;
629 free(name);
630 break;
631 }
632
633 free(name);
634 }
635
636 if (r >= 0 && k < 0)
637 r = k;
638
639 closedir(d);
640
641 return r;
642 }
643
644 static int manager_enumerate_linger_users(Manager *m) {
645 DIR *d;
646 struct dirent *de;
647 int r = 0;
648
649 d = opendir("/var/lib/systemd/linger");
650 if (!d) {
651 if (errno == ENOENT)
652 return 0;
653
654 log_error("Failed to open /var/lib/systemd/linger/: %m");
655 return -errno;
656 }
657
658 while ((de = readdir(d))) {
659 int k;
660
661 if (!dirent_is_file(de))
662 continue;
663
664 k = manager_add_user_by_name(m, de->d_name, NULL);
665 if (k < 0) {
666 log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
667 r = k;
668 }
669 }
670
671 closedir(d);
672
673 return r;
674 }
675
676 int manager_enumerate_users(Manager *m) {
677 DIR *d;
678 struct dirent *de;
679 int r, k;
680
681 assert(m);
682
683 /* First, enumerate user cgroups */
684 r = manager_enumerate_users_from_cgroup(m);
685
686 /* Second, add lingering users on top */
687 k = manager_enumerate_linger_users(m);
688 if (k < 0)
689 r = k;
690
691 /* Third, read in user data stored on disk */
692 d = opendir("/run/systemd/users");
693 if (!d) {
694 if (errno == ENOENT)
695 return 0;
696
697 log_error("Failed to open /run/systemd/users: %m");
698 return -errno;
699 }
700
701 while ((de = readdir(d))) {
702 uid_t uid;
703 User *u;
704
705 if (!dirent_is_file(de))
706 continue;
707
708 k = parse_uid(de->d_name, &uid);
709 if (k < 0) {
710 log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
711 continue;
712 }
713
714 u = hashmap_get(m->users, ULONG_TO_PTR(uid));
715 if (!u) {
716 unlinkat(dirfd(d), de->d_name, 0);
717 continue;
718 }
719
720 k = user_load(u);
721 if (k < 0)
722 r = k;
723 }
724
725 closedir(d);
726
727 return r;
728 }
729
730 static int manager_enumerate_sessions_from_cgroup(Manager *m) {
731 User *u;
732 Iterator i;
733 int r = 0;
734
735 HASHMAP_FOREACH(u, m->users, i) {
736 DIR *d;
737 char *name;
738 int k;
739
740 if (!u->cgroup_path)
741 continue;
742
743 k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
744 if (k < 0) {
745 if (k == -ENOENT)
746 continue;
747
748 log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
749 r = k;
750 continue;
751 }
752
753 while ((k = cg_read_subgroup(d, &name)) > 0) {
754 Session *session;
755
756 if (streq(name, "shared"))
757 continue;
758
759 k = manager_add_session(m, u, name, &session);
760 if (k < 0) {
761 free(name);
762 break;
763 }
764
765 session_add_to_gc_queue(session);
766
767 if (!session->cgroup_path)
768 if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) {
769 k = -ENOMEM;
770 free(name);
771 break;
772 }
773
774 free(name);
775 }
776
777 closedir(d);
778
779 if (k < 0)
780 r = k;
781 }
782
783 return r;
784 }
785
786 int manager_enumerate_sessions(Manager *m) {
787 DIR *d;
788 struct dirent *de;
789 int r = 0;
790
791 assert(m);
792
793 /* First enumerate session cgroups */
794 r = manager_enumerate_sessions_from_cgroup(m);
795
796 /* Second, read in session data stored on disk */
797 d = opendir("/run/systemd/sessions");
798 if (!d) {
799 if (errno == ENOENT)
800 return 0;
801
802 log_error("Failed to open /run/systemd/sessions: %m");
803 return -errno;
804 }
805
806 while ((de = readdir(d))) {
807 struct Session *s;
808 int k;
809
810 if (!dirent_is_file(de))
811 continue;
812
813 s = hashmap_get(m->sessions, de->d_name);
814 if (!s) {
815 unlinkat(dirfd(d), de->d_name, 0);
816 continue;
817 }
818
819 k = session_load(s);
820 if (k < 0)
821 r = k;
822 }
823
824 closedir(d);
825
826 return r;
827 }
828
829 int manager_enumerate_inhibitors(Manager *m) {
830 DIR *d;
831 struct dirent *de;
832 int r = 0;
833
834 assert(m);
835
836 d = opendir("/run/systemd/inhibit");
837 if (!d) {
838 if (errno == ENOENT)
839 return 0;
840
841 log_error("Failed to open /run/systemd/inhibit: %m");
842 return -errno;
843 }
844
845 while ((de = readdir(d))) {
846 int k;
847 Inhibitor *i;
848
849 if (!dirent_is_file(de))
850 continue;
851
852 k = manager_add_inhibitor(m, de->d_name, &i);
853 if (k < 0) {
854 log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
855 r = k;
856 continue;
857 }
858
859 k = inhibitor_load(i);
860 if (k < 0)
861 r = k;
862 }
863
864 closedir(d);
865
866 return r;
867 }
868
869 int manager_dispatch_seat_udev(Manager *m) {
870 struct udev_device *d;
871 int r;
872
873 assert(m);
874
875 d = udev_monitor_receive_device(m->udev_seat_monitor);
876 if (!d)
877 return -ENOMEM;
878
879 r = manager_process_seat_device(m, d);
880 udev_device_unref(d);
881
882 return r;
883 }
884
885 int manager_dispatch_vcsa_udev(Manager *m) {
886 struct udev_device *d;
887 int r = 0;
888 const char *name;
889
890 assert(m);
891
892 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
893 if (!d)
894 return -ENOMEM;
895
896 name = udev_device_get_sysname(d);
897
898 /* Whenever a VCSA device is removed try to reallocate our
899 * VTs, to make sure our auto VTs never go away. */
900
901 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
902 r = seat_preallocate_vts(m->vtconsole);
903
904 udev_device_unref(d);
905
906 return r;
907 }
908
909 int manager_dispatch_button_udev(Manager *m) {
910 struct udev_device *d;
911 int r;
912
913 assert(m);
914
915 d = udev_monitor_receive_device(m->udev_button_monitor);
916 if (!d)
917 return -ENOMEM;
918
919 r = manager_process_button_device(m, d);
920 udev_device_unref(d);
921
922 return r;
923 }
924
925 int manager_dispatch_console(Manager *m) {
926 assert(m);
927
928 if (m->vtconsole)
929 seat_read_active_vt(m->vtconsole);
930
931 return 0;
932 }
933
934 static int vt_is_busy(int vtnr) {
935 struct vt_stat vt_stat;
936 int r = 0, fd;
937
938 assert(vtnr >= 1);
939
940 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
941 * we'd open the latter we'd open the foreground tty which
942 * hence would be unconditionally busy. By opening /dev/tty1
943 * we avoid this. Since tty1 is special and needs to be an
944 * explicitly loaded getty or DM this is safe. */
945
946 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
947 if (fd < 0)
948 return -errno;
949
950 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
951 r = -errno;
952 else
953 r = !!(vt_stat.v_state & (1 << vtnr));
954
955 close_nointr_nofail(fd);
956
957 return r;
958 }
959
960 int manager_spawn_autovt(Manager *m, int vtnr) {
961 int r;
962 char *name = NULL;
963 const char *mode = "fail";
964
965 assert(m);
966 assert(vtnr >= 1);
967
968 if ((unsigned) vtnr > m->n_autovts &&
969 (unsigned) vtnr != m->reserve_vt)
970 return 0;
971
972 if ((unsigned) vtnr != m->reserve_vt) {
973 /* If this is the reserved TTY, we'll start the getty
974 * on it in any case, but otherwise only if it is not
975 * busy. */
976
977 r = vt_is_busy(vtnr);
978 if (r < 0)
979 return r;
980 else if (r > 0)
981 return -EBUSY;
982 }
983
984 if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
985 log_error("Could not allocate service name.");
986 r = -ENOMEM;
987 goto finish;
988 }
989
990 r = bus_method_call_with_reply (
991 m->bus,
992 "org.freedesktop.systemd1",
993 "/org/freedesktop/systemd1",
994 "org.freedesktop.systemd1.Manager",
995 "StartUnit",
996 NULL,
997 NULL,
998 DBUS_TYPE_STRING, &name,
999 DBUS_TYPE_STRING, &mode,
1000 DBUS_TYPE_INVALID);
1001
1002 finish:
1003 free(name);
1004
1005 return r;
1006 }
1007
1008 static int manager_reserve_vt(Manager *m) {
1009 _cleanup_free_ char *p = NULL;
1010
1011 assert(m);
1012
1013 if (m->reserve_vt <= 0)
1014 return 0;
1015
1016 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
1017 return log_oom();
1018
1019 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
1020 if (m->reserve_vt_fd < 0) {
1021
1022 /* Don't complain on VT-less systems */
1023 if (errno != ENOENT)
1024 log_warning("Failed to pin reserved VT: %m");
1025 return -errno;
1026 }
1027
1028 return 0;
1029 }
1030
1031 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
1032 Session *s;
1033 char *p;
1034
1035 assert(m);
1036 assert(cgroup);
1037 assert(session);
1038
1039 s = hashmap_get(m->session_cgroups, cgroup);
1040 if (s) {
1041 *session = s;
1042 return 1;
1043 }
1044
1045 p = strdup(cgroup);
1046 if (!p)
1047 return log_oom();
1048
1049 for (;;) {
1050 char *e;
1051
1052 e = strrchr(p, '/');
1053 if (!e || e == p) {
1054 free(p);
1055 *session = NULL;
1056 return 0;
1057 }
1058
1059 *e = 0;
1060
1061 s = hashmap_get(m->session_cgroups, p);
1062 if (s) {
1063 free(p);
1064 *session = s;
1065 return 1;
1066 }
1067 }
1068 }
1069
1070 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1071 User *u;
1072 char *p;
1073
1074 assert(m);
1075 assert(cgroup);
1076 assert(user);
1077
1078 u = hashmap_get(m->user_cgroups, cgroup);
1079 if (u) {
1080 *user = u;
1081 return 1;
1082 }
1083
1084 p = strdup(cgroup);
1085 if (!p)
1086 return log_oom();
1087
1088 for (;;) {
1089 char *e;
1090
1091 e = strrchr(p, '/');
1092 if (!e || e == p) {
1093 free(p);
1094 *user = NULL;
1095 return 0;
1096 }
1097
1098 *e = 0;
1099
1100 u = hashmap_get(m->user_cgroups, p);
1101 if (u) {
1102 free(p);
1103 *user = u;
1104 return 1;
1105 }
1106 }
1107 }
1108
1109 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1110 char *p;
1111 int r;
1112
1113 assert(m);
1114 assert(pid >= 1);
1115 assert(session);
1116
1117 r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1118 if (r < 0)
1119 return r;
1120
1121 r = manager_get_session_by_cgroup(m, p, session);
1122 free(p);
1123
1124 return r;
1125 }
1126
1127 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1128 Session *s;
1129 User *u;
1130 int r;
1131
1132 r = manager_get_session_by_cgroup(m, cgroup, &s);
1133 if (r > 0)
1134 session_add_to_gc_queue(s);
1135
1136 r = manager_get_user_by_cgroup(m, cgroup, &u);
1137 if (r > 0)
1138 user_add_to_gc_queue(u);
1139 }
1140
1141 static void manager_dispatch_other(Manager *m, int fd) {
1142 Session *s;
1143 Inhibitor *i;
1144 Button *b;
1145
1146 assert_se(m);
1147 assert_se(fd >= 0);
1148
1149 s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1150 if (s) {
1151 assert(s->fifo_fd == fd);
1152 session_remove_fifo(s);
1153 session_stop(s);
1154 return;
1155 }
1156
1157 i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1158 if (i) {
1159 assert(i->fifo_fd == fd);
1160 inhibitor_stop(i);
1161 inhibitor_free(i);
1162 return;
1163 }
1164
1165 b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1166 if (b) {
1167 assert(b->fd == fd);
1168 button_process(b);
1169 return;
1170 }
1171
1172 assert_not_reached("Got event for unknown fd");
1173 }
1174
1175 static int manager_connect_bus(Manager *m) {
1176 DBusError error;
1177 int r;
1178 struct epoll_event ev;
1179
1180 assert(m);
1181 assert(!m->bus);
1182 assert(m->bus_fd < 0);
1183
1184 dbus_error_init(&error);
1185
1186 m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1187 if (!m->bus) {
1188 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1189 r = -ECONNREFUSED;
1190 goto fail;
1191 }
1192
1193 if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1194 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1195 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1196 !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1197 !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1198 r = log_oom();
1199 goto fail;
1200 }
1201
1202 dbus_bus_add_match(m->bus,
1203 "type='signal',"
1204 "interface='org.freedesktop.systemd1.Agent',"
1205 "member='Released',"
1206 "path='/org/freedesktop/systemd1/agent'",
1207 &error);
1208
1209 if (dbus_error_is_set(&error)) {
1210 log_error("Failed to register match: %s", bus_error_message(&error));
1211 r = -EIO;
1212 goto fail;
1213 }
1214
1215 r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1216 if (dbus_error_is_set(&error)) {
1217 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1218 r = -EIO;
1219 goto fail;
1220 }
1221
1222 if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
1223 log_error("Failed to acquire name.");
1224 r = -EEXIST;
1225 goto fail;
1226 }
1227
1228 m->bus_fd = bus_loop_open(m->bus);
1229 if (m->bus_fd < 0) {
1230 r = m->bus_fd;
1231 goto fail;
1232 }
1233
1234 zero(ev);
1235 ev.events = EPOLLIN;
1236 ev.data.u32 = FD_BUS;
1237
1238 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1239 goto fail;
1240
1241 return 0;
1242
1243 fail:
1244 dbus_error_free(&error);
1245
1246 return r;
1247 }
1248
1249 static int manager_connect_console(Manager *m) {
1250 struct epoll_event ev;
1251
1252 assert(m);
1253 assert(m->console_active_fd < 0);
1254
1255 /* On certain architectures (S390 and Xen, and containers),
1256 /dev/tty0 does not exist, so don't fail if we can't open
1257 it. */
1258 if (access("/dev/tty0", F_OK) < 0) {
1259 m->console_active_fd = -1;
1260 return 0;
1261 }
1262
1263 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1264 if (m->console_active_fd < 0) {
1265
1266 /* On some systems the device node /dev/tty0 may exist
1267 * even though /sys/class/tty/tty0 does not. */
1268 if (errno == ENOENT)
1269 return 0;
1270
1271 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1272 return -errno;
1273 }
1274
1275 zero(ev);
1276 ev.events = 0;
1277 ev.data.u32 = FD_CONSOLE;
1278
1279 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1280 return -errno;
1281
1282 return 0;
1283 }
1284
1285 static int manager_connect_udev(Manager *m) {
1286 struct epoll_event ev;
1287 int r;
1288
1289 assert(m);
1290 assert(!m->udev_seat_monitor);
1291 assert(!m->udev_vcsa_monitor);
1292 assert(!m->udev_button_monitor);
1293
1294 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1295 if (!m->udev_seat_monitor)
1296 return -ENOMEM;
1297
1298 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat");
1299 if (r < 0)
1300 return r;
1301
1302 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL);
1303 if (r < 0)
1304 return r;
1305
1306 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1307 if (r < 0)
1308 return r;
1309
1310 m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1311
1312 zero(ev);
1313 ev.events = EPOLLIN;
1314 ev.data.u32 = FD_SEAT_UDEV;
1315 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1316 return -errno;
1317
1318 /* Don't watch keys if nobody cares */
1319 if (m->handle_power_key != HANDLE_IGNORE ||
1320 m->handle_suspend_key != HANDLE_IGNORE ||
1321 m->handle_hibernate_key != HANDLE_IGNORE ||
1322 m->handle_lid_switch != HANDLE_IGNORE) {
1323
1324 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1325 if (!m->udev_button_monitor)
1326 return -ENOMEM;
1327
1328 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1329 if (r < 0)
1330 return r;
1331
1332 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1333 if (r < 0)
1334 return r;
1335
1336 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1337 if (r < 0)
1338 return r;
1339
1340 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1341
1342 zero(ev);
1343 ev.events = EPOLLIN;
1344 ev.data.u32 = FD_BUTTON_UDEV;
1345 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1346 return -errno;
1347 }
1348
1349 /* Don't bother watching VCSA devices, if nobody cares */
1350 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1351
1352 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1353 if (!m->udev_vcsa_monitor)
1354 return -ENOMEM;
1355
1356 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1357 if (r < 0)
1358 return r;
1359
1360 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1361 if (r < 0)
1362 return r;
1363
1364 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1365
1366 zero(ev);
1367 ev.events = EPOLLIN;
1368 ev.data.u32 = FD_VCSA_UDEV;
1369 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1370 return -errno;
1371 }
1372
1373 return 0;
1374 }
1375
1376 void manager_gc(Manager *m, bool drop_not_started) {
1377 Seat *seat;
1378 Session *session;
1379 User *user;
1380
1381 assert(m);
1382
1383 while ((seat = m->seat_gc_queue)) {
1384 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1385 seat->in_gc_queue = false;
1386
1387 if (seat_check_gc(seat, drop_not_started) == 0) {
1388 seat_stop(seat);
1389 seat_free(seat);
1390 }
1391 }
1392
1393 while ((session = m->session_gc_queue)) {
1394 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1395 session->in_gc_queue = false;
1396
1397 if (session_check_gc(session, drop_not_started) == 0) {
1398 session_stop(session);
1399 session_free(session);
1400 }
1401 }
1402
1403 while ((user = m->user_gc_queue)) {
1404 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1405 user->in_gc_queue = false;
1406
1407 if (user_check_gc(user, drop_not_started) == 0) {
1408 user_stop(user);
1409 user_free(user);
1410 }
1411 }
1412 }
1413
1414 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1415 Session *s;
1416 bool idle_hint;
1417 dual_timestamp ts = { 0, 0 };
1418 Iterator i;
1419
1420 assert(m);
1421
1422 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1423
1424 HASHMAP_FOREACH(s, m->sessions, i) {
1425 dual_timestamp k;
1426 int ih;
1427
1428 ih = session_get_idle_hint(s, &k);
1429 if (ih < 0)
1430 return ih;
1431
1432 if (!ih) {
1433 if (!idle_hint) {
1434 if (k.monotonic < ts.monotonic)
1435 ts = k;
1436 } else {
1437 idle_hint = false;
1438 ts = k;
1439 }
1440 } else if (idle_hint) {
1441
1442 if (k.monotonic > ts.monotonic)
1443 ts = k;
1444 }
1445 }
1446
1447 if (t)
1448 *t = ts;
1449
1450 return idle_hint;
1451 }
1452
1453 int manager_dispatch_idle_action(Manager *m) {
1454 struct dual_timestamp since;
1455 struct itimerspec its;
1456 int r;
1457 usec_t n;
1458
1459 assert(m);
1460
1461 if (m->idle_action == HANDLE_IGNORE ||
1462 m->idle_action_usec <= 0) {
1463 r = 0;
1464 goto finish;
1465 }
1466
1467 zero(its);
1468 n = now(CLOCK_MONOTONIC);
1469
1470 r = manager_get_idle_hint(m, &since);
1471 if (r <= 0)
1472 /* Not idle. Let's check if after a timeout it it might be idle then. */
1473 timespec_store(&its.it_value, n + m->idle_action_usec);
1474 else {
1475 /* Idle! Let's see if it's time to do something, or if
1476 * we shall sleep for longer. */
1477
1478 if (n >= since.monotonic + m->idle_action_usec &&
1479 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1480 log_info("System idle. Taking action.");
1481
1482 manager_handle_action(m, 0, m->idle_action, false, false);
1483 m->idle_action_not_before_usec = n;
1484 }
1485
1486 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1487 }
1488
1489 if (m->idle_action_fd < 0) {
1490 struct epoll_event ev;
1491
1492 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1493 if (m->idle_action_fd < 0) {
1494 log_error("Failed to create idle action timer: %m");
1495 r = -errno;
1496 goto finish;
1497 }
1498
1499 zero(ev);
1500 ev.events = EPOLLIN;
1501 ev.data.u32 = FD_IDLE_ACTION;
1502
1503 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1504 log_error("Failed to add idle action timer to epoll: %m");
1505 r = -errno;
1506 goto finish;
1507 }
1508 }
1509
1510 if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1511 log_error("Failed to reset timerfd: %m");
1512 r = -errno;
1513 goto finish;
1514 }
1515
1516 return 0;
1517
1518 finish:
1519 if (m->idle_action_fd >= 0) {
1520 close_nointr_nofail(m->idle_action_fd);
1521 m->idle_action_fd = -1;
1522 }
1523
1524 return r;
1525 }
1526 int manager_startup(Manager *m) {
1527 int r;
1528 Seat *seat;
1529 Session *session;
1530 User *user;
1531 Inhibitor *inhibitor;
1532 Iterator i;
1533
1534 assert(m);
1535 assert(m->epoll_fd <= 0);
1536
1537 cg_shorten_controllers(m->reset_controllers);
1538 cg_shorten_controllers(m->controllers);
1539
1540 m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1541 if (m->epoll_fd < 0)
1542 return -errno;
1543
1544 /* Connect to console */
1545 r = manager_connect_console(m);
1546 if (r < 0)
1547 return r;
1548
1549 /* Connect to udev */
1550 r = manager_connect_udev(m);
1551 if (r < 0)
1552 return r;
1553
1554 /* Connect to the bus */
1555 r = manager_connect_bus(m);
1556 if (r < 0)
1557 return r;
1558
1559 /* Instantiate magic seat 0 */
1560 r = manager_add_seat(m, "seat0", &m->vtconsole);
1561 if (r < 0)
1562 return r;
1563
1564 /* Deserialize state */
1565 manager_enumerate_devices(m);
1566 manager_enumerate_seats(m);
1567 manager_enumerate_users(m);
1568 manager_enumerate_sessions(m);
1569 manager_enumerate_inhibitors(m);
1570 manager_enumerate_buttons(m);
1571
1572 /* Remove stale objects before we start them */
1573 manager_gc(m, false);
1574
1575 /* Reserve the special reserved VT */
1576 manager_reserve_vt(m);
1577
1578 /* And start everything */
1579 HASHMAP_FOREACH(seat, m->seats, i)
1580 seat_start(seat);
1581
1582 HASHMAP_FOREACH(user, m->users, i)
1583 user_start(user);
1584
1585 HASHMAP_FOREACH(session, m->sessions, i)
1586 session_start(session);
1587
1588 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1589 inhibitor_start(inhibitor);
1590
1591 manager_dispatch_idle_action(m);
1592
1593 return 0;
1594 }
1595
1596 static int manager_recheck_buttons(Manager *m) {
1597 Iterator i;
1598 Button *b;
1599 int r = 0;
1600
1601 assert(m);
1602
1603 HASHMAP_FOREACH(b, m->buttons, i) {
1604 int q;
1605
1606 q = button_recheck(b);
1607 if (q > 0)
1608 return 1;
1609 if (q < 0)
1610 r = q;
1611 }
1612
1613 return r;
1614 }
1615
1616 int manager_run(Manager *m) {
1617 assert(m);
1618
1619 for (;;) {
1620 struct epoll_event event;
1621 int n;
1622 int msec = -1;
1623
1624 manager_gc(m, true);
1625
1626 if (manager_dispatch_delayed(m) > 0)
1627 continue;
1628
1629 if (manager_recheck_buttons(m) > 0)
1630 continue;
1631
1632 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1633 continue;
1634
1635 manager_gc(m, true);
1636
1637 if (m->delayed_unit) {
1638 usec_t x, y;
1639
1640 x = now(CLOCK_MONOTONIC);
1641 y = m->delayed_timestamp + m->inhibit_delay_max;
1642
1643 msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1644 }
1645
1646 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1647 if (n < 0) {
1648 if (errno == EINTR || errno == EAGAIN)
1649 continue;
1650
1651 log_error("epoll() failed: %m");
1652 return -errno;
1653 }
1654
1655 if (n == 0)
1656 continue;
1657
1658 switch (event.data.u32) {
1659
1660 case FD_SEAT_UDEV:
1661 manager_dispatch_seat_udev(m);
1662 break;
1663
1664 case FD_VCSA_UDEV:
1665 manager_dispatch_vcsa_udev(m);
1666 break;
1667
1668 case FD_BUTTON_UDEV:
1669 manager_dispatch_button_udev(m);
1670 break;
1671
1672 case FD_CONSOLE:
1673 manager_dispatch_console(m);
1674 break;
1675
1676 case FD_IDLE_ACTION:
1677 manager_dispatch_idle_action(m);
1678 break;
1679
1680 case FD_BUS:
1681 bus_loop_dispatch(m->bus_fd);
1682 break;
1683
1684 default:
1685 if (event.data.u32 >= FD_OTHER_BASE)
1686 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1687 }
1688 }
1689
1690 return 0;
1691 }
1692
1693 static int manager_parse_config_file(Manager *m) {
1694 FILE *f;
1695 const char *fn;
1696 int r;
1697
1698 assert(m);
1699
1700 fn = "/etc/systemd/logind.conf";
1701 f = fopen(fn, "re");
1702 if (!f) {
1703 if (errno == ENOENT)
1704 return 0;
1705
1706 log_warning("Failed to open configuration file %s: %m", fn);
1707 return -errno;
1708 }
1709
1710 r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
1711 if (r < 0)
1712 log_warning("Failed to parse configuration file: %s", strerror(-r));
1713
1714 fclose(f);
1715
1716 return r;
1717 }
1718
1719 int main(int argc, char *argv[]) {
1720 Manager *m = NULL;
1721 int r;
1722
1723 log_set_target(LOG_TARGET_AUTO);
1724 log_set_facility(LOG_AUTH);
1725 log_parse_environment();
1726 log_open();
1727
1728 umask(0022);
1729
1730 if (argc != 1) {
1731 log_error("This program takes no arguments.");
1732 r = -EINVAL;
1733 goto finish;
1734 }
1735
1736 m = manager_new();
1737 if (!m) {
1738 r = log_oom();
1739 goto finish;
1740 }
1741
1742 manager_parse_config_file(m);
1743
1744 r = manager_startup(m);
1745 if (r < 0) {
1746 log_error("Failed to fully start up daemon: %s", strerror(-r));
1747 goto finish;
1748 }
1749
1750 log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1751
1752 sd_notify(false,
1753 "READY=1\n"
1754 "STATUS=Processing requests...");
1755
1756 r = manager_run(m);
1757
1758 log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1759
1760 finish:
1761 sd_notify(false,
1762 "STATUS=Shutting down...");
1763
1764 if (m)
1765 manager_free(m);
1766
1767 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1768 }