chiark / gitweb /
ea7c6e74b0e275f19a4f5850c2466bac04ab2b74
[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 "logind.h"
34 #include "udev-util.h"
35 #include "formats-util.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         m->reserve_vt_fd = -1;
47
48         m->n_autovts = 6;
49         m->reserve_vt = 6;
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->user_units = hashmap_new(&string_hash_ops);
74         m->session_units = hashmap_new(&string_hash_ops);
75
76         m->busnames = set_new(&string_hash_ops);
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         sd_event_source_unref(m->inhibit_timeout_source);
145
146         sd_event_source_unref(m->console_active_event_source);
147         sd_event_source_unref(m->udev_seat_event_source);
148         sd_event_source_unref(m->udev_device_event_source);
149         sd_event_source_unref(m->udev_vcsa_event_source);
150         sd_event_source_unref(m->udev_button_event_source);
151         sd_event_source_unref(m->lid_switch_ignore_event_source);
152
153         safe_close(m->console_active_fd);
154
155         if (m->udev_seat_monitor)
156                 udev_monitor_unref(m->udev_seat_monitor);
157         if (m->udev_device_monitor)
158                 udev_monitor_unref(m->udev_device_monitor);
159         if (m->udev_vcsa_monitor)
160                 udev_monitor_unref(m->udev_vcsa_monitor);
161         if (m->udev_button_monitor)
162                 udev_monitor_unref(m->udev_button_monitor);
163
164         if (m->udev)
165                 udev_unref(m->udev);
166
167         bus_verify_polkit_async_registry_free(m->polkit_registry);
168
169         sd_bus_unref(m->bus);
170         sd_event_unref(m->event);
171
172         safe_close(m->reserve_vt_fd);
173
174         strv_free(m->kill_only_users);
175         strv_free(m->kill_exclude_users);
176
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_reserve_vt(Manager *m) {
556         _cleanup_free_ char *p = NULL;
557
558         assert(m);
559
560         if (m->reserve_vt <= 0)
561                 return 0;
562
563         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
564                 return log_oom();
565
566         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
567         if (m->reserve_vt_fd < 0) {
568
569                 /* Don't complain on VT-less systems */
570                 if (errno != ENOENT)
571                         log_warning_errno(errno, "Failed to pin reserved VT: %m");
572                 return -errno;
573         }
574
575         return 0;
576 }
577
578 static int manager_connect_bus(Manager *m) {
579         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
580         int r;
581
582         assert(m);
583         assert(!m->bus);
584
585         r = sd_bus_default_system(&m->bus);
586         if (r < 0)
587                 return log_error_errno(r, "Failed to connect to system bus: %m");
588
589         r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
590         if (r < 0)
591                 return log_error_errno(r, "Failed to add manager object vtable: %m");
592
593         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
594         if (r < 0)
595                 return log_error_errno(r, "Failed to add seat object vtable: %m");
596
597         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
598         if (r < 0)
599                 return log_error_errno(r, "Failed to add seat enumerator: %m");
600
601         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
602         if (r < 0)
603                 return log_error_errno(r, "Failed to add session object vtable: %m");
604
605         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
606         if (r < 0)
607                 return log_error_errno(r, "Failed to add session enumerator: %m");
608
609         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
610         if (r < 0)
611                 return log_error_errno(r, "Failed to add user object vtable: %m");
612
613         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
614         if (r < 0)
615                 return log_error_errno(r, "Failed to add user enumerator: %m");
616
617         r = sd_bus_add_match(m->bus,
618                              NULL,
619                              "type='signal',"
620                              "sender='org.freedesktop.DBus',"
621                              "interface='org.freedesktop.DBus',"
622                              "member='NameOwnerChanged',"
623                              "path='/org/freedesktop/DBus'",
624                              match_name_owner_changed, m);
625         if (r < 0)
626                 return log_error_errno(r, "Failed to add match for NameOwnerChanged: %m");
627
628         r = sd_bus_add_match(m->bus,
629                              NULL,
630                              "type='signal',"
631                              "sender='org.freedesktop.systemd1',"
632                              "interface='org.freedesktop.systemd1.Manager',"
633                              "member='JobRemoved',"
634                              "path='/org/freedesktop/systemd1'",
635                              match_job_removed, m);
636         if (r < 0)
637                 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
638
639         r = sd_bus_add_match(m->bus,
640                              NULL,
641                              "type='signal',"
642                              "sender='org.freedesktop.systemd1',"
643                              "interface='org.freedesktop.systemd1.Manager',"
644                              "member='UnitRemoved',"
645                              "path='/org/freedesktop/systemd1'",
646                              match_unit_removed, m);
647         if (r < 0)
648                 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
649
650         r = sd_bus_add_match(m->bus,
651                              NULL,
652                              "type='signal',"
653                              "sender='org.freedesktop.systemd1',"
654                              "interface='org.freedesktop.DBus.Properties',"
655                              "member='PropertiesChanged'",
656                              match_properties_changed, m);
657         if (r < 0)
658                 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
659
660         r = sd_bus_add_match(m->bus,
661                              NULL,
662                              "type='signal',"
663                              "sender='org.freedesktop.systemd1',"
664                              "interface='org.freedesktop.systemd1.Manager',"
665                              "member='Reloading',"
666                              "path='/org/freedesktop/systemd1'",
667                              match_reloading, m);
668         if (r < 0)
669                 return log_error_errno(r, "Failed to add match for Reloading: %m");
670
671         r = sd_bus_call_method(
672                         m->bus,
673                         "org.freedesktop.systemd1",
674                         "/org/freedesktop/systemd1",
675                         "org.freedesktop.systemd1.Manager",
676                         "Subscribe",
677                         &error,
678                         NULL, NULL);
679         if (r < 0) {
680                 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
681                 return r;
682         }
683
684         r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
685         if (r < 0)
686                 return log_error_errno(r, "Failed to register name: %m");
687
688         r = sd_bus_attach_event(m->bus, m->event, 0);
689         if (r < 0)
690                 return log_error_errno(r, "Failed to attach bus to event loop: %m");
691
692         return 0;
693 }
694
695 static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
696         Manager *m = data;
697         Session *active, *iter;
698
699         /*
700          * We got a VT-switch signal and we have to acknowledge it immediately.
701          * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
702          * old user-space might run multiple sessions on a single VT, *sigh*.
703          * Therefore, we have to iterate all sessions and find one with a vtfd
704          * on the requested VT.
705          * As only VTs with active controllers have VT_PROCESS set, our current
706          * notion of the active VT might be wrong (for instance if the switch
707          * happens while we setup VT_PROCESS). Therefore, read the current VT
708          * first and then use s->active->vtnr as reference. Note that this is
709          * not racy, as no further VT-switch can happen as long as we're in
710          * synchronous VT_PROCESS mode.
711          */
712
713         assert(m->seat0);
714         seat_read_active_vt(m->seat0);
715
716         active = m->seat0->active;
717         if (!active || active->vtnr < 1) {
718                 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
719                 return 0;
720         }
721
722         if (active->vtfd >= 0) {
723                 session_leave_vt(active);
724         } else {
725                 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
726                         if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
727                                 session_leave_vt(iter);
728                                 break;
729                         }
730                 }
731         }
732
733         return 0;
734 }
735
736 static int manager_connect_console(Manager *m) {
737         int r;
738
739         assert(m);
740         assert(m->console_active_fd < 0);
741
742         /* On certain architectures (S390 and Xen, and containers),
743            /dev/tty0 does not exist, so don't fail if we can't open
744            it. */
745         if (access("/dev/tty0", F_OK) < 0)
746                 return 0;
747
748         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
749         if (m->console_active_fd < 0) {
750
751                 /* On some systems the device node /dev/tty0 may exist
752                  * even though /sys/class/tty/tty0 does not. */
753                 if (errno == ENOENT)
754                         return 0;
755
756                 log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
757                 return -errno;
758         }
759
760         r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
761         if (r < 0) {
762                 log_error("Failed to watch foreground console");
763                 return r;
764         }
765
766         /*
767          * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
768          * as VT-acquire signal. We ignore any acquire-events (yes, we still
769          * have to provide a valid signal-number for it!) and acknowledge all
770          * release events immediately.
771          */
772
773         if (SIGRTMIN + 1 > SIGRTMAX) {
774                 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
775                 return -EINVAL;
776         }
777
778         r = ignore_signals(SIGRTMIN + 1, -1);
779         if (r < 0)
780                 return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m");
781
782         r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
783         if (r < 0)
784                 return log_error_errno(r, "Cannot block SIGRTMIN: %m");
785
786         r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
787         if (r < 0)
788                 return r;
789
790         return 0;
791 }
792
793 static int manager_connect_udev(Manager *m) {
794         int r;
795
796         assert(m);
797         assert(!m->udev_seat_monitor);
798         assert(!m->udev_device_monitor);
799         assert(!m->udev_vcsa_monitor);
800         assert(!m->udev_button_monitor);
801
802         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
803         if (!m->udev_seat_monitor)
804                 return -ENOMEM;
805
806         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
807         if (r < 0)
808                 return r;
809
810         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
811         if (r < 0)
812                 return r;
813
814         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);
815         if (r < 0)
816                 return r;
817
818         m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
819         if (!m->udev_device_monitor)
820                 return -ENOMEM;
821
822         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
823         if (r < 0)
824                 return r;
825
826         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
827         if (r < 0)
828                 return r;
829
830         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
831         if (r < 0)
832                 return r;
833
834         r = udev_monitor_enable_receiving(m->udev_device_monitor);
835         if (r < 0)
836                 return r;
837
838         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);
839         if (r < 0)
840                 return r;
841
842         /* Don't watch keys if nobody cares */
843         if (m->handle_power_key != HANDLE_IGNORE ||
844             m->handle_suspend_key != HANDLE_IGNORE ||
845             m->handle_hibernate_key != HANDLE_IGNORE ||
846             m->handle_lid_switch != HANDLE_IGNORE ||
847             m->handle_lid_switch_docked != HANDLE_IGNORE) {
848
849                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
850                 if (!m->udev_button_monitor)
851                         return -ENOMEM;
852
853                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
854                 if (r < 0)
855                         return r;
856
857                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
858                 if (r < 0)
859                         return r;
860
861                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
862                 if (r < 0)
863                         return r;
864
865                 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);
866                 if (r < 0)
867                         return r;
868         }
869
870         /* Don't bother watching VCSA devices, if nobody cares */
871         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
872
873                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
874                 if (!m->udev_vcsa_monitor)
875                         return -ENOMEM;
876
877                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
878                 if (r < 0)
879                         return r;
880
881                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
882                 if (r < 0)
883                         return r;
884
885                 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);
886                 if (r < 0)
887                         return r;
888         }
889
890         return 0;
891 }
892
893 void manager_gc(Manager *m, bool drop_not_started) {
894         Seat *seat;
895         Session *session;
896         User *user;
897
898         assert(m);
899
900         while ((seat = m->seat_gc_queue)) {
901                 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
902                 seat->in_gc_queue = false;
903
904                 if (!seat_check_gc(seat, drop_not_started)) {
905                         seat_stop(seat, false);
906                         seat_free(seat);
907                 }
908         }
909
910         while ((session = m->session_gc_queue)) {
911                 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
912                 session->in_gc_queue = false;
913
914                 /* First, if we are not closing yet, initiate stopping */
915                 if (!session_check_gc(session, drop_not_started) &&
916                     session_get_state(session) != SESSION_CLOSING)
917                         session_stop(session, false);
918
919                 /* Normally, this should make the session busy again,
920                  * if it doesn't then let's get rid of it
921                  * immediately */
922                 if (!session_check_gc(session, drop_not_started)) {
923                         session_finalize(session);
924                         session_free(session);
925                 }
926         }
927
928         while ((user = m->user_gc_queue)) {
929                 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
930                 user->in_gc_queue = false;
931
932                 /* First step: queue stop jobs */
933                 if (!user_check_gc(user, drop_not_started))
934                         user_stop(user, false);
935
936                 /* Second step: finalize user */
937                 if (!user_check_gc(user, drop_not_started)) {
938                         user_finalize(user);
939                         user_free(user);
940                 }
941         }
942 }
943
944 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
945         Manager *m = userdata;
946         struct dual_timestamp since;
947         usec_t n, elapse;
948         int r;
949
950         assert(m);
951
952         if (m->idle_action == HANDLE_IGNORE ||
953             m->idle_action_usec <= 0)
954                 return 0;
955
956         n = now(CLOCK_MONOTONIC);
957
958         r = manager_get_idle_hint(m, &since);
959         if (r <= 0)
960                 /* Not idle. Let's check if after a timeout it might be idle then. */
961                 elapse = n + m->idle_action_usec;
962         else {
963                 /* Idle! Let's see if it's time to do something, or if
964                  * we shall sleep for longer. */
965
966                 if (n >= since.monotonic + m->idle_action_usec &&
967                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
968                         log_info("System idle. Taking action.");
969
970                         manager_handle_action(m, 0, m->idle_action, false, false);
971                         m->idle_action_not_before_usec = n;
972                 }
973
974                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
975         }
976
977         if (!m->idle_action_event_source) {
978
979                 r = sd_event_add_time(
980                                 m->event,
981                                 &m->idle_action_event_source,
982                                 CLOCK_MONOTONIC,
983                                 elapse, USEC_PER_SEC*30,
984                                 manager_dispatch_idle_action, m);
985                 if (r < 0)
986                         return log_error_errno(r, "Failed to add idle event source: %m");
987
988                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
989                 if (r < 0)
990                         return log_error_errno(r, "Failed to set idle event source priority: %m");
991         } else {
992                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
993                 if (r < 0)
994                         return log_error_errno(r, "Failed to set idle event timer: %m");
995
996                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
997                 if (r < 0)
998                         return log_error_errno(r, "Failed to enable idle event timer: %m");
999         }
1000
1001         return 0;
1002 }
1003
1004 int manager_startup(Manager *m) {
1005         int r;
1006         Seat *seat;
1007         Session *session;
1008         User *user;
1009         Button *button;
1010         Inhibitor *inhibitor;
1011         Iterator i;
1012
1013         assert(m);
1014
1015         /* Connect to console */
1016         r = manager_connect_console(m);
1017         if (r < 0)
1018                 return r;
1019
1020         /* Connect to udev */
1021         r = manager_connect_udev(m);
1022         if (r < 0)
1023                 return log_error_errno(r, "Failed to create udev watchers: %m");
1024
1025         /* Connect to the bus */
1026         r = manager_connect_bus(m);
1027         if (r < 0)
1028                 return r;
1029
1030         /* Instantiate magic seat 0 */
1031         r = manager_add_seat(m, "seat0", &m->seat0);
1032         if (r < 0)
1033                 return log_error_errno(r, "Failed to add seat0: %m");
1034
1035         r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
1036         if (r < 0)
1037                 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
1038
1039         /* Deserialize state */
1040         r = manager_enumerate_devices(m);
1041         if (r < 0)
1042                 log_warning_errno(r, "Device enumeration failed: %m");
1043
1044         r = manager_enumerate_seats(m);
1045         if (r < 0)
1046                 log_warning_errno(r, "Seat enumeration failed: %m");
1047
1048         r = manager_enumerate_users(m);
1049         if (r < 0)
1050                 log_warning_errno(r, "User enumeration failed: %m");
1051
1052         r = manager_enumerate_sessions(m);
1053         if (r < 0)
1054                 log_warning_errno(r, "Session enumeration failed: %m");
1055
1056         r = manager_enumerate_inhibitors(m);
1057         if (r < 0)
1058                 log_warning_errno(r, "Inhibitor enumeration failed: %m");
1059
1060         r = manager_enumerate_buttons(m);
1061         if (r < 0)
1062                 log_warning_errno(r, "Button enumeration failed: %m");
1063
1064         /* Remove stale objects before we start them */
1065         manager_gc(m, false);
1066
1067         /* Reserve the special reserved VT */
1068         manager_reserve_vt(m);
1069
1070         /* And start everything */
1071         HASHMAP_FOREACH(seat, m->seats, i)
1072                 seat_start(seat);
1073
1074         HASHMAP_FOREACH(user, m->users, i)
1075                 user_start(user);
1076
1077         HASHMAP_FOREACH(session, m->sessions, i)
1078                 session_start(session);
1079
1080         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1081                 inhibitor_start(inhibitor);
1082
1083         HASHMAP_FOREACH(button, m->buttons, i)
1084                 button_check_switches(button);
1085
1086         manager_dispatch_idle_action(NULL, 0, m);
1087
1088         return 0;
1089 }
1090
1091 int manager_run(Manager *m) {
1092         int r;
1093
1094         assert(m);
1095
1096         for (;;) {
1097                 r = sd_event_get_state(m->event);
1098                 if (r < 0)
1099                         return r;
1100                 if (r == SD_EVENT_FINISHED)
1101                         return 0;
1102
1103                 manager_gc(m, true);
1104
1105                 r = sd_event_run(m->event, (uint64_t) -1);
1106                 if (r < 0)
1107                         return r;
1108         }
1109 }
1110
1111 static int manager_parse_config_file(Manager *m) {
1112         assert(m);
1113
1114         return config_parse_many("/etc/systemd/logind.conf",
1115                                  CONF_DIRS_NULSTR("systemd/logind.conf"),
1116                                  "Login\0",
1117                                  config_item_perf_lookup, logind_gperf_lookup,
1118                                  false, m);
1119 }
1120
1121 int main(int argc, char *argv[]) {
1122         Manager *m = NULL;
1123         int r;
1124
1125         log_set_target(LOG_TARGET_AUTO);
1126         log_set_facility(LOG_AUTH);
1127         log_parse_environment();
1128         log_open();
1129
1130         umask(0022);
1131
1132         if (argc != 1) {
1133                 log_error("This program takes no arguments.");
1134                 r = -EINVAL;
1135                 goto finish;
1136         }
1137
1138         /* Always create the directories people can create inotify
1139          * watches in. Note that some applications might check for the
1140          * existence of /run/systemd/seats/ to determine whether
1141          * logind is available, so please always make sure this check
1142          * stays in. */
1143         mkdir_label("/run/systemd/seats", 0755);
1144         mkdir_label("/run/systemd/users", 0755);
1145         mkdir_label("/run/systemd/sessions", 0755);
1146
1147         m = manager_new();
1148         if (!m) {
1149                 r = log_oom();
1150                 goto finish;
1151         }
1152
1153         manager_parse_config_file(m);
1154
1155         r = manager_startup(m);
1156         if (r < 0) {
1157                 log_error_errno(r, "Failed to fully start up daemon: %m");
1158                 goto finish;
1159         }
1160
1161         log_debug("systemd-logind running as pid "PID_FMT, getpid());
1162
1163         sd_notify(false,
1164                   "READY=1\n"
1165                   "STATUS=Processing requests...");
1166
1167         r = manager_run(m);
1168
1169         log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
1170
1171 finish:
1172         sd_notify(false,
1173                   "STOPPING=1\n"
1174                   "STATUS=Shutting down...");
1175
1176         if (m)
1177                 manager_free(m);
1178
1179         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1180 }