chiark / gitweb /
logind: fix serialization of ListInhibitors() request
[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 <libudev.h>
24 #include <fcntl.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <linux/vt.h>
28 #include <sys/timerfd.h>
29
30 #include "sd-daemon.h"
31 #include "strv.h"
32 #include "conf-parser.h"
33 #include "mkdir.h"
34 #include "bus-util.h"
35 #include "bus-error.h"
36 #include "logind.h"
37
38 Manager *manager_new(void) {
39         Manager *m;
40         int r;
41
42         m = new0(Manager, 1);
43         if (!m)
44                 return NULL;
45
46         m->console_active_fd = -1;
47         m->reserve_vt_fd = -1;
48
49         m->n_autovts = 6;
50         m->reserve_vt = 6;
51         m->inhibit_delay_max = 5 * USEC_PER_SEC;
52         m->handle_power_key = HANDLE_POWEROFF;
53         m->handle_suspend_key = HANDLE_SUSPEND;
54         m->handle_hibernate_key = HANDLE_HIBERNATE;
55         m->handle_lid_switch = HANDLE_SUSPEND;
56         m->lid_switch_ignore_inhibited = true;
57
58         m->idle_action_usec = 30 * USEC_PER_MINUTE;
59         m->idle_action = HANDLE_IGNORE;
60         m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
61
62         m->devices = hashmap_new(string_hash_func, string_compare_func);
63         m->seats = hashmap_new(string_hash_func, string_compare_func);
64         m->sessions = hashmap_new(string_hash_func, string_compare_func);
65         m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
66         m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
67         m->buttons = hashmap_new(string_hash_func, string_compare_func);
68
69         m->user_units = hashmap_new(string_hash_func, string_compare_func);
70         m->session_units = hashmap_new(string_hash_func, string_compare_func);
71
72         m->busnames = set_new(string_hash_func, string_compare_func);
73
74         if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
75             !m->user_units || !m->session_units ||
76             !m->busnames) {
77                 manager_free(m);
78                 return NULL;
79         }
80
81         m->kill_exclude_users = strv_new("root", NULL);
82         if (!m->kill_exclude_users) {
83                 manager_free(m);
84                 return NULL;
85         }
86
87         m->udev = udev_new();
88         if (!m->udev) {
89                 manager_free(m);
90                 return NULL;
91         }
92
93         r = sd_event_new(&m->event);
94         if (r < 0) {
95                 manager_free(m);
96                 return NULL;
97         }
98
99         return m;
100 }
101
102 void manager_free(Manager *m) {
103         Session *session;
104         User *u;
105         Device *d;
106         Seat *s;
107         Inhibitor *i;
108         Button *b;
109
110         assert(m);
111
112         while ((session = hashmap_first(m->sessions)))
113                 session_free(session);
114
115         while ((u = hashmap_first(m->users)))
116                 user_free(u);
117
118         while ((d = hashmap_first(m->devices)))
119                 device_free(d);
120
121         while ((s = hashmap_first(m->seats)))
122                 seat_free(s);
123
124         while ((i = hashmap_first(m->inhibitors)))
125                 inhibitor_free(i);
126
127         while ((b = hashmap_first(m->buttons)))
128                 button_free(b);
129
130         hashmap_free(m->devices);
131         hashmap_free(m->seats);
132         hashmap_free(m->sessions);
133         hashmap_free(m->users);
134         hashmap_free(m->inhibitors);
135         hashmap_free(m->buttons);
136
137         hashmap_free(m->user_units);
138         hashmap_free(m->session_units);
139
140         set_free_free(m->busnames);
141
142         sd_event_source_unref(m->idle_action_event_source);
143
144         sd_event_source_unref(m->console_active_event_source);
145         sd_event_source_unref(m->udev_seat_event_source);
146         sd_event_source_unref(m->udev_device_event_source);
147         sd_event_source_unref(m->udev_vcsa_event_source);
148         sd_event_source_unref(m->udev_button_event_source);
149
150         if (m->console_active_fd >= 0)
151                 close_nointr_nofail(m->console_active_fd);
152
153         if (m->udev_seat_monitor)
154                 udev_monitor_unref(m->udev_seat_monitor);
155         if (m->udev_device_monitor)
156                 udev_monitor_unref(m->udev_device_monitor);
157         if (m->udev_vcsa_monitor)
158                 udev_monitor_unref(m->udev_vcsa_monitor);
159         if (m->udev_button_monitor)
160                 udev_monitor_unref(m->udev_button_monitor);
161
162         if (m->udev)
163                 udev_unref(m->udev);
164
165         bus_verify_polkit_async_registry_free(m->bus, m->polkit_registry);
166
167         sd_bus_unref(m->bus);
168         sd_event_unref(m->event);
169
170         if (m->reserve_vt_fd >= 0)
171                 close_nointr_nofail(m->reserve_vt_fd);
172
173         strv_free(m->kill_only_users);
174         strv_free(m->kill_exclude_users);
175
176         free(m->action_job);
177         free(m);
178 }
179
180 int manager_enumerate_devices(Manager *m) {
181         struct udev_list_entry *item = NULL, *first = NULL;
182         struct udev_enumerate *e;
183         int r;
184
185         assert(m);
186
187         /* Loads devices from udev and creates seats for them as
188          * necessary */
189
190         e = udev_enumerate_new(m->udev);
191         if (!e) {
192                 r = -ENOMEM;
193                 goto finish;
194         }
195
196         r = udev_enumerate_add_match_tag(e, "master-of-seat");
197         if (r < 0)
198                 goto finish;
199
200         r = udev_enumerate_scan_devices(e);
201         if (r < 0)
202                 goto finish;
203
204         first = udev_enumerate_get_list_entry(e);
205         udev_list_entry_foreach(item, first) {
206                 struct udev_device *d;
207                 int k;
208
209                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
210                 if (!d) {
211                         r = -ENOMEM;
212                         goto finish;
213                 }
214
215                 k = manager_process_seat_device(m, d);
216                 udev_device_unref(d);
217
218                 if (k < 0)
219                         r = k;
220         }
221
222 finish:
223         if (e)
224                 udev_enumerate_unref(e);
225
226         return r;
227 }
228
229 int manager_enumerate_buttons(Manager *m) {
230         struct udev_list_entry *item = NULL, *first = NULL;
231         struct udev_enumerate *e;
232         int r;
233
234         assert(m);
235
236         /* Loads buttons from udev */
237
238         if (m->handle_power_key == HANDLE_IGNORE &&
239             m->handle_suspend_key == HANDLE_IGNORE &&
240             m->handle_hibernate_key == HANDLE_IGNORE &&
241             m->handle_lid_switch == HANDLE_IGNORE)
242                 return 0;
243
244         e = udev_enumerate_new(m->udev);
245         if (!e) {
246                 r = -ENOMEM;
247                 goto finish;
248         }
249
250         r = udev_enumerate_add_match_subsystem(e, "input");
251         if (r < 0)
252                 goto finish;
253
254         r = udev_enumerate_add_match_tag(e, "power-switch");
255         if (r < 0)
256                 goto finish;
257
258         r = udev_enumerate_scan_devices(e);
259         if (r < 0)
260                 goto finish;
261
262         first = udev_enumerate_get_list_entry(e);
263         udev_list_entry_foreach(item, first) {
264                 struct udev_device *d;
265                 int k;
266
267                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
268                 if (!d) {
269                         r = -ENOMEM;
270                         goto finish;
271                 }
272
273                 k = manager_process_button_device(m, d);
274                 udev_device_unref(d);
275
276                 if (k < 0)
277                         r = k;
278         }
279
280 finish:
281         if (e)
282                 udev_enumerate_unref(e);
283
284         return r;
285 }
286
287 int manager_enumerate_seats(Manager *m) {
288         _cleanup_closedir_ DIR *d = NULL;
289         struct dirent *de;
290         int r = 0;
291
292         assert(m);
293
294         /* This loads data about seats stored on disk, but does not
295          * actually create any seats. Removes data of seats that no
296          * longer exist. */
297
298         d = opendir("/run/systemd/seats");
299         if (!d) {
300                 if (errno == ENOENT)
301                         return 0;
302
303                 log_error("Failed to open /run/systemd/seats: %m");
304                 return -errno;
305         }
306
307         FOREACH_DIRENT(de, d, return -errno) {
308                 Seat *s;
309                 int k;
310
311                 if (!dirent_is_file(de))
312                         continue;
313
314                 s = hashmap_get(m->seats, de->d_name);
315                 if (!s) {
316                         unlinkat(dirfd(d), de->d_name, 0);
317                         continue;
318                 }
319
320                 k = seat_load(s);
321                 if (k < 0)
322                         r = k;
323         }
324
325         return r;
326 }
327
328 static int manager_enumerate_linger_users(Manager *m) {
329         _cleanup_closedir_ DIR *d = NULL;
330         struct dirent *de;
331         int r = 0;
332
333         assert(m);
334
335         d = opendir("/var/lib/systemd/linger");
336         if (!d) {
337                 if (errno == ENOENT)
338                         return 0;
339
340                 log_error("Failed to open /var/lib/systemd/linger/: %m");
341                 return -errno;
342         }
343
344         FOREACH_DIRENT(de, d, return -errno) {
345                 int k;
346
347                 if (!dirent_is_file(de))
348                         continue;
349
350                 k = manager_add_user_by_name(m, de->d_name, NULL);
351                 if (k < 0) {
352                         log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
353                         r = k;
354                 }
355         }
356
357         return r;
358 }
359
360 int manager_enumerate_users(Manager *m) {
361         _cleanup_closedir_ DIR *d = NULL;
362         struct dirent *de;
363         int r, k;
364
365         assert(m);
366
367         /* Add lingering users */
368         r = manager_enumerate_linger_users(m);
369
370         /* Read in user data stored on disk */
371         d = opendir("/run/systemd/users");
372         if (!d) {
373                 if (errno == ENOENT)
374                         return 0;
375
376                 log_error("Failed to open /run/systemd/users: %m");
377                 return -errno;
378         }
379
380         FOREACH_DIRENT(de, d, return -errno) {
381                 User *u;
382
383                 if (!dirent_is_file(de))
384                         continue;
385
386                 k = manager_add_user_by_name(m, de->d_name, &u);
387                 if (k < 0) {
388                         log_error("Failed to add user by file name %s: %s", de->d_name, strerror(-k));
389
390                         r = k;
391                         continue;
392                 }
393
394                 user_add_to_gc_queue(u);
395
396                 k = user_load(u);
397                 if (k < 0)
398                         r = k;
399         }
400
401         return r;
402 }
403
404 int manager_enumerate_sessions(Manager *m) {
405         _cleanup_closedir_ DIR *d = NULL;
406         struct dirent *de;
407         int r = 0;
408
409         assert(m);
410
411         /* Read in session data stored on disk */
412         d = opendir("/run/systemd/sessions");
413         if (!d) {
414                 if (errno == ENOENT)
415                         return 0;
416
417                 log_error("Failed to open /run/systemd/sessions: %m");
418                 return -errno;
419         }
420
421         FOREACH_DIRENT(de, d, return -errno) {
422                 struct Session *s;
423                 int k;
424
425                 if (!dirent_is_file(de))
426                         continue;
427
428                 if (!session_id_valid(de->d_name)) {
429                         log_warning("Invalid session file name '%s', ignoring.", de->d_name);
430                         r = -EINVAL;
431                         continue;
432                 }
433
434                 k = manager_add_session(m, de->d_name, &s);
435                 if (k < 0) {
436                         log_error("Failed to add session by file name %s: %s", de->d_name, strerror(-k));
437
438                         r = k;
439                         continue;
440                 }
441
442                 session_add_to_gc_queue(s);
443
444                 k = session_load(s);
445                 if (k < 0)
446                         r = k;
447         }
448
449         return r;
450 }
451
452 int manager_enumerate_inhibitors(Manager *m) {
453         _cleanup_closedir_ DIR *d = NULL;
454         struct dirent *de;
455         int r = 0;
456
457         assert(m);
458
459         d = opendir("/run/systemd/inhibit");
460         if (!d) {
461                 if (errno == ENOENT)
462                         return 0;
463
464                 log_error("Failed to open /run/systemd/inhibit: %m");
465                 return -errno;
466         }
467
468         FOREACH_DIRENT(de, d, return -errno) {
469                 int k;
470                 Inhibitor *i;
471
472                 if (!dirent_is_file(de))
473                         continue;
474
475                 k = manager_add_inhibitor(m, de->d_name, &i);
476                 if (k < 0) {
477                         log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
478                         r = k;
479                         continue;
480                 }
481
482                 k = inhibitor_load(i);
483                 if (k < 0)
484                         r = k;
485         }
486
487         return r;
488 }
489
490 static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
491         Manager *m = userdata;
492         struct udev_device *d;
493         int r;
494
495         assert(m);
496
497         d = udev_monitor_receive_device(m->udev_seat_monitor);
498         if (!d)
499                 return -ENOMEM;
500
501         r = manager_process_seat_device(m, d);
502         udev_device_unref(d);
503
504         return r;
505 }
506
507 static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
508         Manager *m = userdata;
509         struct udev_device *d;
510         int r;
511
512         assert(m);
513
514         d = udev_monitor_receive_device(m->udev_device_monitor);
515         if (!d)
516                 return -ENOMEM;
517
518         r = manager_process_seat_device(m, d);
519         udev_device_unref(d);
520
521         return r;
522 }
523
524 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
525         Manager *m = userdata;
526         struct udev_device *d;
527         int r = 0;
528         const char *name;
529
530         assert(m);
531
532         d = udev_monitor_receive_device(m->udev_vcsa_monitor);
533         if (!d)
534                 return -ENOMEM;
535
536         name = udev_device_get_sysname(d);
537
538         /* Whenever a VCSA device is removed try to reallocate our
539          * VTs, to make sure our auto VTs never go away. */
540
541         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
542                 r = seat_preallocate_vts(m->seat0);
543
544         udev_device_unref(d);
545
546         return r;
547 }
548
549 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
550         Manager *m = userdata;
551         struct udev_device *d;
552         int r;
553
554         assert(m);
555
556         d = udev_monitor_receive_device(m->udev_button_monitor);
557         if (!d)
558                 return -ENOMEM;
559
560         r = manager_process_button_device(m, d);
561         udev_device_unref(d);
562
563         return r;
564 }
565
566 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
567         Manager *m = userdata;
568
569         assert(m);
570         assert(m->seat0);
571         assert(m->console_active_fd == fd);
572
573         seat_read_active_vt(m->seat0);
574
575         return 0;
576 }
577
578 static int manager_reserve_vt(Manager *m) {
579         _cleanup_free_ char *p = NULL;
580
581         assert(m);
582
583         if (m->reserve_vt <= 0)
584                 return 0;
585
586         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
587                 return log_oom();
588
589         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
590         if (m->reserve_vt_fd < 0) {
591
592                 /* Don't complain on VT-less systems */
593                 if (errno != ENOENT)
594                         log_warning("Failed to pin reserved VT: %m");
595                 return -errno;
596         }
597
598         return 0;
599 }
600
601 static int manager_connect_bus(Manager *m) {
602         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
603         int r;
604
605         assert(m);
606         assert(!m->bus);
607
608         r = sd_bus_open_system(&m->bus);
609         if (r < 0) {
610                 log_error("Failed to connect to system bus: %s", strerror(-r));
611                 return r;
612         }
613
614         r = sd_bus_add_object_vtable(m->bus, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
615         if (r < 0) {
616                 log_error("Failed to add manager object vtable: %s", strerror(-r));
617                 return r;
618         }
619
620         r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
621         if (r < 0) {
622                 log_error("Failed to add seat object vtable: %s", strerror(-r));
623                 return r;
624         }
625
626         r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
627         if (r < 0) {
628                 log_error("Failed to add seat enumerator: %s", strerror(-r));
629                 return r;
630         }
631
632         r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
633         if (r < 0) {
634                 log_error("Failed to add session object vtable: %s", strerror(-r));
635                 return r;
636         }
637
638         r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/session", session_node_enumerator, m);
639         if (r < 0) {
640                 log_error("Failed to add session enumerator: %s", strerror(-r));
641                 return r;
642         }
643
644         r = sd_bus_add_fallback_vtable(m->bus, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
645         if (r < 0) {
646                 log_error("Failed to add user object vtable: %s", strerror(-r));
647                 return r;
648         }
649
650         r = sd_bus_add_node_enumerator(m->bus, "/org/freedesktop/login1/user", user_node_enumerator, m);
651         if (r < 0) {
652                 log_error("Failed to add user enumerator: %s", strerror(-r));
653                 return r;
654         }
655
656         r = sd_bus_add_match(m->bus,
657                              "type='signal',"
658                              "sender='org.freedesktop.DBus',"
659                              "interface='org.freedesktop.DBus',"
660                              "member='NameOwnerChanged',"
661                              "path='/org/freedesktop/DBus'",
662                              match_name_owner_changed, m);
663         if (r < 0) {
664                 log_error("Failed to add match for NameOwnerChanged: %s", strerror(-r));
665                 return r;
666         }
667
668         r = sd_bus_add_match(m->bus,
669                              "type='signal',"
670                              "sender='org.freedesktop.systemd1',"
671                              "interface='org.freedesktop.systemd1.Manager',"
672                              "member='JobRemoved',"
673                              "path='/org/freedesktop/systemd1'",
674                              match_job_removed, m);
675         if (r < 0) {
676                 log_error("Failed to add match for JobRemoved: %s", strerror(-r));
677                 return r;
678         }
679
680         r = sd_bus_add_match(m->bus,
681                              "type='signal',"
682                              "sender='org.freedesktop.systemd1',"
683                              "interface='org.freedesktop.systemd1.Manager',"
684                              "member='UnitRemoved',"
685                              "path='/org/freedesktop/systemd1'",
686                              match_unit_removed, m);
687         if (r < 0) {
688                 log_error("Failed to add match for UnitRemoved: %s", strerror(-r));
689                 return r;
690         }
691
692         r = sd_bus_add_match(m->bus,
693                              "type='signal',"
694                              "sender='org.freedesktop.systemd1',"
695                              "interface='org.freedesktop.DBus.Properties',"
696                              "member='PropertiesChanged'",
697                              match_properties_changed, m);
698         if (r < 0) {
699                 log_error("Failed to add match for PropertiesChanged: %s", strerror(-r));
700                 return r;
701         }
702
703         r = sd_bus_add_match(m->bus,
704                              "type='signal',"
705                              "sender='org.freedesktop.systemd1',"
706                              "interface='org.freedesktop.systemd1.Manager',"
707                              "member='Reloading',"
708                              "path='/org/freedesktop/systemd1'",
709                              match_reloading, m);
710         if (r < 0) {
711                 log_error("Failed to add match for Reloading: %s", strerror(-r));
712                 return r;
713         }
714
715         r = sd_bus_call_method(
716                         m->bus,
717                         "org.freedesktop.systemd1",
718                         "/org/freedesktop/systemd1",
719                         "org.freedesktop.systemd1.Manager",
720                         "Subscribe",
721                         &error,
722                         NULL, NULL);
723         if (r < 0) {
724                 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
725                 return r;
726         }
727
728         r = sd_bus_request_name(m->bus, "org.freedesktop.login1", SD_BUS_NAME_DO_NOT_QUEUE);
729         if (r < 0) {
730                 log_error("Failed to register name: %s", strerror(-r));
731                 return r;
732         }
733
734         if (r != SD_BUS_NAME_PRIMARY_OWNER)  {
735                 log_error("Failed to acquire name.");
736                 return -EEXIST;
737         }
738
739         r = sd_bus_attach_event(m->bus, m->event, 0);
740         if (r < 0) {
741                 log_error("Failed to attach bus to event loop: %s", strerror(-r));
742                 return r;
743         }
744
745         return 0;
746 }
747
748 static int manager_connect_console(Manager *m) {
749         int r;
750
751         assert(m);
752         assert(m->console_active_fd < 0);
753
754         /* On certain architectures (S390 and Xen, and containers),
755            /dev/tty0 does not exist, so don't fail if we can't open
756            it. */
757         if (access("/dev/tty0", F_OK) < 0)
758                 return 0;
759
760         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
761         if (m->console_active_fd < 0) {
762
763                 /* On some systems the device node /dev/tty0 may exist
764                  * even though /sys/class/tty/tty0 does not. */
765                 if (errno == ENOENT)
766                         return 0;
767
768                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
769                 return -errno;
770         }
771
772         r = sd_event_add_io(m->event, m->console_active_fd, 0, manager_dispatch_console, m, &m->console_active_event_source);
773         if (r < 0) {
774                 log_error("Failed to watch foreground console");
775                 return r;
776         }
777
778         return 0;
779 }
780
781 static int manager_connect_udev(Manager *m) {
782         int r;
783
784         assert(m);
785         assert(!m->udev_seat_monitor);
786         assert(!m->udev_device_monitor);
787         assert(!m->udev_vcsa_monitor);
788         assert(!m->udev_button_monitor);
789
790         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
791         if (!m->udev_seat_monitor)
792                 return -ENOMEM;
793
794         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
795         if (r < 0)
796                 return r;
797
798         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
799         if (r < 0)
800                 return r;
801
802         r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_seat_monitor), EPOLLIN, manager_dispatch_seat_udev, m, &m->udev_seat_event_source);
803         if (r < 0)
804                 return r;
805
806         m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
807         if (!m->udev_device_monitor)
808                 return -ENOMEM;
809
810         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
811         if (r < 0)
812                 return r;
813
814         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
815         if (r < 0)
816                 return r;
817
818         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
819         if (r < 0)
820                 return r;
821
822         r = udev_monitor_enable_receiving(m->udev_device_monitor);
823         if (r < 0)
824                 return r;
825
826         r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_device_monitor), EPOLLIN, manager_dispatch_device_udev, m, &m->udev_device_event_source);
827         if (r < 0)
828                 return r;
829
830         /* Don't watch keys if nobody cares */
831         if (m->handle_power_key != HANDLE_IGNORE ||
832             m->handle_suspend_key != HANDLE_IGNORE ||
833             m->handle_hibernate_key != HANDLE_IGNORE ||
834             m->handle_lid_switch != HANDLE_IGNORE) {
835
836                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
837                 if (!m->udev_button_monitor)
838                         return -ENOMEM;
839
840                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
841                 if (r < 0)
842                         return r;
843
844                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
845                 if (r < 0)
846                         return r;
847
848                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
849                 if (r < 0)
850                         return r;
851
852                 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_button_monitor), EPOLLIN, manager_dispatch_button_udev, m, &m->udev_button_event_source);
853                 if (r < 0)
854                         return r;
855         }
856
857         /* Don't bother watching VCSA devices, if nobody cares */
858         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
859
860                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
861                 if (!m->udev_vcsa_monitor)
862                         return -ENOMEM;
863
864                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
865                 if (r < 0)
866                         return r;
867
868                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
869                 if (r < 0)
870                         return r;
871
872                 r = sd_event_add_io(m->event, udev_monitor_get_fd(m->udev_vcsa_monitor), EPOLLIN, manager_dispatch_vcsa_udev, m, &m->udev_vcsa_event_source);
873                 if (r < 0)
874                         return r;
875         }
876
877         return 0;
878 }
879
880 void manager_gc(Manager *m, bool drop_not_started) {
881         Seat *seat;
882         Session *session;
883         User *user;
884
885         assert(m);
886
887         while ((seat = m->seat_gc_queue)) {
888                 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
889                 seat->in_gc_queue = false;
890
891                 if (!seat_check_gc(seat, drop_not_started)) {
892                         seat_stop(seat);
893                         seat_free(seat);
894                 }
895         }
896
897         while ((session = m->session_gc_queue)) {
898                 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
899                 session->in_gc_queue = false;
900
901                 if (!session_check_gc(session, drop_not_started)) {
902                         session_stop(session);
903                         session_finalize(session);
904                         session_free(session);
905                 }
906         }
907
908         while ((user = m->user_gc_queue)) {
909                 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
910                 user->in_gc_queue = false;
911
912                 if (!user_check_gc(user, drop_not_started)) {
913                         user_stop(user);
914                         user_finalize(user);
915                         user_free(user);
916                 }
917         }
918 }
919
920 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
921         Manager *m = userdata;
922         struct dual_timestamp since;
923         usec_t n, elapse;
924         int r;
925
926         assert(m);
927
928         if (m->idle_action == HANDLE_IGNORE ||
929             m->idle_action_usec <= 0)
930                 return 0;
931
932         n = now(CLOCK_MONOTONIC);
933
934         r = manager_get_idle_hint(m, &since);
935         if (r <= 0)
936                 /* Not idle. Let's check if after a timeout it might be idle then. */
937                 elapse = n + m->idle_action_usec;
938         else {
939                 /* Idle! Let's see if it's time to do something, or if
940                  * we shall sleep for longer. */
941
942                 if (n >= since.monotonic + m->idle_action_usec &&
943                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
944                         log_info("System idle. Taking action.");
945
946                         manager_handle_action(m, 0, m->idle_action, false, false);
947                         m->idle_action_not_before_usec = n;
948                 }
949
950                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
951         }
952
953         if (!m->idle_action_event_source) {
954
955                 r = sd_event_add_monotonic(m->event, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m, &m->idle_action_event_source);
956                 if (r < 0) {
957                         log_error("Failed to add idle event source: %s", strerror(-r));
958                         return r;
959                 }
960
961                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_PRIORITY_IDLE+10);
962                 if (r < 0) {
963                         log_error("Failed to set idle event source priority: %s", strerror(-r));
964                         return r;
965                 }
966         } else {
967                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
968                 if (r < 0) {
969                         log_error("Failed to set idle event timer: %s", strerror(-r));
970                         return r;
971                 }
972
973                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
974                 if (r < 0) {
975                         log_error("Failed to enable idle event timer: %s", strerror(-r));
976                         return r;
977                 }
978         }
979
980         return 0;
981 }
982
983 int manager_startup(Manager *m) {
984         int r;
985         Seat *seat;
986         Session *session;
987         User *user;
988         Inhibitor *inhibitor;
989         Iterator i;
990
991         assert(m);
992
993         /* Connect to console */
994         r = manager_connect_console(m);
995         if (r < 0)
996                 return r;
997
998         /* Connect to udev */
999         r = manager_connect_udev(m);
1000         if (r < 0) {
1001                 log_error("Failed to create udev watchers: %s", strerror(-r));
1002                 return r;
1003         }
1004
1005         /* Connect to the bus */
1006         r = manager_connect_bus(m);
1007         if (r < 0)
1008                 return r;
1009
1010         /* Instantiate magic seat 0 */
1011         r = manager_add_seat(m, "seat0", &m->seat0);
1012         if (r < 0) {
1013                 log_error("Failed to add seat0: %s", strerror(-r));
1014                 return r;
1015         }
1016
1017         /* Deserialize state */
1018         r = manager_enumerate_devices(m);
1019         if (r < 0)
1020                 log_warning("Device enumeration failed: %s", strerror(-r));
1021
1022         r = manager_enumerate_seats(m);
1023         if (r < 0)
1024                 log_warning("Seat enumeration failed: %s", strerror(-r));
1025
1026         r = manager_enumerate_users(m);
1027         if (r < 0)
1028                 log_warning("User enumeration failed: %s", strerror(-r));
1029
1030         r = manager_enumerate_sessions(m);
1031         if (r < 0)
1032                 log_warning("Session enumeration failed: %s", strerror(-r));
1033
1034         r = manager_enumerate_inhibitors(m);
1035         if (r < 0)
1036                 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1037
1038         r = manager_enumerate_buttons(m);
1039         if (r < 0)
1040                 log_warning("Button enumeration failed: %s", strerror(-r));
1041
1042         /* Remove stale objects before we start them */
1043         manager_gc(m, false);
1044
1045         /* Reserve the special reserved VT */
1046         manager_reserve_vt(m);
1047
1048         /* And start everything */
1049         HASHMAP_FOREACH(seat, m->seats, i)
1050                 seat_start(seat);
1051
1052         HASHMAP_FOREACH(user, m->users, i)
1053                 user_start(user);
1054
1055         HASHMAP_FOREACH(session, m->sessions, i)
1056                 session_start(session);
1057
1058         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1059                 inhibitor_start(inhibitor);
1060
1061         manager_dispatch_idle_action(NULL, 0, m);
1062
1063         return 0;
1064 }
1065
1066 static int manager_recheck_buttons(Manager *m) {
1067         Iterator i;
1068         Button *b;
1069         int r = 0;
1070
1071         assert(m);
1072
1073         HASHMAP_FOREACH(b, m->buttons, i) {
1074                 int q;
1075
1076                 q = button_recheck(b);
1077                 if (q > 0)
1078                         return 1;
1079                 if (q < 0)
1080                         r = q;
1081         }
1082
1083         return r;
1084 }
1085
1086 int manager_run(Manager *m) {
1087         int r;
1088
1089         assert(m);
1090
1091         for (;;) {
1092                 usec_t us = (uint64_t) -1;
1093
1094                 r = sd_event_get_state(m->event);
1095                 if (r < 0)
1096                         return r;
1097                 if (r == SD_EVENT_FINISHED)
1098                         return 0;
1099
1100                 manager_gc(m, true);
1101
1102                 if (manager_dispatch_delayed(m) > 0)
1103                         continue;
1104
1105                 if (manager_recheck_buttons(m) > 0)
1106                         continue;
1107
1108                 if (m->action_what != 0 && !m->action_job) {
1109                         usec_t x, y;
1110
1111                         x = now(CLOCK_MONOTONIC);
1112                         y = m->action_timestamp + m->inhibit_delay_max;
1113
1114                         us = x >= y ? 0 : y - x;
1115                 }
1116
1117                 r = sd_event_run(m->event, us);
1118                 if (r < 0)
1119                         return r;
1120         }
1121
1122         return 0;
1123 }
1124
1125 static int manager_parse_config_file(Manager *m) {
1126         static const char fn[] = "/etc/systemd/logind.conf";
1127         _cleanup_fclose_ FILE *f = NULL;
1128         int r;
1129
1130         assert(m);
1131
1132         f = fopen(fn, "re");
1133         if (!f) {
1134                 if (errno == ENOENT)
1135                         return 0;
1136
1137                 log_warning("Failed to open configuration file %s: %m", fn);
1138                 return -errno;
1139         }
1140
1141         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1142                          (void*) logind_gperf_lookup, false, false, m);
1143         if (r < 0)
1144                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1145
1146         return r;
1147 }
1148
1149 int main(int argc, char *argv[]) {
1150         Manager *m = NULL;
1151         int r;
1152
1153         log_set_target(LOG_TARGET_AUTO);
1154         log_set_facility(LOG_AUTH);
1155         log_parse_environment();
1156         log_open();
1157
1158         umask(0022);
1159
1160         if (argc != 1) {
1161                 log_error("This program takes no arguments.");
1162                 r = -EINVAL;
1163                 goto finish;
1164         }
1165
1166         /* Always create the directories people can create inotify
1167          * watches in. Note that some applications might check for the
1168          * existence of /run/systemd/seats/ to determine whether
1169          * logind is available, so please always make sure this check
1170          * stays in. */
1171         mkdir_label("/run/systemd/seats", 0755);
1172         mkdir_label("/run/systemd/users", 0755);
1173         mkdir_label("/run/systemd/sessions", 0755);
1174
1175         m = manager_new();
1176         if (!m) {
1177                 r = log_oom();
1178                 goto finish;
1179         }
1180
1181         manager_parse_config_file(m);
1182
1183         r = manager_startup(m);
1184         if (r < 0) {
1185                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1186                 goto finish;
1187         }
1188
1189         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1190
1191         sd_notify(false,
1192                   "READY=1\n"
1193                   "STATUS=Processing requests...");
1194
1195         r = manager_run(m);
1196
1197         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1198
1199 finish:
1200         sd_notify(false,
1201                   "STATUS=Shutting down...");
1202
1203         if (m)
1204                 manager_free(m);
1205
1206         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1207 }