chiark / gitweb /
Fix spelling errors using 'codespell' tool
[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 = strdup(cgroup);
1045         if (!p)
1046                 return log_oom();
1047
1048         for (;;) {
1049                 char *e;
1050
1051                 e = strrchr(p, '/');
1052                 if (!e || e == p) {
1053                         free(p);
1054                         *session = NULL;
1055                         return 0;
1056                 }
1057
1058                 *e = 0;
1059
1060                 s = hashmap_get(m->session_cgroups, p);
1061                 if (s) {
1062                         free(p);
1063                         *session = s;
1064                         return 1;
1065                 }
1066         }
1067 }
1068
1069 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1070         User *u;
1071         char *p;
1072
1073         assert(m);
1074         assert(cgroup);
1075         assert(user);
1076
1077         u = hashmap_get(m->user_cgroups, cgroup);
1078         if (u) {
1079                 *user = u;
1080                 return 1;
1081         }
1082
1083         p = strdup(cgroup);
1084         if (!p)
1085                 return log_oom();
1086
1087         for (;;) {
1088                 char *e;
1089
1090                 e = strrchr(p, '/');
1091                 if (!e || e == p) {
1092                         free(p);
1093                         *user = NULL;
1094                         return 0;
1095                 }
1096
1097                 *e = 0;
1098
1099                 u = hashmap_get(m->user_cgroups, p);
1100                 if (u) {
1101                         free(p);
1102                         *user = u;
1103                         return 1;
1104                 }
1105         }
1106 }
1107
1108 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1109         char *p;
1110         int r;
1111
1112         assert(m);
1113         assert(pid >= 1);
1114         assert(session);
1115
1116         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1117         if (r < 0)
1118                 return r;
1119
1120         r = manager_get_session_by_cgroup(m, p, session);
1121         free(p);
1122
1123         return r;
1124 }
1125
1126 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1127         Session *s;
1128         User *u;
1129         int r;
1130
1131         r = manager_get_session_by_cgroup(m, cgroup, &s);
1132         if (r > 0)
1133                 session_add_to_gc_queue(s);
1134
1135         r = manager_get_user_by_cgroup(m, cgroup, &u);
1136         if (r > 0)
1137                 user_add_to_gc_queue(u);
1138 }
1139
1140 static void manager_dispatch_other(Manager *m, int fd) {
1141         Session *s;
1142         Inhibitor *i;
1143         Button *b;
1144
1145         assert_se(m);
1146         assert_se(fd >= 0);
1147
1148         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1149         if (s) {
1150                 assert(s->fifo_fd == fd);
1151                 session_remove_fifo(s);
1152                 session_stop(s);
1153                 return;
1154         }
1155
1156         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1157         if (i) {
1158                 assert(i->fifo_fd == fd);
1159                 inhibitor_stop(i);
1160                 inhibitor_free(i);
1161                 return;
1162         }
1163
1164         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1165         if (b) {
1166                 assert(b->fd == fd);
1167                 button_process(b);
1168                 return;
1169         }
1170
1171         assert_not_reached("Got event for unknown fd");
1172 }
1173
1174 static int manager_connect_bus(Manager *m) {
1175         DBusError error;
1176         int r;
1177         struct epoll_event ev = {
1178                 .events = EPOLLIN,
1179                 .data.u32 = FD_BUS,
1180         };
1181
1182         assert(m);
1183         assert(!m->bus);
1184         assert(m->bus_fd < 0);
1185
1186         dbus_error_init(&error);
1187
1188         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1189         if (!m->bus) {
1190                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1191                 r = -ECONNREFUSED;
1192                 goto fail;
1193         }
1194
1195         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1196             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1197             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1198             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1199             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1200                 r = log_oom();
1201                 goto fail;
1202         }
1203
1204         dbus_bus_add_match(m->bus,
1205                            "type='signal',"
1206                            "interface='org.freedesktop.systemd1.Agent',"
1207                            "member='Released',"
1208                            "path='/org/freedesktop/systemd1/agent'",
1209                            &error);
1210
1211         if (dbus_error_is_set(&error)) {
1212                 log_error("Failed to register match: %s", bus_error_message(&error));
1213                 r = -EIO;
1214                 goto fail;
1215         }
1216
1217         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1218         if (dbus_error_is_set(&error)) {
1219                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1220                 r = -EIO;
1221                 goto fail;
1222         }
1223
1224         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1225                 log_error("Failed to acquire name.");
1226                 r = -EEXIST;
1227                 goto fail;
1228         }
1229
1230         m->bus_fd = bus_loop_open(m->bus);
1231         if (m->bus_fd < 0) {
1232                 r = m->bus_fd;
1233                 goto fail;
1234         }
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                 .events = 0,
1250                 .data.u32 = FD_CONSOLE,
1251         };
1252
1253         assert(m);
1254         assert(m->console_active_fd < 0);
1255
1256         /* On certain architectures (S390 and Xen, and containers),
1257            /dev/tty0 does not exist, so don't fail if we can't open
1258            it. */
1259         if (access("/dev/tty0", F_OK) < 0) {
1260                 m->console_active_fd = -1;
1261                 return 0;
1262         }
1263
1264         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1265         if (m->console_active_fd < 0) {
1266
1267                 /* On some systems the device node /dev/tty0 may exist
1268                  * even though /sys/class/tty/tty0 does not. */
1269                 if (errno == ENOENT)
1270                         return 0;
1271
1272                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1273                 return -errno;
1274         }
1275
1276         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1277                 return -errno;
1278
1279         return 0;
1280 }
1281
1282 static int manager_connect_udev(Manager *m) {
1283         int r;
1284         struct epoll_event ev = {
1285                 .events = EPOLLIN,
1286                 .data.u32 = FD_SEAT_UDEV,
1287         };
1288
1289         assert(m);
1290         assert(!m->udev_seat_monitor);
1291         assert(!m->udev_vcsa_monitor);
1292         assert(!m->udev_button_monitor);
1293
1294         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1295         if (!m->udev_seat_monitor)
1296                 return -ENOMEM;
1297
1298         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1299         if (r < 0)
1300                 return r;
1301
1302         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1303         if (r < 0)
1304                 return r;
1305
1306         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1307
1308         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1309                 return -errno;
1310
1311         /* Don't watch keys if nobody cares */
1312         if (m->handle_power_key != HANDLE_IGNORE ||
1313             m->handle_suspend_key != HANDLE_IGNORE ||
1314             m->handle_hibernate_key != HANDLE_IGNORE ||
1315             m->handle_lid_switch != HANDLE_IGNORE) {
1316
1317                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1318                 if (!m->udev_button_monitor)
1319                         return -ENOMEM;
1320
1321                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1322                 if (r < 0)
1323                         return r;
1324
1325                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1326                 if (r < 0)
1327                         return r;
1328
1329                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1330                 if (r < 0)
1331                         return r;
1332
1333                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1334
1335                 zero(ev);
1336                 ev.events = EPOLLIN;
1337                 ev.data.u32 = FD_BUTTON_UDEV;
1338                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1339                         return -errno;
1340         }
1341
1342         /* Don't bother watching VCSA devices, if nobody cares */
1343         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1344
1345                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1346                 if (!m->udev_vcsa_monitor)
1347                         return -ENOMEM;
1348
1349                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1350                 if (r < 0)
1351                         return r;
1352
1353                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1354                 if (r < 0)
1355                         return r;
1356
1357                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1358
1359                 zero(ev);
1360                 ev.events = EPOLLIN;
1361                 ev.data.u32 = FD_VCSA_UDEV;
1362                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1363                         return -errno;
1364         }
1365
1366         return 0;
1367 }
1368
1369 void manager_gc(Manager *m, bool drop_not_started) {
1370         Seat *seat;
1371         Session *session;
1372         User *user;
1373
1374         assert(m);
1375
1376         while ((seat = m->seat_gc_queue)) {
1377                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1378                 seat->in_gc_queue = false;
1379
1380                 if (seat_check_gc(seat, drop_not_started) == 0) {
1381                         seat_stop(seat);
1382                         seat_free(seat);
1383                 }
1384         }
1385
1386         while ((session = m->session_gc_queue)) {
1387                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1388                 session->in_gc_queue = false;
1389
1390                 if (session_check_gc(session, drop_not_started) == 0) {
1391                         session_stop(session);
1392                         session_free(session);
1393                 }
1394         }
1395
1396         while ((user = m->user_gc_queue)) {
1397                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1398                 user->in_gc_queue = false;
1399
1400                 if (user_check_gc(user, drop_not_started) == 0) {
1401                         user_stop(user);
1402                         user_free(user);
1403                 }
1404         }
1405 }
1406
1407 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1408         Session *s;
1409         bool idle_hint;
1410         dual_timestamp ts = { 0, 0 };
1411         Iterator i;
1412
1413         assert(m);
1414
1415         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1416
1417         HASHMAP_FOREACH(s, m->sessions, i) {
1418                 dual_timestamp k;
1419                 int ih;
1420
1421                 ih = session_get_idle_hint(s, &k);
1422                 if (ih < 0)
1423                         return ih;
1424
1425                 if (!ih) {
1426                         if (!idle_hint) {
1427                                 if (k.monotonic < ts.monotonic)
1428                                         ts = k;
1429                         } else {
1430                                 idle_hint = false;
1431                                 ts = k;
1432                         }
1433                 } else if (idle_hint) {
1434
1435                         if (k.monotonic > ts.monotonic)
1436                                 ts = k;
1437                 }
1438         }
1439
1440         if (t)
1441                 *t = ts;
1442
1443         return idle_hint;
1444 }
1445
1446 int manager_dispatch_idle_action(Manager *m) {
1447         struct dual_timestamp since;
1448         struct itimerspec its = {};
1449         int r;
1450         usec_t n;
1451
1452         assert(m);
1453
1454         if (m->idle_action == HANDLE_IGNORE ||
1455             m->idle_action_usec <= 0) {
1456                 r = 0;
1457                 goto finish;
1458         }
1459
1460         n = now(CLOCK_MONOTONIC);
1461
1462         r = manager_get_idle_hint(m, &since);
1463         if (r <= 0)
1464                 /* Not idle. Let's check if after a timeout it might be idle then. */
1465                 timespec_store(&its.it_value, n + m->idle_action_usec);
1466         else {
1467                 /* Idle! Let's see if it's time to do something, or if
1468                  * we shall sleep for longer. */
1469
1470                 if (n >= since.monotonic + m->idle_action_usec &&
1471                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1472                         log_info("System idle. Taking action.");
1473
1474                         manager_handle_action(m, 0, m->idle_action, false, false);
1475                         m->idle_action_not_before_usec = n;
1476                 }
1477
1478                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1479         }
1480
1481         if (m->idle_action_fd < 0) {
1482                 struct epoll_event ev = {
1483                         .events = EPOLLIN,
1484                         .data.u32 = FD_IDLE_ACTION,
1485                 };
1486
1487                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1488                 if (m->idle_action_fd < 0) {
1489                         log_error("Failed to create idle action timer: %m");
1490                         r = -errno;
1491                         goto finish;
1492                 }
1493
1494                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1495                         log_error("Failed to add idle action timer to epoll: %m");
1496                         r = -errno;
1497                         goto finish;
1498                 }
1499         }
1500
1501         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1502                 log_error("Failed to reset timerfd: %m");
1503                 r = -errno;
1504                 goto finish;
1505         }
1506
1507         return 0;
1508
1509 finish:
1510         if (m->idle_action_fd >= 0) {
1511                 close_nointr_nofail(m->idle_action_fd);
1512                 m->idle_action_fd = -1;
1513         }
1514
1515         return r;
1516 }
1517 int manager_startup(Manager *m) {
1518         int r;
1519         Seat *seat;
1520         Session *session;
1521         User *user;
1522         Inhibitor *inhibitor;
1523         Iterator i;
1524
1525         assert(m);
1526         assert(m->epoll_fd <= 0);
1527
1528         cg_shorten_controllers(m->reset_controllers);
1529         cg_shorten_controllers(m->controllers);
1530
1531         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1532         if (m->epoll_fd < 0)
1533                 return -errno;
1534
1535         /* Connect to console */
1536         r = manager_connect_console(m);
1537         if (r < 0)
1538                 return r;
1539
1540         /* Connect to udev */
1541         r = manager_connect_udev(m);
1542         if (r < 0)
1543                 return r;
1544
1545         /* Connect to the bus */
1546         r = manager_connect_bus(m);
1547         if (r < 0)
1548                 return r;
1549
1550         /* Instantiate magic seat 0 */
1551         r = manager_add_seat(m, "seat0", &m->vtconsole);
1552         if (r < 0)
1553                 return r;
1554
1555         /* Deserialize state */
1556         manager_enumerate_devices(m);
1557         manager_enumerate_seats(m);
1558         manager_enumerate_users(m);
1559         manager_enumerate_sessions(m);
1560         manager_enumerate_inhibitors(m);
1561         manager_enumerate_buttons(m);
1562
1563         /* Remove stale objects before we start them */
1564         manager_gc(m, false);
1565
1566         /* Reserve the special reserved VT */
1567         manager_reserve_vt(m);
1568
1569         /* And start everything */
1570         HASHMAP_FOREACH(seat, m->seats, i)
1571                 seat_start(seat);
1572
1573         HASHMAP_FOREACH(user, m->users, i)
1574                 user_start(user);
1575
1576         HASHMAP_FOREACH(session, m->sessions, i)
1577                 session_start(session);
1578
1579         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1580                 inhibitor_start(inhibitor);
1581
1582         manager_dispatch_idle_action(m);
1583
1584         return 0;
1585 }
1586
1587 static int manager_recheck_buttons(Manager *m) {
1588         Iterator i;
1589         Button *b;
1590         int r = 0;
1591
1592         assert(m);
1593
1594         HASHMAP_FOREACH(b, m->buttons, i) {
1595                 int q;
1596
1597                 q = button_recheck(b);
1598                 if (q > 0)
1599                         return 1;
1600                 if (q < 0)
1601                         r = q;
1602         }
1603
1604         return r;
1605 }
1606
1607 int manager_run(Manager *m) {
1608         assert(m);
1609
1610         for (;;) {
1611                 struct epoll_event event;
1612                 int n;
1613                 int msec = -1;
1614
1615                 manager_gc(m, true);
1616
1617                 if (manager_dispatch_delayed(m) > 0)
1618                         continue;
1619
1620                 if (manager_recheck_buttons(m) > 0)
1621                         continue;
1622
1623                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1624                         continue;
1625
1626                 manager_gc(m, true);
1627
1628                 if (m->action_what != 0) {
1629                         usec_t x, y;
1630
1631                         x = now(CLOCK_MONOTONIC);
1632                         y = m->action_timestamp + m->inhibit_delay_max;
1633
1634                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1635                 }
1636
1637                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1638                 if (n < 0) {
1639                         if (errno == EINTR || errno == EAGAIN)
1640                                 continue;
1641
1642                         log_error("epoll() failed: %m");
1643                         return -errno;
1644                 }
1645
1646                 if (n == 0)
1647                         continue;
1648
1649                 switch (event.data.u32) {
1650
1651                 case FD_SEAT_UDEV:
1652                         manager_dispatch_seat_udev(m);
1653                         break;
1654
1655                 case FD_VCSA_UDEV:
1656                         manager_dispatch_vcsa_udev(m);
1657                         break;
1658
1659                 case FD_BUTTON_UDEV:
1660                         manager_dispatch_button_udev(m);
1661                         break;
1662
1663                 case FD_CONSOLE:
1664                         manager_dispatch_console(m);
1665                         break;
1666
1667                 case FD_IDLE_ACTION:
1668                         manager_dispatch_idle_action(m);
1669                         break;
1670
1671                 case FD_BUS:
1672                         bus_loop_dispatch(m->bus_fd);
1673                         break;
1674
1675                 default:
1676                         if (event.data.u32 >= FD_OTHER_BASE)
1677                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1678                 }
1679         }
1680
1681         return 0;
1682 }
1683
1684 static int manager_parse_config_file(Manager *m) {
1685         FILE *f;
1686         const char *fn;
1687         int r;
1688
1689         assert(m);
1690
1691         fn = "/etc/systemd/logind.conf";
1692         f = fopen(fn, "re");
1693         if (!f) {
1694                 if (errno == ENOENT)
1695                         return 0;
1696
1697                 log_warning("Failed to open configuration file %s: %m", fn);
1698                 return -errno;
1699         }
1700
1701         r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
1702         if (r < 0)
1703                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1704
1705         fclose(f);
1706
1707         return r;
1708 }
1709
1710 int main(int argc, char *argv[]) {
1711         Manager *m = NULL;
1712         int r;
1713
1714         log_set_target(LOG_TARGET_AUTO);
1715         log_set_facility(LOG_AUTH);
1716         log_parse_environment();
1717         log_open();
1718
1719         umask(0022);
1720
1721         if (argc != 1) {
1722                 log_error("This program takes no arguments.");
1723                 r = -EINVAL;
1724                 goto finish;
1725         }
1726
1727         /* Always create the directories people can create inotify
1728          * watches in. Note that some applications might check for the
1729          * existence of /run/systemd/seats/ to determine whether
1730          * logind is available, so please always make sure this check
1731          * stays in. */
1732         mkdir_label("/run/systemd/seats", 0755);
1733         mkdir_label("/run/systemd/users", 0755);
1734         mkdir_label("/run/systemd/sessions", 0755);
1735
1736         m = manager_new();
1737         if (!m) {
1738                 r = log_oom();
1739                 goto finish;
1740         }
1741
1742         manager_parse_config_file(m);
1743
1744         r = manager_startup(m);
1745         if (r < 0) {
1746                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1747                 goto finish;
1748         }
1749
1750         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1751
1752         sd_notify(false,
1753                   "READY=1\n"
1754                   "STATUS=Processing requests...");
1755
1756         r = manager_run(m);
1757
1758         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1759
1760 finish:
1761         sd_notify(false,
1762                   "STATUS=Shutting down...");
1763
1764         if (m)
1765                 manager_free(m);
1766
1767         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1768 }