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