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