chiark / gitweb /
702382acff4ac2633ddeca18a4962edb3515c8e4
[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(pid >= 1);
997         assert(session);
998
999         r = cg_pid_get_unit(pid, &unit);
1000         if (r < 0)
1001                 return r;
1002
1003         s = hashmap_get(m->session_units, unit);
1004         if (!s)
1005                 return 0;
1006
1007         *session = s;
1008         return 1;
1009 }
1010
1011 int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
1012         _cleanup_free_ char *unit = NULL;
1013         User *u;
1014         int r;
1015
1016         assert(m);
1017         assert(pid >= 1);
1018         assert(user);
1019
1020         r = cg_pid_get_slice(pid, &unit);
1021         if (r < 0)
1022                 return r;
1023
1024         u = hashmap_get(m->user_units, unit);
1025         if (!u)
1026                 return 0;
1027
1028         *user = u;
1029         return 1;
1030 }
1031
1032 static void manager_dispatch_other(Manager *m, int fd) {
1033         Session *s;
1034         Inhibitor *i;
1035         Button *b;
1036
1037         assert_se(m);
1038         assert_se(fd >= 0);
1039
1040         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1041         if (s) {
1042                 assert(s->fifo_fd == fd);
1043                 session_remove_fifo(s);
1044                 session_stop(s);
1045                 return;
1046         }
1047
1048         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1049         if (i) {
1050                 assert(i->fifo_fd == fd);
1051                 inhibitor_stop(i);
1052                 inhibitor_free(i);
1053                 return;
1054         }
1055
1056         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1057         if (b) {
1058                 assert(b->fd == fd);
1059                 button_process(b);
1060                 return;
1061         }
1062
1063         assert_not_reached("Got event for unknown fd");
1064 }
1065
1066 static int manager_connect_bus(Manager *m) {
1067         DBusError error;
1068         int r;
1069         struct epoll_event ev = {
1070                 .events = EPOLLIN,
1071                 .data.u32 = FD_BUS,
1072         };
1073
1074         assert(m);
1075         assert(!m->bus);
1076         assert(m->bus_fd < 0);
1077
1078         dbus_error_init(&error);
1079
1080         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1081         if (!m->bus) {
1082                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1083                 r = -ECONNREFUSED;
1084                 goto fail;
1085         }
1086
1087         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1088             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1089             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1090             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1091             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1092                 r = log_oom();
1093                 goto fail;
1094         }
1095
1096         dbus_bus_add_match(m->bus,
1097                            "type='signal',"
1098                            "sender='"DBUS_SERVICE_DBUS"',"
1099                            "interface='"DBUS_INTERFACE_DBUS"',"
1100                            "member='NameOwnerChanged',"
1101                            "path='"DBUS_PATH_DBUS"'",
1102                            &error);
1103         if (dbus_error_is_set(&error)) {
1104                 log_error("Failed to add match for NameOwnerChanged: %s", bus_error_message(&error));
1105                 dbus_error_free(&error);
1106         }
1107
1108         dbus_bus_add_match(m->bus,
1109                            "type='signal',"
1110                            "sender='org.freedesktop.systemd1',"
1111                            "interface='org.freedesktop.systemd1.Manager',"
1112                            "member='JobRemoved',"
1113                            "path='/org/freedesktop/systemd1'",
1114                            &error);
1115         if (dbus_error_is_set(&error)) {
1116                 log_error("Failed to add match for JobRemoved: %s", bus_error_message(&error));
1117                 dbus_error_free(&error);
1118         }
1119
1120         dbus_bus_add_match(m->bus,
1121                            "type='signal',"
1122                            "sender='org.freedesktop.systemd1',"
1123                            "interface='org.freedesktop.systemd1.Manager',"
1124                            "member='UnitRemoved',"
1125                            "path='/org/freedesktop/systemd1'",
1126                            &error);
1127         if (dbus_error_is_set(&error)) {
1128                 log_error("Failed to add match for UnitRemoved: %s", bus_error_message(&error));
1129                 dbus_error_free(&error);
1130         }
1131
1132         dbus_bus_add_match(m->bus,
1133                            "type='signal',"
1134                            "sender='org.freedesktop.systemd1',"
1135                            "interface='org.freedesktop.DBus.Properties',"
1136                            "member='PropertiesChanged'",
1137                            &error);
1138         if (dbus_error_is_set(&error)) {
1139                 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
1140                 dbus_error_free(&error);
1141         }
1142
1143         dbus_bus_add_match(m->bus,
1144                            "type='signal',"
1145                            "sender='org.freedesktop.systemd1',"
1146                            "interface='org.freedesktop.systemd1.Manager',"
1147                            "member='Reloading',"
1148                            "path='/org/freedesktop/systemd1'",
1149                            &error);
1150         if (dbus_error_is_set(&error)) {
1151                 log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
1152                 dbus_error_free(&error);
1153         }
1154
1155         r = bus_method_call_with_reply(
1156                         m->bus,
1157                         "org.freedesktop.systemd1",
1158                         "/org/freedesktop/systemd1",
1159                         "org.freedesktop.systemd1.Manager",
1160                         "Subscribe",
1161                         NULL,
1162                         &error,
1163                         DBUS_TYPE_INVALID);
1164         if (r < 0) {
1165                 log_error("Failed to enable subscription: %s", bus_error(&error, r));
1166                 dbus_error_free(&error);
1167         }
1168
1169         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1170         if (dbus_error_is_set(&error)) {
1171                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1172                 r = -EIO;
1173                 goto fail;
1174         }
1175
1176         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1177                 log_error("Failed to acquire name.");
1178                 r = -EEXIST;
1179                 goto fail;
1180         }
1181
1182         m->bus_fd = bus_loop_open(m->bus);
1183         if (m->bus_fd < 0) {
1184                 r = m->bus_fd;
1185                 goto fail;
1186         }
1187
1188         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1189                 goto fail;
1190
1191         return 0;
1192
1193 fail:
1194         dbus_error_free(&error);
1195
1196         return r;
1197 }
1198
1199 static int manager_connect_console(Manager *m) {
1200         struct epoll_event ev = {
1201                 .events = 0,
1202                 .data.u32 = FD_CONSOLE,
1203         };
1204
1205         assert(m);
1206         assert(m->console_active_fd < 0);
1207
1208         /* On certain architectures (S390 and Xen, and containers),
1209            /dev/tty0 does not exist, so don't fail if we can't open
1210            it. */
1211         if (access("/dev/tty0", F_OK) < 0) {
1212                 m->console_active_fd = -1;
1213                 return 0;
1214         }
1215
1216         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1217         if (m->console_active_fd < 0) {
1218
1219                 /* On some systems the device node /dev/tty0 may exist
1220                  * even though /sys/class/tty/tty0 does not. */
1221                 if (errno == ENOENT)
1222                         return 0;
1223
1224                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1225                 return -errno;
1226         }
1227
1228         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1229                 return -errno;
1230
1231         return 0;
1232 }
1233
1234 static int manager_connect_udev(Manager *m) {
1235         int r;
1236         struct epoll_event ev = {
1237                 .events = EPOLLIN,
1238                 .data.u32 = FD_SEAT_UDEV,
1239         };
1240
1241         assert(m);
1242         assert(!m->udev_seat_monitor);
1243         assert(!m->udev_device_monitor);
1244         assert(!m->udev_vcsa_monitor);
1245         assert(!m->udev_button_monitor);
1246
1247         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1248         if (!m->udev_seat_monitor)
1249                 return -ENOMEM;
1250
1251         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
1252         if (r < 0)
1253                 return r;
1254
1255         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1256         if (r < 0)
1257                 return r;
1258
1259         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1260
1261         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1262                 return -errno;
1263
1264         m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1265         if (!m->udev_device_monitor)
1266                 return -ENOMEM;
1267
1268         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
1269         if (r < 0)
1270                 return r;
1271
1272         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
1273         if (r < 0)
1274                 return r;
1275
1276         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
1277         if (r < 0)
1278                 return r;
1279
1280         r = udev_monitor_enable_receiving(m->udev_device_monitor);
1281         if (r < 0)
1282                 return r;
1283
1284         m->udev_device_fd = udev_monitor_get_fd(m->udev_device_monitor);
1285         zero(ev);
1286         ev.events = EPOLLIN;
1287         ev.data.u32 = FD_DEVICE_UDEV;
1288         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_device_fd, &ev) < 0)
1289                 return -errno;
1290
1291         /* Don't watch keys if nobody cares */
1292         if (m->handle_power_key != HANDLE_IGNORE ||
1293             m->handle_suspend_key != HANDLE_IGNORE ||
1294             m->handle_hibernate_key != HANDLE_IGNORE ||
1295             m->handle_lid_switch != HANDLE_IGNORE) {
1296
1297                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1298                 if (!m->udev_button_monitor)
1299                         return -ENOMEM;
1300
1301                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1302                 if (r < 0)
1303                         return r;
1304
1305                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1306                 if (r < 0)
1307                         return r;
1308
1309                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1310                 if (r < 0)
1311                         return r;
1312
1313                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1314
1315                 zero(ev);
1316                 ev.events = EPOLLIN;
1317                 ev.data.u32 = FD_BUTTON_UDEV;
1318                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1319                         return -errno;
1320         }
1321
1322         /* Don't bother watching VCSA devices, if nobody cares */
1323         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1324
1325                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1326                 if (!m->udev_vcsa_monitor)
1327                         return -ENOMEM;
1328
1329                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1330                 if (r < 0)
1331                         return r;
1332
1333                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1334                 if (r < 0)
1335                         return r;
1336
1337                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1338
1339                 zero(ev);
1340                 ev.events = EPOLLIN;
1341                 ev.data.u32 = FD_VCSA_UDEV;
1342                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1343                         return -errno;
1344         }
1345
1346         return 0;
1347 }
1348
1349 void manager_gc(Manager *m, bool drop_not_started) {
1350         Seat *seat;
1351         Session *session;
1352         User *user;
1353
1354         assert(m);
1355
1356         while ((seat = m->seat_gc_queue)) {
1357                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1358                 seat->in_gc_queue = false;
1359
1360                 if (seat_check_gc(seat, drop_not_started) == 0) {
1361                         seat_stop(seat);
1362                         seat_free(seat);
1363                 }
1364         }
1365
1366         while ((session = m->session_gc_queue)) {
1367                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1368                 session->in_gc_queue = false;
1369
1370                 if (session_check_gc(session, drop_not_started) == 0) {
1371                         session_stop(session);
1372                         session_finalize(session);
1373                         session_free(session);
1374                 }
1375         }
1376
1377         while ((user = m->user_gc_queue)) {
1378                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1379                 user->in_gc_queue = false;
1380
1381                 if (user_check_gc(user, drop_not_started) == 0) {
1382                         user_stop(user);
1383                         user_finalize(user);
1384                         user_free(user);
1385                 }
1386         }
1387 }
1388
1389 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1390         Session *s;
1391         bool idle_hint;
1392         dual_timestamp ts = { 0, 0 };
1393         Iterator i;
1394
1395         assert(m);
1396
1397         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
1398
1399         HASHMAP_FOREACH(s, m->sessions, i) {
1400                 dual_timestamp k;
1401                 int ih;
1402
1403                 ih = session_get_idle_hint(s, &k);
1404                 if (ih < 0)
1405                         return ih;
1406
1407                 if (!ih) {
1408                         if (!idle_hint) {
1409                                 if (k.monotonic < ts.monotonic)
1410                                         ts = k;
1411                         } else {
1412                                 idle_hint = false;
1413                                 ts = k;
1414                         }
1415                 } else if (idle_hint) {
1416
1417                         if (k.monotonic > ts.monotonic)
1418                                 ts = k;
1419                 }
1420         }
1421
1422         if (t)
1423                 *t = ts;
1424
1425         return idle_hint;
1426 }
1427
1428 bool manager_shall_kill(Manager *m, const char *user) {
1429         assert(m);
1430         assert(user);
1431
1432         if (!m->kill_user_processes)
1433                 return false;
1434
1435         if (strv_contains(m->kill_exclude_users, user))
1436                 return false;
1437
1438         if (strv_isempty(m->kill_only_users))
1439                 return true;
1440
1441         return strv_contains(m->kill_only_users, user);
1442 }
1443
1444 int manager_dispatch_idle_action(Manager *m) {
1445         struct dual_timestamp since;
1446         struct itimerspec its = {};
1447         int r;
1448         usec_t n;
1449
1450         assert(m);
1451
1452         if (m->idle_action == HANDLE_IGNORE ||
1453             m->idle_action_usec <= 0) {
1454                 r = 0;
1455                 goto finish;
1456         }
1457
1458         n = now(CLOCK_MONOTONIC);
1459
1460         r = manager_get_idle_hint(m, &since);
1461         if (r <= 0)
1462                 /* Not idle. Let's check if after a timeout it might be idle then. */
1463                 timespec_store(&its.it_value, n + m->idle_action_usec);
1464         else {
1465                 /* Idle! Let's see if it's time to do something, or if
1466                  * we shall sleep for longer. */
1467
1468                 if (n >= since.monotonic + m->idle_action_usec &&
1469                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1470                         log_info("System idle. Taking action.");
1471
1472                         manager_handle_action(m, 0, m->idle_action, false, false);
1473                         m->idle_action_not_before_usec = n;
1474                 }
1475
1476                 timespec_store(&its.it_value, MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec);
1477         }
1478
1479         if (m->idle_action_fd < 0) {
1480                 struct epoll_event ev = {
1481                         .events = EPOLLIN,
1482                         .data.u32 = FD_IDLE_ACTION,
1483                 };
1484
1485                 m->idle_action_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
1486                 if (m->idle_action_fd < 0) {
1487                         log_error("Failed to create idle action timer: %m");
1488                         r = -errno;
1489                         goto finish;
1490                 }
1491
1492                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->idle_action_fd, &ev) < 0) {
1493                         log_error("Failed to add idle action timer to epoll: %m");
1494                         r = -errno;
1495                         goto finish;
1496                 }
1497         }
1498
1499         if (timerfd_settime(m->idle_action_fd, TFD_TIMER_ABSTIME, &its, NULL) < 0) {
1500                 log_error("Failed to reset timerfd: %m");
1501                 r = -errno;
1502                 goto finish;
1503         }
1504
1505         return 0;
1506
1507 finish:
1508         if (m->idle_action_fd >= 0) {
1509                 close_nointr_nofail(m->idle_action_fd);
1510                 m->idle_action_fd = -1;
1511         }
1512
1513         return r;
1514 }
1515 int manager_startup(Manager *m) {
1516         int r;
1517         Seat *seat;
1518         Session *session;
1519         User *user;
1520         Inhibitor *inhibitor;
1521         Iterator i;
1522
1523         assert(m);
1524         assert(m->epoll_fd <= 0);
1525
1526         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1527         if (m->epoll_fd < 0)
1528                 return -errno;
1529
1530         /* Connect to console */
1531         r = manager_connect_console(m);
1532         if (r < 0)
1533                 return r;
1534
1535         /* Connect to udev */
1536         r = manager_connect_udev(m);
1537         if (r < 0)
1538                 return r;
1539
1540         /* Connect to the bus */
1541         r = manager_connect_bus(m);
1542         if (r < 0)
1543                 return r;
1544
1545         /* Instantiate magic seat 0 */
1546         r = manager_add_seat(m, "seat0", &m->seat0);
1547         if (r < 0)
1548                 return r;
1549
1550         /* Deserialize state */
1551         r = manager_enumerate_devices(m);
1552         if (r < 0)
1553                 log_warning("Device enumeration failed: %s", strerror(-r));
1554
1555         r = manager_enumerate_seats(m);
1556         if (r < 0)
1557                 log_warning("Seat enumeration failed: %s", strerror(-r));
1558
1559         r = manager_enumerate_users(m);
1560         if (r < 0)
1561                 log_warning("User enumeration failed: %s", strerror(-r));
1562
1563         r = manager_enumerate_sessions(m);
1564         if (r < 0)
1565                 log_warning("Session enumeration failed: %s", strerror(-r));
1566
1567         r = manager_enumerate_inhibitors(m);
1568         if (r < 0)
1569                 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1570
1571         r = manager_enumerate_buttons(m);
1572         if (r < 0)
1573                 log_warning("Button enumeration failed: %s", strerror(-r));
1574
1575         /* Remove stale objects before we start them */
1576         manager_gc(m, false);
1577
1578         /* Reserve the special reserved VT */
1579         manager_reserve_vt(m);
1580
1581         /* And start everything */
1582         HASHMAP_FOREACH(seat, m->seats, i)
1583                 seat_start(seat);
1584
1585         HASHMAP_FOREACH(user, m->users, i)
1586                 user_start(user);
1587
1588         HASHMAP_FOREACH(session, m->sessions, i)
1589                 session_start(session);
1590
1591         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1592                 inhibitor_start(inhibitor);
1593
1594         manager_dispatch_idle_action(m);
1595
1596         return 0;
1597 }
1598
1599 static int manager_recheck_buttons(Manager *m) {
1600         Iterator i;
1601         Button *b;
1602         int r = 0;
1603
1604         assert(m);
1605
1606         HASHMAP_FOREACH(b, m->buttons, i) {
1607                 int q;
1608
1609                 q = button_recheck(b);
1610                 if (q > 0)
1611                         return 1;
1612                 if (q < 0)
1613                         r = q;
1614         }
1615
1616         return r;
1617 }
1618
1619 int manager_run(Manager *m) {
1620         assert(m);
1621
1622         for (;;) {
1623                 struct epoll_event event;
1624                 int n;
1625                 int msec = -1;
1626
1627                 manager_gc(m, true);
1628
1629                 if (manager_dispatch_delayed(m) > 0)
1630                         continue;
1631
1632                 if (manager_recheck_buttons(m) > 0)
1633                         continue;
1634
1635                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1636                         continue;
1637
1638                 manager_gc(m, true);
1639
1640                 if (m->action_what != 0 && !m->action_job) {
1641                         usec_t x, y;
1642
1643                         x = now(CLOCK_MONOTONIC);
1644                         y = m->action_timestamp + m->inhibit_delay_max;
1645
1646                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1647                 }
1648
1649                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1650                 if (n < 0) {
1651                         if (errno == EINTR || errno == EAGAIN)
1652                                 continue;
1653
1654                         log_error("epoll() failed: %m");
1655                         return -errno;
1656                 }
1657
1658                 if (n == 0)
1659                         continue;
1660
1661                 switch (event.data.u32) {
1662
1663                 case FD_SEAT_UDEV:
1664                         manager_dispatch_seat_udev(m);
1665                         break;
1666
1667                 case FD_DEVICE_UDEV:
1668                         manager_dispatch_device_udev(m);
1669                         break;
1670
1671                 case FD_VCSA_UDEV:
1672                         manager_dispatch_vcsa_udev(m);
1673                         break;
1674
1675                 case FD_BUTTON_UDEV:
1676                         manager_dispatch_button_udev(m);
1677                         break;
1678
1679                 case FD_CONSOLE:
1680                         manager_dispatch_console(m);
1681                         break;
1682
1683                 case FD_IDLE_ACTION:
1684                         manager_dispatch_idle_action(m);
1685                         break;
1686
1687                 case FD_BUS:
1688                         bus_loop_dispatch(m->bus_fd);
1689                         break;
1690
1691                 default:
1692                         if (event.data.u32 >= FD_OTHER_BASE)
1693                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1694                 }
1695         }
1696
1697         return 0;
1698 }
1699
1700 static int manager_parse_config_file(Manager *m) {
1701         static const char fn[] = "/etc/systemd/logind.conf";
1702         _cleanup_fclose_ FILE *f = NULL;
1703         int r;
1704
1705         assert(m);
1706
1707         f = fopen(fn, "re");
1708         if (!f) {
1709                 if (errno == ENOENT)
1710                         return 0;
1711
1712                 log_warning("Failed to open configuration file %s: %m", fn);
1713                 return -errno;
1714         }
1715
1716         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1717                          (void*) logind_gperf_lookup, false, false, m);
1718         if (r < 0)
1719                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1720
1721         return r;
1722 }
1723
1724 int main(int argc, char *argv[]) {
1725         Manager *m = NULL;
1726         int r;
1727
1728         log_set_target(LOG_TARGET_AUTO);
1729         log_set_facility(LOG_AUTH);
1730         log_parse_environment();
1731         log_open();
1732
1733         umask(0022);
1734
1735         if (argc != 1) {
1736                 log_error("This program takes no arguments.");
1737                 r = -EINVAL;
1738                 goto finish;
1739         }
1740
1741         /* Always create the directories people can create inotify
1742          * watches in. Note that some applications might check for the
1743          * existence of /run/systemd/seats/ to determine whether
1744          * logind is available, so please always make sure this check
1745          * stays in. */
1746         mkdir_label("/run/systemd/seats", 0755);
1747         mkdir_label("/run/systemd/users", 0755);
1748         mkdir_label("/run/systemd/sessions", 0755);
1749
1750         m = manager_new();
1751         if (!m) {
1752                 r = log_oom();
1753                 goto finish;
1754         }
1755
1756         manager_parse_config_file(m);
1757
1758         r = manager_startup(m);
1759         if (r < 0) {
1760                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1761                 goto finish;
1762         }
1763
1764         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1765
1766         sd_notify(false,
1767                   "READY=1\n"
1768                   "STATUS=Processing requests...");
1769
1770         r = manager_run(m);
1771
1772         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1773
1774 finish:
1775         sd_notify(false,
1776                   "STATUS=Shutting down...");
1777
1778         if (m)
1779                 manager_free(m);
1780
1781         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1782 }