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