chiark / gitweb /
systemctl,loginctl,cgls: do not ellipsize cgroup members when --full is specified
[elogind.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_tag(e, "seat-master");
463         if (r < 0)
464                 goto finish;
465
466         r = udev_enumerate_scan_devices(e);
467         if (r < 0)
468                 goto finish;
469
470         first = udev_enumerate_get_list_entry(e);
471         udev_list_entry_foreach(item, first) {
472                 struct udev_device *d;
473                 int k;
474
475                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
476                 if (!d) {
477                         r = -ENOMEM;
478                         goto finish;
479                 }
480
481                 k = manager_process_seat_device(m, d);
482                 udev_device_unref(d);
483
484                 if (k < 0)
485                         r = k;
486         }
487
488 finish:
489         if (e)
490                 udev_enumerate_unref(e);
491
492         return r;
493 }
494
495 int manager_enumerate_buttons(Manager *m) {
496         struct udev_list_entry *item = NULL, *first = NULL;
497         struct udev_enumerate *e;
498         int r;
499
500         assert(m);
501
502         /* Loads buttons from udev */
503
504         if (m->handle_power_key == HANDLE_IGNORE &&
505             m->handle_suspend_key == HANDLE_IGNORE &&
506             m->handle_hibernate_key == HANDLE_IGNORE &&
507             m->handle_lid_switch == HANDLE_IGNORE)
508                 return 0;
509
510         e = udev_enumerate_new(m->udev);
511         if (!e) {
512                 r = -ENOMEM;
513                 goto finish;
514         }
515
516         r = udev_enumerate_add_match_subsystem(e, "input");
517         if (r < 0)
518                 goto finish;
519
520         r = udev_enumerate_add_match_tag(e, "power-switch");
521         if (r < 0)
522                 goto finish;
523
524         r = udev_enumerate_scan_devices(e);
525         if (r < 0)
526                 goto finish;
527
528         first = udev_enumerate_get_list_entry(e);
529         udev_list_entry_foreach(item, first) {
530                 struct udev_device *d;
531                 int k;
532
533                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
534                 if (!d) {
535                         r = -ENOMEM;
536                         goto finish;
537                 }
538
539                 k = manager_process_button_device(m, d);
540                 udev_device_unref(d);
541
542                 if (k < 0)
543                         r = k;
544         }
545
546 finish:
547         if (e)
548                 udev_enumerate_unref(e);
549
550         return r;
551 }
552
553 int manager_enumerate_seats(Manager *m) {
554         DIR *d;
555         struct dirent *de;
556         int r = 0;
557
558         assert(m);
559
560         /* This loads data about seats stored on disk, but does not
561          * actually create any seats. Removes data of seats that no
562          * longer exist. */
563
564         d = opendir("/run/systemd/seats");
565         if (!d) {
566                 if (errno == ENOENT)
567                         return 0;
568
569                 log_error("Failed to open /run/systemd/seats: %m");
570                 return -errno;
571         }
572
573         while ((de = readdir(d))) {
574                 Seat *s;
575                 int k;
576
577                 if (!dirent_is_file(de))
578                         continue;
579
580                 s = hashmap_get(m->seats, de->d_name);
581                 if (!s) {
582                         unlinkat(dirfd(d), de->d_name, 0);
583                         continue;
584                 }
585
586                 k = seat_load(s);
587                 if (k < 0)
588                         r = k;
589         }
590
591         closedir(d);
592
593         return r;
594 }
595
596 static int manager_enumerate_users_from_cgroup(Manager *m) {
597         int r = 0, k;
598         char *name;
599         DIR *d;
600
601         r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
602         if (r < 0) {
603                 if (r == -ENOENT)
604                         return 0;
605
606                 log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
607                 return r;
608         }
609
610         while ((k = cg_read_subgroup(d, &name)) > 0) {
611                 User *user;
612
613                 k = manager_add_user_by_name(m, name, &user);
614                 if (k < 0) {
615                         free(name);
616                         r = k;
617                         continue;
618                 }
619
620                 user_add_to_gc_queue(user);
621
622                 if (!user->cgroup_path)
623                         if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) {
624                                 r = -ENOMEM;
625                                 free(name);
626                                 break;
627                         }
628
629                 free(name);
630         }
631
632         if (r >= 0 && k < 0)
633                 r = k;
634
635         closedir(d);
636
637         return r;
638 }
639
640 static int manager_enumerate_linger_users(Manager *m) {
641         DIR *d;
642         struct dirent *de;
643         int r = 0;
644
645         d = opendir("/var/lib/systemd/linger");
646         if (!d) {
647                 if (errno == ENOENT)
648                         return 0;
649
650                 log_error("Failed to open /var/lib/systemd/linger/: %m");
651                 return -errno;
652         }
653
654         while ((de = readdir(d))) {
655                 int k;
656
657                 if (!dirent_is_file(de))
658                         continue;
659
660                 k = manager_add_user_by_name(m, de->d_name, NULL);
661                 if (k < 0) {
662                         log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
663                         r = k;
664                 }
665         }
666
667         closedir(d);
668
669         return r;
670 }
671
672 int manager_enumerate_users(Manager *m) {
673         DIR *d;
674         struct dirent *de;
675         int r, k;
676
677         assert(m);
678
679         /* First, enumerate user cgroups */
680         r = manager_enumerate_users_from_cgroup(m);
681
682         /* Second, add lingering users on top */
683         k = manager_enumerate_linger_users(m);
684         if (k < 0)
685                 r = k;
686
687         /* Third, read in user data stored on disk */
688         d = opendir("/run/systemd/users");
689         if (!d) {
690                 if (errno == ENOENT)
691                         return 0;
692
693                 log_error("Failed to open /run/systemd/users: %m");
694                 return -errno;
695         }
696
697         while ((de = readdir(d))) {
698                 uid_t uid;
699                 User *u;
700
701                 if (!dirent_is_file(de))
702                         continue;
703
704                 k = parse_uid(de->d_name, &uid);
705                 if (k < 0) {
706                         log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
707                         continue;
708                 }
709
710                 u = hashmap_get(m->users, ULONG_TO_PTR(uid));
711                 if (!u) {
712                         unlinkat(dirfd(d), de->d_name, 0);
713                         continue;
714                 }
715
716                 k = user_load(u);
717                 if (k < 0)
718                         r = k;
719         }
720
721         closedir(d);
722
723         return r;
724 }
725
726 static int manager_enumerate_sessions_from_cgroup(Manager *m) {
727         User *u;
728         Iterator i;
729         int r = 0;
730
731         HASHMAP_FOREACH(u, m->users, i) {
732                 DIR *d;
733                 char *name;
734                 int k;
735
736                 if (!u->cgroup_path)
737                         continue;
738
739                 k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
740                 if (k < 0) {
741                         if (k == -ENOENT)
742                                 continue;
743
744                         log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
745                         r = k;
746                         continue;
747                 }
748
749                 while ((k = cg_read_subgroup(d, &name)) > 0) {
750                         Session *session;
751
752                         if (streq(name, "shared"))
753                                 continue;
754
755                         k = manager_add_session(m, u, name, &session);
756                         if (k < 0) {
757                                 free(name);
758                                 break;
759                         }
760
761                         session_add_to_gc_queue(session);
762
763                         if (!session->cgroup_path)
764                                 if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) {
765                                         k = -ENOMEM;
766                                         free(name);
767                                         break;
768                                 }
769
770                         free(name);
771                 }
772
773                 closedir(d);
774
775                 if (k < 0)
776                         r = k;
777         }
778
779         return r;
780 }
781
782 int manager_enumerate_sessions(Manager *m) {
783         DIR *d;
784         struct dirent *de;
785         int r = 0;
786
787         assert(m);
788
789         /* First enumerate session cgroups */
790         r = manager_enumerate_sessions_from_cgroup(m);
791
792         /* Second, read in session data stored on disk */
793         d = opendir("/run/systemd/sessions");
794         if (!d) {
795                 if (errno == ENOENT)
796                         return 0;
797
798                 log_error("Failed to open /run/systemd/sessions: %m");
799                 return -errno;
800         }
801
802         while ((de = readdir(d))) {
803                 struct Session *s;
804                 int k;
805
806                 if (!dirent_is_file(de))
807                         continue;
808
809                 s = hashmap_get(m->sessions, de->d_name);
810                 if (!s) {
811                         unlinkat(dirfd(d), de->d_name, 0);
812                         continue;
813                 }
814
815                 k = session_load(s);
816                 if (k < 0)
817                         r = k;
818         }
819
820         closedir(d);
821
822         return r;
823 }
824
825 int manager_enumerate_inhibitors(Manager *m) {
826         DIR *d;
827         struct dirent *de;
828         int r = 0;
829
830         assert(m);
831
832         d = opendir("/run/systemd/inhibit");
833         if (!d) {
834                 if (errno == ENOENT)
835                         return 0;
836
837                 log_error("Failed to open /run/systemd/inhibit: %m");
838                 return -errno;
839         }
840
841         while ((de = readdir(d))) {
842                 int k;
843                 Inhibitor *i;
844
845                 if (!dirent_is_file(de))
846                         continue;
847
848                 k = manager_add_inhibitor(m, de->d_name, &i);
849                 if (k < 0) {
850                         log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
851                         r = k;
852                         continue;
853                 }
854
855                 k = inhibitor_load(i);
856                 if (k < 0)
857                         r = k;
858         }
859
860         closedir(d);
861
862         return r;
863 }
864
865 int manager_dispatch_seat_udev(Manager *m) {
866         struct udev_device *d;
867         int r;
868
869         assert(m);
870
871         d = udev_monitor_receive_device(m->udev_seat_monitor);
872         if (!d)
873                 return -ENOMEM;
874
875         r = manager_process_seat_device(m, d);
876         udev_device_unref(d);
877
878         return r;
879 }
880
881 int manager_dispatch_vcsa_udev(Manager *m) {
882         struct udev_device *d;
883         int r = 0;
884         const char *name;
885
886         assert(m);
887
888         d = udev_monitor_receive_device(m->udev_vcsa_monitor);
889         if (!d)
890                 return -ENOMEM;
891
892         name = udev_device_get_sysname(d);
893
894         /* Whenever a VCSA device is removed try to reallocate our
895          * VTs, to make sure our auto VTs never go away. */
896
897         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
898                 r = seat_preallocate_vts(m->vtconsole);
899
900         udev_device_unref(d);
901
902         return r;
903 }
904
905 int manager_dispatch_button_udev(Manager *m) {
906         struct udev_device *d;
907         int r;
908
909         assert(m);
910
911         d = udev_monitor_receive_device(m->udev_button_monitor);
912         if (!d)
913                 return -ENOMEM;
914
915         r = manager_process_button_device(m, d);
916         udev_device_unref(d);
917
918         return r;
919 }
920
921 int manager_dispatch_console(Manager *m) {
922         assert(m);
923
924         if (m->vtconsole)
925                 seat_read_active_vt(m->vtconsole);
926
927         return 0;
928 }
929
930 static int vt_is_busy(int vtnr) {
931         struct vt_stat vt_stat;
932         int r = 0, fd;
933
934         assert(vtnr >= 1);
935
936         /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
937          * we'd open the latter we'd open the foreground tty which
938          * hence would be unconditionally busy. By opening /dev/tty1
939          * we avoid this. Since tty1 is special and needs to be an
940          * explicitly loaded getty or DM this is safe. */
941
942         fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
943         if (fd < 0)
944                 return -errno;
945
946         if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
947                 r = -errno;
948         else
949                 r = !!(vt_stat.v_state & (1 << vtnr));
950
951         close_nointr_nofail(fd);
952
953         return r;
954 }
955
956 int manager_spawn_autovt(Manager *m, int vtnr) {
957         int r;
958         char *name = NULL;
959         const char *mode = "fail";
960
961         assert(m);
962         assert(vtnr >= 1);
963
964         if ((unsigned) vtnr > m->n_autovts &&
965             (unsigned) vtnr != m->reserve_vt)
966                 return 0;
967
968         if ((unsigned) vtnr != m->reserve_vt) {
969                 /* If this is the reserved TTY, we'll start the getty
970                  * on it in any case, but otherwise only if it is not
971                  * busy. */
972
973                 r = vt_is_busy(vtnr);
974                 if (r < 0)
975                         return r;
976                 else if (r > 0)
977                         return -EBUSY;
978         }
979
980         if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
981                 log_error("Could not allocate service name.");
982                 r = -ENOMEM;
983                 goto finish;
984         }
985
986         r = bus_method_call_with_reply (
987                         m->bus,
988                         "org.freedesktop.systemd1",
989                         "/org/freedesktop/systemd1",
990                         "org.freedesktop.systemd1.Manager",
991                         "StartUnit",
992                         NULL,
993                         NULL,
994                         DBUS_TYPE_STRING, &name,
995                         DBUS_TYPE_STRING, &mode,
996                         DBUS_TYPE_INVALID);
997
998 finish:
999         free(name);
1000
1001         return r;
1002 }
1003
1004 static int manager_reserve_vt(Manager *m) {
1005         _cleanup_free_ char *p = NULL;
1006
1007         assert(m);
1008
1009         if (m->reserve_vt <= 0)
1010                 return 0;
1011
1012         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
1013                 return log_oom();
1014
1015         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
1016         if (m->reserve_vt_fd < 0) {
1017
1018                 /* Don't complain on VT-less systems */
1019                 if (errno != ENOENT)
1020                         log_warning("Failed to pin reserved VT: %m");
1021                 return -errno;
1022         }
1023
1024         return 0;
1025 }
1026
1027 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
1028         Session *s;
1029         char *p;
1030
1031         assert(m);
1032         assert(cgroup);
1033         assert(session);
1034
1035         s = hashmap_get(m->session_cgroups, cgroup);
1036         if (s) {
1037                 *session = s;
1038                 return 1;
1039         }
1040
1041         p = strdup(cgroup);
1042         if (!p)
1043                 return log_oom();
1044
1045         for (;;) {
1046                 char *e;
1047
1048                 e = strrchr(p, '/');
1049                 if (!e || e == p) {
1050                         free(p);
1051                         *session = NULL;
1052                         return 0;
1053                 }
1054
1055                 *e = 0;
1056
1057                 s = hashmap_get(m->session_cgroups, p);
1058                 if (s) {
1059                         free(p);
1060                         *session = s;
1061                         return 1;
1062                 }
1063         }
1064 }
1065
1066 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1067         User *u;
1068         char *p;
1069
1070         assert(m);
1071         assert(cgroup);
1072         assert(user);
1073
1074         u = hashmap_get(m->user_cgroups, cgroup);
1075         if (u) {
1076                 *user = u;
1077                 return 1;
1078         }
1079
1080         p = strdup(cgroup);
1081         if (!p)
1082                 return log_oom();
1083
1084         for (;;) {
1085                 char *e;
1086
1087                 e = strrchr(p, '/');
1088                 if (!e || e == p) {
1089                         free(p);
1090                         *user = NULL;
1091                         return 0;
1092                 }
1093
1094                 *e = 0;
1095
1096                 u = hashmap_get(m->user_cgroups, p);
1097                 if (u) {
1098                         free(p);
1099                         *user = u;
1100                         return 1;
1101                 }
1102         }
1103 }
1104
1105 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1106         char *p;
1107         int r;
1108
1109         assert(m);
1110         assert(pid >= 1);
1111         assert(session);
1112
1113         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1114         if (r < 0)
1115                 return r;
1116
1117         r = manager_get_session_by_cgroup(m, p, session);
1118         free(p);
1119
1120         return r;
1121 }
1122
1123 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1124         Session *s;
1125         User *u;
1126         int r;
1127
1128         r = manager_get_session_by_cgroup(m, cgroup, &s);
1129         if (r > 0)
1130                 session_add_to_gc_queue(s);
1131
1132         r = manager_get_user_by_cgroup(m, cgroup, &u);
1133         if (r > 0)
1134                 user_add_to_gc_queue(u);
1135 }
1136
1137 static void manager_dispatch_other(Manager *m, int fd) {
1138         Session *s;
1139         Inhibitor *i;
1140         Button *b;
1141
1142         assert_se(m);
1143         assert_se(fd >= 0);
1144
1145         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1146         if (s) {
1147                 assert(s->fifo_fd == fd);
1148                 session_remove_fifo(s);
1149                 session_stop(s);
1150                 return;
1151         }
1152
1153         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1154         if (i) {
1155                 assert(i->fifo_fd == fd);
1156                 inhibitor_stop(i);
1157                 inhibitor_free(i);
1158                 return;
1159         }
1160
1161         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1162         if (b) {
1163                 assert(b->fd == fd);
1164                 button_process(b);
1165                 return;
1166         }
1167
1168         assert_not_reached("Got event for unknown fd");
1169 }
1170
1171 static int manager_connect_bus(Manager *m) {
1172         DBusError error;
1173         int r;
1174         struct epoll_event ev;
1175
1176         assert(m);
1177         assert(!m->bus);
1178         assert(m->bus_fd < 0);
1179
1180         dbus_error_init(&error);
1181
1182         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1183         if (!m->bus) {
1184                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1185                 r = -ECONNREFUSED;
1186                 goto fail;
1187         }
1188
1189         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1190             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1191             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1192             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1193             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1194                 r = log_oom();
1195                 goto fail;
1196         }
1197
1198         dbus_bus_add_match(m->bus,
1199                            "type='signal',"
1200                            "interface='org.freedesktop.systemd1.Agent',"
1201                            "member='Released',"
1202                            "path='/org/freedesktop/systemd1/agent'",
1203                            &error);
1204
1205         if (dbus_error_is_set(&error)) {
1206                 log_error("Failed to register match: %s", bus_error_message(&error));
1207                 r = -EIO;
1208                 goto fail;
1209         }
1210
1211         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1212         if (dbus_error_is_set(&error)) {
1213                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1214                 r = -EIO;
1215                 goto fail;
1216         }
1217
1218         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1219                 log_error("Failed to acquire name.");
1220                 r = -EEXIST;
1221                 goto fail;
1222         }
1223
1224         m->bus_fd = bus_loop_open(m->bus);
1225         if (m->bus_fd < 0) {
1226                 r = m->bus_fd;
1227                 goto fail;
1228         }
1229
1230         zero(ev);
1231         ev.events = EPOLLIN;
1232         ev.data.u32 = FD_BUS;
1233
1234         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1235                 goto fail;
1236
1237         return 0;
1238
1239 fail:
1240         dbus_error_free(&error);
1241
1242         return r;
1243 }
1244
1245 static int manager_connect_console(Manager *m) {
1246         struct epoll_event ev;
1247
1248         assert(m);
1249         assert(m->console_active_fd < 0);
1250
1251         /* On certain architectures (S390 and Xen, and containers),
1252            /dev/tty0 does not exist, so don't fail if we can't open
1253            it. */
1254         if (access("/dev/tty0", F_OK) < 0) {
1255                 m->console_active_fd = -1;
1256                 return 0;
1257         }
1258
1259         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1260         if (m->console_active_fd < 0) {
1261
1262                 /* On some systems the device node /dev/tty0 may exist
1263                  * even though /sys/class/tty/tty0 does not. */
1264                 if (errno == ENOENT)
1265                         return 0;
1266
1267                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1268                 return -errno;
1269         }
1270
1271         zero(ev);
1272         ev.events = 0;
1273         ev.data.u32 = FD_CONSOLE;
1274
1275         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1276                 return -errno;
1277
1278         return 0;
1279 }
1280
1281 static int manager_connect_udev(Manager *m) {
1282         struct epoll_event ev;
1283         int r;
1284
1285         assert(m);
1286         assert(!m->udev_seat_monitor);
1287         assert(!m->udev_vcsa_monitor);
1288         assert(!m->udev_button_monitor);
1289
1290         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1291         if (!m->udev_seat_monitor)
1292                 return -ENOMEM;
1293
1294         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat-master");
1295         if (r < 0)
1296                 return r;
1297
1298         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1299         if (r < 0)
1300                 return r;
1301
1302         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1303
1304         zero(ev);
1305         ev.events = EPOLLIN;
1306         ev.data.u32 = FD_SEAT_UDEV;
1307         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1308                 return -errno;
1309
1310         /* Don't watch keys if nobody cares */
1311         if (m->handle_power_key != HANDLE_IGNORE ||
1312             m->handle_suspend_key != HANDLE_IGNORE ||
1313             m->handle_hibernate_key != HANDLE_IGNORE ||
1314             m->handle_lid_switch != HANDLE_IGNORE) {
1315
1316                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1317                 if (!m->udev_button_monitor)
1318                         return -ENOMEM;
1319
1320                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1321                 if (r < 0)
1322                         return r;
1323
1324                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1325                 if (r < 0)
1326                         return r;
1327
1328                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1329                 if (r < 0)
1330                         return r;
1331
1332                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1333
1334                 zero(ev);
1335                 ev.events = EPOLLIN;
1336                 ev.data.u32 = FD_BUTTON_UDEV;
1337                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1338                         return -errno;
1339         }
1340
1341         /* Don't bother watching VCSA devices, if nobody cares */
1342         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1343
1344                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1345                 if (!m->udev_vcsa_monitor)
1346                         return -ENOMEM;
1347
1348                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1349                 if (r < 0)
1350                         return r;
1351
1352                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1353                 if (r < 0)
1354                         return r;
1355
1356                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1357
1358                 zero(ev);
1359                 ev.events = EPOLLIN;
1360                 ev.data.u32 = FD_VCSA_UDEV;
1361                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1362                         return -errno;
1363         }
1364
1365         return 0;
1366 }
1367
1368 void manager_gc(Manager *m, bool drop_not_started) {
1369         Seat *seat;
1370         Session *session;
1371         User *user;
1372
1373         assert(m);
1374
1375         while ((seat = m->seat_gc_queue)) {
1376                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1377                 seat->in_gc_queue = false;
1378
1379                 if (seat_check_gc(seat, drop_not_started) == 0) {
1380                         seat_stop(seat);
1381                         seat_free(seat);
1382                 }
1383         }
1384
1385         while ((session = m->session_gc_queue)) {
1386                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1387                 session->in_gc_queue = false;
1388
1389                 if (session_check_gc(session, drop_not_started) == 0) {
1390                         session_stop(session);
1391                         session_free(session);
1392                 }
1393         }
1394
1395         while ((user = m->user_gc_queue)) {
1396                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1397                 user->in_gc_queue = false;
1398
1399                 if (user_check_gc(user, drop_not_started) == 0) {
1400                         user_stop(user);
1401                         user_free(user);
1402                 }
1403         }
1404 }
1405
1406 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1407         Session *s;
1408         bool idle_hint;
1409         dual_timestamp ts = { 0, 0 };
1410         Iterator i;
1411
1412         assert(m);
1413
1414         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1415
1416         HASHMAP_FOREACH(s, m->sessions, i) {
1417                 dual_timestamp k;
1418                 int ih;
1419
1420                 ih = session_get_idle_hint(s, &k);
1421                 if (ih < 0)
1422                         return ih;
1423
1424                 if (!ih) {
1425                         if (!idle_hint) {
1426                                 if (k.monotonic < ts.monotonic)
1427                                         ts = k;
1428                         } else {
1429                                 idle_hint = false;
1430                                 ts = k;
1431                         }
1432                 } else if (idle_hint) {
1433
1434                         if (k.monotonic > ts.monotonic)
1435                                 ts = k;
1436                 }
1437         }
1438
1439         if (t)
1440                 *t = ts;
1441
1442         return idle_hint;
1443 }
1444
1445 int manager_dispatch_idle_action(Manager *m) {
1446         struct dual_timestamp since;
1447         struct itimerspec its;
1448         int r;
1449         usec_t n;
1450
1451         assert(m);
1452
1453         if (m->idle_action == HANDLE_IGNORE ||
1454             m->idle_action_usec <= 0) {
1455                 r = 0;
1456                 goto finish;
1457         }
1458
1459         zero(its);
1460         n = now(CLOCK_MONOTONIC);
1461
1462         r = manager_get_idle_hint(m, &since);
1463         if (r <= 0)
1464                 /* Not idle. Let's check if after a timeout it it might be idle then. */
1465                 timespec_store(&its.it_value, n + m->idle_action_usec);
1466         else {
1467                 /* Idle! Let's see if it's time to do something, or if
1468                  * we shall sleep for longer. */
1469
1470                 if (n >= since.monotonic + m->idle_action_usec &&
1471                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1472                         log_info("System idle. Taking action.");
1473
1474                         manager_handle_action(m, 0, m->idle_action, false, false);
1475                         m->idle_action_not_before_usec = n;
1476                 }
1477
1478                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1479         }
1480
1481         if (m->idle_action_fd < 0) {
1482                 struct epoll_event ev;
1483
1484                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1485                 if (m->idle_action_fd < 0) {
1486                         log_error("Failed to create idle action timer: %m");
1487                         r = -errno;
1488                         goto finish;
1489                 }
1490
1491                 zero(ev);
1492                 ev.events = EPOLLIN;
1493                 ev.data.u32 = FD_IDLE_ACTION;
1494
1495                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1496                         log_error("Failed to add idle action timer to epoll: %m");
1497                         r = -errno;
1498                         goto finish;
1499                 }
1500         }
1501
1502         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1503                 log_error("Failed to reset timerfd: %m");
1504                 r = -errno;
1505                 goto finish;
1506         }
1507
1508         return 0;
1509
1510 finish:
1511         if (m->idle_action_fd >= 0) {
1512                 close_nointr_nofail(m->idle_action_fd);
1513                 m->idle_action_fd = -1;
1514         }
1515
1516         return r;
1517 }
1518 int manager_startup(Manager *m) {
1519         int r;
1520         Seat *seat;
1521         Session *session;
1522         User *user;
1523         Inhibitor *inhibitor;
1524         Iterator i;
1525
1526         assert(m);
1527         assert(m->epoll_fd <= 0);
1528
1529         cg_shorten_controllers(m->reset_controllers);
1530         cg_shorten_controllers(m->controllers);
1531
1532         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1533         if (m->epoll_fd < 0)
1534                 return -errno;
1535
1536         /* Connect to console */
1537         r = manager_connect_console(m);
1538         if (r < 0)
1539                 return r;
1540
1541         /* Connect to udev */
1542         r = manager_connect_udev(m);
1543         if (r < 0)
1544                 return r;
1545
1546         /* Connect to the bus */
1547         r = manager_connect_bus(m);
1548         if (r < 0)
1549                 return r;
1550
1551         /* Instantiate magic seat 0 */
1552         r = manager_add_seat(m, "seat0", &m->vtconsole);
1553         if (r < 0)
1554                 return r;
1555
1556         /* Deserialize state */
1557         manager_enumerate_devices(m);
1558         manager_enumerate_seats(m);
1559         manager_enumerate_users(m);
1560         manager_enumerate_sessions(m);
1561         manager_enumerate_inhibitors(m);
1562         manager_enumerate_buttons(m);
1563
1564         /* Remove stale objects before we start them */
1565         manager_gc(m, false);
1566
1567         /* Reserve the special reserved VT */
1568         manager_reserve_vt(m);
1569
1570         /* And start everything */
1571         HASHMAP_FOREACH(seat, m->seats, i)
1572                 seat_start(seat);
1573
1574         HASHMAP_FOREACH(user, m->users, i)
1575                 user_start(user);
1576
1577         HASHMAP_FOREACH(session, m->sessions, i)
1578                 session_start(session);
1579
1580         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1581                 inhibitor_start(inhibitor);
1582
1583         manager_dispatch_idle_action(m);
1584
1585         return 0;
1586 }
1587
1588 static int manager_recheck_buttons(Manager *m) {
1589         Iterator i;
1590         Button *b;
1591         int r = 0;
1592
1593         assert(m);
1594
1595         HASHMAP_FOREACH(b, m->buttons, i) {
1596                 int q;
1597
1598                 q = button_recheck(b);
1599                 if (q > 0)
1600                         return 1;
1601                 if (q < 0)
1602                         r = q;
1603         }
1604
1605         return r;
1606 }
1607
1608 int manager_run(Manager *m) {
1609         assert(m);
1610
1611         for (;;) {
1612                 struct epoll_event event;
1613                 int n;
1614                 int msec = -1;
1615
1616                 manager_gc(m, true);
1617
1618                 if (manager_dispatch_delayed(m) > 0)
1619                         continue;
1620
1621                 if (manager_recheck_buttons(m) > 0)
1622                         continue;
1623
1624                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1625                         continue;
1626
1627                 manager_gc(m, true);
1628
1629                 if (m->delayed_unit) {
1630                         usec_t x, y;
1631
1632                         x = now(CLOCK_MONOTONIC);
1633                         y = m->delayed_timestamp + m->inhibit_delay_max;
1634
1635                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1636                 }
1637
1638                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1639                 if (n < 0) {
1640                         if (errno == EINTR || errno == EAGAIN)
1641                                 continue;
1642
1643                         log_error("epoll() failed: %m");
1644                         return -errno;
1645                 }
1646
1647                 if (n == 0)
1648                         continue;
1649
1650                 switch (event.data.u32) {
1651
1652                 case FD_SEAT_UDEV:
1653                         manager_dispatch_seat_udev(m);
1654                         break;
1655
1656                 case FD_VCSA_UDEV:
1657                         manager_dispatch_vcsa_udev(m);
1658                         break;
1659
1660                 case FD_BUTTON_UDEV:
1661                         manager_dispatch_button_udev(m);
1662                         break;
1663
1664                 case FD_CONSOLE:
1665                         manager_dispatch_console(m);
1666                         break;
1667
1668                 case FD_IDLE_ACTION:
1669                         manager_dispatch_idle_action(m);
1670                         break;
1671
1672                 case FD_BUS:
1673                         bus_loop_dispatch(m->bus_fd);
1674                         break;
1675
1676                 default:
1677                         if (event.data.u32 >= FD_OTHER_BASE)
1678                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1679                 }
1680         }
1681
1682         return 0;
1683 }
1684
1685 static int manager_parse_config_file(Manager *m) {
1686         FILE *f;
1687         const char *fn;
1688         int r;
1689
1690         assert(m);
1691
1692         fn = "/etc/systemd/logind.conf";
1693         f = fopen(fn, "re");
1694         if (!f) {
1695                 if (errno == ENOENT)
1696                         return 0;
1697
1698                 log_warning("Failed to open configuration file %s: %m", fn);
1699                 return -errno;
1700         }
1701
1702         r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
1703         if (r < 0)
1704                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1705
1706         fclose(f);
1707
1708         return r;
1709 }
1710
1711 int main(int argc, char *argv[]) {
1712         Manager *m = NULL;
1713         int r;
1714
1715         log_set_target(LOG_TARGET_AUTO);
1716         log_set_facility(LOG_AUTH);
1717         log_parse_environment();
1718         log_open();
1719
1720         umask(0022);
1721
1722         if (argc != 1) {
1723                 log_error("This program takes no arguments.");
1724                 r = -EINVAL;
1725                 goto finish;
1726         }
1727
1728         m = manager_new();
1729         if (!m) {
1730                 r = log_oom();
1731                 goto finish;
1732         }
1733
1734         manager_parse_config_file(m);
1735
1736         r = manager_startup(m);
1737         if (r < 0) {
1738                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1739                 goto finish;
1740         }
1741
1742         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1743
1744         sd_notify(false,
1745                   "READY=1\n"
1746                   "STATUS=Processing requests...");
1747
1748         r = manager_run(m);
1749
1750         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1751
1752 finish:
1753         sd_notify(false,
1754                   "STATUS=Shutting down...");
1755
1756         if (m)
1757                 manager_free(m);
1758
1759         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1760 }