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