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