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