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