chiark / gitweb /
bus: make sd_bus_request_name() and sd_bus_release_name() behave more like other...
[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_default(&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 static 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 static 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 static 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 static 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 static 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 static 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_default_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_REPLACE_EXISTING|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         r = sd_bus_attach_event(m->bus, m->event, 0);
735         if (r < 0) {
736                 log_error("Failed to attach bus to event loop: %s", strerror(-r));
737                 return r;
738         }
739
740         return 0;
741 }
742
743 static int manager_connect_console(Manager *m) {
744         int r;
745
746         assert(m);
747         assert(m->console_active_fd < 0);
748
749         /* On certain architectures (S390 and Xen, and containers),
750            /dev/tty0 does not exist, so don't fail if we can't open
751            it. */
752         if (access("/dev/tty0", F_OK) < 0)
753                 return 0;
754
755         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
756         if (m->console_active_fd < 0) {
757
758                 /* On some systems the device node /dev/tty0 may exist
759                  * even though /sys/class/tty/tty0 does not. */
760                 if (errno == ENOENT)
761                         return 0;
762
763                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
764                 return -errno;
765         }
766
767         r = sd_event_add_io(m->event, m->console_active_fd, 0, manager_dispatch_console, m, &m->console_active_event_source);
768         if (r < 0) {
769                 log_error("Failed to watch foreground console");
770                 return r;
771         }
772
773         return 0;
774 }
775
776 static int manager_connect_udev(Manager *m) {
777         int r;
778
779         assert(m);
780         assert(!m->udev_seat_monitor);
781         assert(!m->udev_device_monitor);
782         assert(!m->udev_vcsa_monitor);
783         assert(!m->udev_button_monitor);
784
785         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
786         if (!m->udev_seat_monitor)
787                 return -ENOMEM;
788
789         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
790         if (r < 0)
791                 return r;
792
793         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
794         if (r < 0)
795                 return r;
796
797         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);
798         if (r < 0)
799                 return r;
800
801         m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
802         if (!m->udev_device_monitor)
803                 return -ENOMEM;
804
805         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
806         if (r < 0)
807                 return r;
808
809         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
810         if (r < 0)
811                 return r;
812
813         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
814         if (r < 0)
815                 return r;
816
817         r = udev_monitor_enable_receiving(m->udev_device_monitor);
818         if (r < 0)
819                 return r;
820
821         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);
822         if (r < 0)
823                 return r;
824
825         /* Don't watch keys if nobody cares */
826         if (m->handle_power_key != HANDLE_IGNORE ||
827             m->handle_suspend_key != HANDLE_IGNORE ||
828             m->handle_hibernate_key != HANDLE_IGNORE ||
829             m->handle_lid_switch != HANDLE_IGNORE) {
830
831                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
832                 if (!m->udev_button_monitor)
833                         return -ENOMEM;
834
835                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
836                 if (r < 0)
837                         return r;
838
839                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
840                 if (r < 0)
841                         return r;
842
843                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
844                 if (r < 0)
845                         return r;
846
847                 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);
848                 if (r < 0)
849                         return r;
850         }
851
852         /* Don't bother watching VCSA devices, if nobody cares */
853         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
854
855                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
856                 if (!m->udev_vcsa_monitor)
857                         return -ENOMEM;
858
859                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
860                 if (r < 0)
861                         return r;
862
863                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
864                 if (r < 0)
865                         return r;
866
867                 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);
868                 if (r < 0)
869                         return r;
870         }
871
872         return 0;
873 }
874
875 void manager_gc(Manager *m, bool drop_not_started) {
876         Seat *seat;
877         Session *session;
878         User *user;
879
880         assert(m);
881
882         while ((seat = m->seat_gc_queue)) {
883                 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
884                 seat->in_gc_queue = false;
885
886                 if (!seat_check_gc(seat, drop_not_started)) {
887                         seat_stop(seat);
888                         seat_free(seat);
889                 }
890         }
891
892         while ((session = m->session_gc_queue)) {
893                 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
894                 session->in_gc_queue = false;
895
896                 if (!session_check_gc(session, drop_not_started)) {
897                         session_stop(session);
898                         session_finalize(session);
899                         session_free(session);
900                 }
901         }
902
903         while ((user = m->user_gc_queue)) {
904                 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
905                 user->in_gc_queue = false;
906
907                 if (!user_check_gc(user, drop_not_started)) {
908                         user_stop(user);
909                         user_finalize(user);
910                         user_free(user);
911                 }
912         }
913 }
914
915 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
916         Manager *m = userdata;
917         struct dual_timestamp since;
918         usec_t n, elapse;
919         int r;
920
921         assert(m);
922
923         if (m->idle_action == HANDLE_IGNORE ||
924             m->idle_action_usec <= 0)
925                 return 0;
926
927         n = now(CLOCK_MONOTONIC);
928
929         r = manager_get_idle_hint(m, &since);
930         if (r <= 0)
931                 /* Not idle. Let's check if after a timeout it might be idle then. */
932                 elapse = n + m->idle_action_usec;
933         else {
934                 /* Idle! Let's see if it's time to do something, or if
935                  * we shall sleep for longer. */
936
937                 if (n >= since.monotonic + m->idle_action_usec &&
938                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
939                         log_info("System idle. Taking action.");
940
941                         manager_handle_action(m, 0, m->idle_action, false, false);
942                         m->idle_action_not_before_usec = n;
943                 }
944
945                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
946         }
947
948         if (!m->idle_action_event_source) {
949
950                 r = sd_event_add_monotonic(m->event, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m, &m->idle_action_event_source);
951                 if (r < 0) {
952                         log_error("Failed to add idle event source: %s", strerror(-r));
953                         return r;
954                 }
955
956                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
957                 if (r < 0) {
958                         log_error("Failed to set idle event source priority: %s", strerror(-r));
959                         return r;
960                 }
961         } else {
962                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
963                 if (r < 0) {
964                         log_error("Failed to set idle event timer: %s", strerror(-r));
965                         return r;
966                 }
967
968                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
969                 if (r < 0) {
970                         log_error("Failed to enable idle event timer: %s", strerror(-r));
971                         return r;
972                 }
973         }
974
975         return 0;
976 }
977
978 int manager_startup(Manager *m) {
979         int r;
980         Seat *seat;
981         Session *session;
982         User *user;
983         Inhibitor *inhibitor;
984         Iterator i;
985
986         assert(m);
987
988         /* Connect to console */
989         r = manager_connect_console(m);
990         if (r < 0)
991                 return r;
992
993         /* Connect to udev */
994         r = manager_connect_udev(m);
995         if (r < 0) {
996                 log_error("Failed to create udev watchers: %s", strerror(-r));
997                 return r;
998         }
999
1000         /* Connect to the bus */
1001         r = manager_connect_bus(m);
1002         if (r < 0)
1003                 return r;
1004
1005         /* Instantiate magic seat 0 */
1006         r = manager_add_seat(m, "seat0", &m->seat0);
1007         if (r < 0) {
1008                 log_error("Failed to add seat0: %s", strerror(-r));
1009                 return r;
1010         }
1011
1012         /* Deserialize state */
1013         r = manager_enumerate_devices(m);
1014         if (r < 0)
1015                 log_warning("Device enumeration failed: %s", strerror(-r));
1016
1017         r = manager_enumerate_seats(m);
1018         if (r < 0)
1019                 log_warning("Seat enumeration failed: %s", strerror(-r));
1020
1021         r = manager_enumerate_users(m);
1022         if (r < 0)
1023                 log_warning("User enumeration failed: %s", strerror(-r));
1024
1025         r = manager_enumerate_sessions(m);
1026         if (r < 0)
1027                 log_warning("Session enumeration failed: %s", strerror(-r));
1028
1029         r = manager_enumerate_inhibitors(m);
1030         if (r < 0)
1031                 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1032
1033         r = manager_enumerate_buttons(m);
1034         if (r < 0)
1035                 log_warning("Button enumeration failed: %s", strerror(-r));
1036
1037         /* Remove stale objects before we start them */
1038         manager_gc(m, false);
1039
1040         /* Reserve the special reserved VT */
1041         manager_reserve_vt(m);
1042
1043         /* And start everything */
1044         HASHMAP_FOREACH(seat, m->seats, i)
1045                 seat_start(seat);
1046
1047         HASHMAP_FOREACH(user, m->users, i)
1048                 user_start(user);
1049
1050         HASHMAP_FOREACH(session, m->sessions, i)
1051                 session_start(session);
1052
1053         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1054                 inhibitor_start(inhibitor);
1055
1056         manager_dispatch_idle_action(NULL, 0, m);
1057
1058         return 0;
1059 }
1060
1061 static int manager_recheck_buttons(Manager *m) {
1062         Iterator i;
1063         Button *b;
1064         int r = 0;
1065
1066         assert(m);
1067
1068         HASHMAP_FOREACH(b, m->buttons, i) {
1069                 int q;
1070
1071                 q = button_recheck(b);
1072                 if (q > 0)
1073                         return 1;
1074                 if (q < 0)
1075                         r = q;
1076         }
1077
1078         return r;
1079 }
1080
1081 int manager_run(Manager *m) {
1082         int r;
1083
1084         assert(m);
1085
1086         for (;;) {
1087                 usec_t us = (uint64_t) -1;
1088
1089                 r = sd_event_get_state(m->event);
1090                 if (r < 0)
1091                         return r;
1092                 if (r == SD_EVENT_FINISHED)
1093                         return 0;
1094
1095                 manager_gc(m, true);
1096
1097                 if (manager_dispatch_delayed(m) > 0)
1098                         continue;
1099
1100                 if (manager_recheck_buttons(m) > 0)
1101                         continue;
1102
1103                 if (m->action_what != 0 && !m->action_job) {
1104                         usec_t x, y;
1105
1106                         x = now(CLOCK_MONOTONIC);
1107                         y = m->action_timestamp + m->inhibit_delay_max;
1108
1109                         us = x >= y ? 0 : y - x;
1110                 }
1111
1112                 r = sd_event_run(m->event, us);
1113                 if (r < 0)
1114                         return r;
1115         }
1116
1117         return 0;
1118 }
1119
1120 static int manager_parse_config_file(Manager *m) {
1121         static const char fn[] = "/etc/systemd/logind.conf";
1122         _cleanup_fclose_ FILE *f = NULL;
1123         int r;
1124
1125         assert(m);
1126
1127         f = fopen(fn, "re");
1128         if (!f) {
1129                 if (errno == ENOENT)
1130                         return 0;
1131
1132                 log_warning("Failed to open configuration file %s: %m", fn);
1133                 return -errno;
1134         }
1135
1136         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1137                          (void*) logind_gperf_lookup, false, false, m);
1138         if (r < 0)
1139                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1140
1141         return r;
1142 }
1143
1144 int main(int argc, char *argv[]) {
1145         Manager *m = NULL;
1146         int r;
1147
1148         log_set_target(LOG_TARGET_AUTO);
1149         log_set_facility(LOG_AUTH);
1150         log_parse_environment();
1151         log_open();
1152
1153         umask(0022);
1154
1155         if (argc != 1) {
1156                 log_error("This program takes no arguments.");
1157                 r = -EINVAL;
1158                 goto finish;
1159         }
1160
1161         /* Always create the directories people can create inotify
1162          * watches in. Note that some applications might check for the
1163          * existence of /run/systemd/seats/ to determine whether
1164          * logind is available, so please always make sure this check
1165          * stays in. */
1166         mkdir_label("/run/systemd/seats", 0755);
1167         mkdir_label("/run/systemd/users", 0755);
1168         mkdir_label("/run/systemd/sessions", 0755);
1169
1170         m = manager_new();
1171         if (!m) {
1172                 r = log_oom();
1173                 goto finish;
1174         }
1175
1176         manager_parse_config_file(m);
1177
1178         r = manager_startup(m);
1179         if (r < 0) {
1180                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1181                 goto finish;
1182         }
1183
1184         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1185
1186         sd_notify(false,
1187                   "READY=1\n"
1188                   "STATUS=Processing requests...");
1189
1190         r = manager_run(m);
1191
1192         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1193
1194 finish:
1195         sd_notify(false,
1196                   "STATUS=Shutting down...");
1197
1198         if (m)
1199                 manager_free(m);
1200
1201         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1202 }