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