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