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