chiark / gitweb /
554409926a120b0b6345c36b4861c874f159d83b
[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                 if (!user_check_gc(user, drop_not_started) &&
893                     user_get_state(user) != USER_CLOSING)
894                         user_stop(user, false);
895
896                 if (!user_check_gc(user, drop_not_started)) {
897                         user_finalize(user);
898                         user_free(user);
899                 }
900         }
901 }
902
903 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
904         Manager *m = userdata;
905         struct dual_timestamp since;
906         usec_t n, elapse;
907         int r;
908
909         assert(m);
910
911         if (m->idle_action == HANDLE_IGNORE ||
912             m->idle_action_usec <= 0)
913                 return 0;
914
915         n = now(CLOCK_MONOTONIC);
916
917         r = manager_get_idle_hint(m, &since);
918         if (r <= 0)
919                 /* Not idle. Let's check if after a timeout it might be idle then. */
920                 elapse = n + m->idle_action_usec;
921         else {
922                 /* Idle! Let's see if it's time to do something, or if
923                  * we shall sleep for longer. */
924
925                 if (n >= since.monotonic + m->idle_action_usec &&
926                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
927                         log_info("System idle. Taking action.");
928
929                         manager_handle_action(m, 0, m->idle_action, false, false);
930                         m->idle_action_not_before_usec = n;
931                 }
932
933                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
934         }
935
936         if (!m->idle_action_event_source) {
937
938                 r = sd_event_add_monotonic(m->event, elapse, USEC_PER_SEC*30, manager_dispatch_idle_action, m, &m->idle_action_event_source);
939                 if (r < 0) {
940                         log_error("Failed to add idle event source: %s", strerror(-r));
941                         return r;
942                 }
943
944                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
945                 if (r < 0) {
946                         log_error("Failed to set idle event source priority: %s", strerror(-r));
947                         return r;
948                 }
949         } else {
950                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
951                 if (r < 0) {
952                         log_error("Failed to set idle event timer: %s", strerror(-r));
953                         return r;
954                 }
955
956                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
957                 if (r < 0) {
958                         log_error("Failed to enable idle event timer: %s", strerror(-r));
959                         return r;
960                 }
961         }
962
963         return 0;
964 }
965
966 int manager_startup(Manager *m) {
967         int r;
968         Seat *seat;
969         Session *session;
970         User *user;
971         Inhibitor *inhibitor;
972         Iterator i;
973
974         assert(m);
975
976         /* Connect to console */
977         r = manager_connect_console(m);
978         if (r < 0)
979                 return r;
980
981         /* Connect to udev */
982         r = manager_connect_udev(m);
983         if (r < 0) {
984                 log_error("Failed to create udev watchers: %s", strerror(-r));
985                 return r;
986         }
987
988         /* Connect to the bus */
989         r = manager_connect_bus(m);
990         if (r < 0)
991                 return r;
992
993         /* Instantiate magic seat 0 */
994         r = manager_add_seat(m, "seat0", &m->seat0);
995         if (r < 0) {
996                 log_error("Failed to add seat0: %s", strerror(-r));
997                 return r;
998         }
999
1000         /* Deserialize state */
1001         r = manager_enumerate_devices(m);
1002         if (r < 0)
1003                 log_warning("Device enumeration failed: %s", strerror(-r));
1004
1005         r = manager_enumerate_seats(m);
1006         if (r < 0)
1007                 log_warning("Seat enumeration failed: %s", strerror(-r));
1008
1009         r = manager_enumerate_users(m);
1010         if (r < 0)
1011                 log_warning("User enumeration failed: %s", strerror(-r));
1012
1013         r = manager_enumerate_sessions(m);
1014         if (r < 0)
1015                 log_warning("Session enumeration failed: %s", strerror(-r));
1016
1017         r = manager_enumerate_inhibitors(m);
1018         if (r < 0)
1019                 log_warning("Inhibitor enumeration failed: %s", strerror(-r));
1020
1021         r = manager_enumerate_buttons(m);
1022         if (r < 0)
1023                 log_warning("Button enumeration failed: %s", strerror(-r));
1024
1025         /* Remove stale objects before we start them */
1026         manager_gc(m, false);
1027
1028         /* Reserve the special reserved VT */
1029         manager_reserve_vt(m);
1030
1031         /* And start everything */
1032         HASHMAP_FOREACH(seat, m->seats, i)
1033                 seat_start(seat);
1034
1035         HASHMAP_FOREACH(user, m->users, i)
1036                 user_start(user);
1037
1038         HASHMAP_FOREACH(session, m->sessions, i)
1039                 session_start(session);
1040
1041         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1042                 inhibitor_start(inhibitor);
1043
1044         manager_dispatch_idle_action(NULL, 0, m);
1045
1046         return 0;
1047 }
1048
1049 static int manager_recheck_buttons(Manager *m) {
1050         Iterator i;
1051         Button *b;
1052         int r = 0;
1053
1054         assert(m);
1055
1056         HASHMAP_FOREACH(b, m->buttons, i) {
1057                 int q;
1058
1059                 q = button_recheck(b);
1060                 if (q > 0)
1061                         return 1;
1062                 if (q < 0)
1063                         r = q;
1064         }
1065
1066         return r;
1067 }
1068
1069 int manager_run(Manager *m) {
1070         int r;
1071
1072         assert(m);
1073
1074         for (;;) {
1075                 usec_t us = (uint64_t) -1;
1076
1077                 r = sd_event_get_state(m->event);
1078                 if (r < 0)
1079                         return r;
1080                 if (r == SD_EVENT_FINISHED)
1081                         return 0;
1082
1083                 manager_gc(m, true);
1084
1085                 if (manager_dispatch_delayed(m) > 0)
1086                         continue;
1087
1088                 if (manager_recheck_buttons(m) > 0)
1089                         continue;
1090
1091                 if (m->action_what != 0 && !m->action_job) {
1092                         usec_t x, y;
1093
1094                         x = now(CLOCK_MONOTONIC);
1095                         y = m->action_timestamp + m->inhibit_delay_max;
1096
1097                         us = x >= y ? 0 : y - x;
1098                 }
1099
1100                 r = sd_event_run(m->event, us);
1101                 if (r < 0)
1102                         return r;
1103         }
1104
1105         return 0;
1106 }
1107
1108 static int manager_parse_config_file(Manager *m) {
1109         static const char fn[] = "/etc/systemd/logind.conf";
1110         _cleanup_fclose_ FILE *f = NULL;
1111         int r;
1112
1113         assert(m);
1114
1115         f = fopen(fn, "re");
1116         if (!f) {
1117                 if (errno == ENOENT)
1118                         return 0;
1119
1120                 log_warning("Failed to open configuration file %s: %m", fn);
1121                 return -errno;
1122         }
1123
1124         r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup,
1125                          (void*) logind_gperf_lookup, false, false, m);
1126         if (r < 0)
1127                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1128
1129         return r;
1130 }
1131
1132 int main(int argc, char *argv[]) {
1133         Manager *m = NULL;
1134         int r;
1135
1136         log_set_target(LOG_TARGET_AUTO);
1137         log_set_facility(LOG_AUTH);
1138         log_parse_environment();
1139         log_open();
1140
1141         umask(0022);
1142
1143         if (argc != 1) {
1144                 log_error("This program takes no arguments.");
1145                 r = -EINVAL;
1146                 goto finish;
1147         }
1148
1149         /* Always create the directories people can create inotify
1150          * watches in. Note that some applications might check for the
1151          * existence of /run/systemd/seats/ to determine whether
1152          * logind is available, so please always make sure this check
1153          * stays in. */
1154         mkdir_label("/run/systemd/seats", 0755);
1155         mkdir_label("/run/systemd/users", 0755);
1156         mkdir_label("/run/systemd/sessions", 0755);
1157
1158         m = manager_new();
1159         if (!m) {
1160                 r = log_oom();
1161                 goto finish;
1162         }
1163
1164         manager_parse_config_file(m);
1165
1166         r = manager_startup(m);
1167         if (r < 0) {
1168                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1169                 goto finish;
1170         }
1171
1172         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1173
1174         sd_notify(false,
1175                   "READY=1\n"
1176                   "STATUS=Processing requests...");
1177
1178         r = manager_run(m);
1179
1180         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1181
1182 finish:
1183         sd_notify(false,
1184                   "STATUS=Shutting down...");
1185
1186         if (m)
1187                 manager_free(m);
1188
1189         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1190 }