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