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