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