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