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