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