chiark / gitweb /
Remove src/fstab-generator
[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
36 Manager *manager_new(void) {
37         Manager *m;
38         int r;
39
40         m = new0(Manager, 1);
41         if (!m)
42                 return NULL;
43
44         m->console_active_fd = -1;
45         m->reserve_vt_fd = -1;
46
47         m->n_autovts = 6;
48         m->reserve_vt = 6;
49         m->remove_ipc = true;
50         m->inhibit_delay_max = 5 * USEC_PER_SEC;
51         m->handle_power_key = HANDLE_POWEROFF;
52         m->handle_suspend_key = HANDLE_SUSPEND;
53         m->handle_hibernate_key = HANDLE_HIBERNATE;
54         m->handle_lid_switch = HANDLE_SUSPEND;
55         m->handle_lid_switch_docked = HANDLE_IGNORE;
56         m->lid_switch_ignore_inhibited = true;
57         m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
58
59         m->idle_action_usec = 30 * USEC_PER_MINUTE;
60         m->idle_action = HANDLE_IGNORE;
61         m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
62
63         m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
64
65         m->devices = hashmap_new(&string_hash_ops);
66         m->seats = hashmap_new(&string_hash_ops);
67         m->sessions = hashmap_new(&string_hash_ops);
68         m->users = hashmap_new(NULL);
69         m->inhibitors = hashmap_new(&string_hash_ops);
70         m->buttons = hashmap_new(&string_hash_ops);
71
72         m->user_units = hashmap_new(&string_hash_ops);
73         m->session_units = hashmap_new(&string_hash_ops);
74
75         m->busnames = set_new(&string_hash_ops);
76
77         if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->busnames ||
78             !m->user_units || !m->session_units)
79                 goto fail;
80
81         m->kill_exclude_users = strv_new("root", NULL);
82         if (!m->kill_exclude_users)
83                 goto fail;
84
85         m->udev = udev_new();
86         if (!m->udev)
87                 goto fail;
88
89         r = sd_event_default(&m->event);
90         if (r < 0)
91                 goto fail;
92
93         sd_event_set_watchdog(m->event, true);
94
95         return m;
96
97 fail:
98         manager_free(m);
99         return NULL;
100 }
101
102 void manager_free(Manager *m) {
103         Session *session;
104         User *u;
105         Device *d;
106         Seat *s;
107         Inhibitor *i;
108         Button *b;
109
110         assert(m);
111
112         while ((session = hashmap_first(m->sessions)))
113                 session_free(session);
114
115         while ((u = hashmap_first(m->users)))
116                 user_free(u);
117
118         while ((d = hashmap_first(m->devices)))
119                 device_free(d);
120
121         while ((s = hashmap_first(m->seats)))
122                 seat_free(s);
123
124         while ((i = hashmap_first(m->inhibitors)))
125                 inhibitor_free(i);
126
127         while ((b = hashmap_first(m->buttons)))
128                 button_free(b);
129
130         hashmap_free(m->devices);
131         hashmap_free(m->seats);
132         hashmap_free(m->sessions);
133         hashmap_free(m->users);
134         hashmap_free(m->inhibitors);
135         hashmap_free(m->buttons);
136
137         hashmap_free(m->user_units);
138         hashmap_free(m->session_units);
139
140         set_free_free(m->busnames);
141
142         sd_event_source_unref(m->idle_action_event_source);
143
144         sd_event_source_unref(m->console_active_event_source);
145         sd_event_source_unref(m->udev_seat_event_source);
146         sd_event_source_unref(m->udev_device_event_source);
147         sd_event_source_unref(m->udev_vcsa_event_source);
148         sd_event_source_unref(m->udev_button_event_source);
149         sd_event_source_unref(m->lid_switch_ignore_event_source);
150
151         safe_close(m->console_active_fd);
152
153         if (m->udev_seat_monitor)
154                 udev_monitor_unref(m->udev_seat_monitor);
155         if (m->udev_device_monitor)
156                 udev_monitor_unref(m->udev_device_monitor);
157         if (m->udev_vcsa_monitor)
158                 udev_monitor_unref(m->udev_vcsa_monitor);
159         if (m->udev_button_monitor)
160                 udev_monitor_unref(m->udev_button_monitor);
161
162         if (m->udev)
163                 udev_unref(m->udev);
164
165         bus_verify_polkit_async_registry_free(m->polkit_registry);
166
167         sd_bus_unref(m->bus);
168         sd_event_unref(m->event);
169
170         safe_close(m->reserve_vt_fd);
171
172         strv_free(m->kill_only_users);
173         strv_free(m->kill_exclude_users);
174
175         free(m->action_job);
176         free(m);
177 }
178
179 static int manager_enumerate_devices(Manager *m) {
180         struct udev_list_entry *item = NULL, *first = NULL;
181         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
182         int r;
183
184         assert(m);
185
186         /* Loads devices from udev and creates seats for them as
187          * necessary */
188
189         e = udev_enumerate_new(m->udev);
190         if (!e)
191                 return -ENOMEM;
192
193         r = udev_enumerate_add_match_tag(e, "master-of-seat");
194         if (r < 0)
195                 return r;
196
197         r = udev_enumerate_add_match_is_initialized(e);
198         if (r < 0)
199                 return r;
200
201         r = udev_enumerate_scan_devices(e);
202         if (r < 0)
203                 return r;
204
205         first = udev_enumerate_get_list_entry(e);
206         udev_list_entry_foreach(item, first) {
207                 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
208                 int k;
209
210                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
211                 if (!d)
212                         return -ENOMEM;
213
214                 k = manager_process_seat_device(m, d);
215                 if (k < 0)
216                         r = k;
217         }
218
219         return r;
220 }
221
222 static int manager_enumerate_buttons(Manager *m) {
223         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
224         struct udev_list_entry *item = NULL, *first = NULL;
225         int r;
226
227         assert(m);
228
229         /* Loads buttons from udev */
230
231         if (m->handle_power_key == HANDLE_IGNORE &&
232             m->handle_suspend_key == HANDLE_IGNORE &&
233             m->handle_hibernate_key == HANDLE_IGNORE &&
234             m->handle_lid_switch == HANDLE_IGNORE &&
235             m->handle_lid_switch_docked == 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_errno(errno, "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_errno(errno, "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_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
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_errno(errno, "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_errno(k, "Failed to add user by file name %s: %m", de->d_name);
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_errno(errno, "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_errno(k, "Failed to add session by file name %s: %m", de->d_name);
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_errno(errno, "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_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
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_errno(errno, "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                 return log_error_errno(r, "Failed to connect to system bus: %m");
586
587         r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
588         if (r < 0)
589                 return log_error_errno(r, "Failed to add manager object vtable: %m");
590
591         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
592         if (r < 0)
593                 return log_error_errno(r, "Failed to add seat object vtable: %m");
594
595         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
596         if (r < 0)
597                 return log_error_errno(r, "Failed to add seat enumerator: %m");
598
599         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
600         if (r < 0)
601                 return log_error_errno(r, "Failed to add session object vtable: %m");
602
603         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
604         if (r < 0)
605                 return log_error_errno(r, "Failed to add session enumerator: %m");
606
607         r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
608         if (r < 0)
609                 return log_error_errno(r, "Failed to add user object vtable: %m");
610
611         r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
612         if (r < 0)
613                 return log_error_errno(r, "Failed to add user enumerator: %m");
614
615         r = sd_bus_add_match(m->bus,
616                              NULL,
617                              "type='signal',"
618                              "sender='org.freedesktop.DBus',"
619                              "interface='org.freedesktop.DBus',"
620                              "member='NameOwnerChanged',"
621                              "path='/org/freedesktop/DBus'",
622                              match_name_owner_changed, m);
623         if (r < 0)
624                 return log_error_errno(r, "Failed to add match for NameOwnerChanged: %m");
625
626         r = sd_bus_add_match(m->bus,
627                              NULL,
628                              "type='signal',"
629                              "sender='org.freedesktop.systemd1',"
630                              "interface='org.freedesktop.systemd1.Manager',"
631                              "member='JobRemoved',"
632                              "path='/org/freedesktop/systemd1'",
633                              match_job_removed, m);
634         if (r < 0)
635                 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
636
637         r = sd_bus_add_match(m->bus,
638                              NULL,
639                              "type='signal',"
640                              "sender='org.freedesktop.systemd1',"
641                              "interface='org.freedesktop.systemd1.Manager',"
642                              "member='UnitRemoved',"
643                              "path='/org/freedesktop/systemd1'",
644                              match_unit_removed, m);
645         if (r < 0)
646                 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
647
648         r = sd_bus_add_match(m->bus,
649                              NULL,
650                              "type='signal',"
651                              "sender='org.freedesktop.systemd1',"
652                              "interface='org.freedesktop.DBus.Properties',"
653                              "member='PropertiesChanged'",
654                              match_properties_changed, m);
655         if (r < 0)
656                 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
657
658         r = sd_bus_add_match(m->bus,
659                              NULL,
660                              "type='signal',"
661                              "sender='org.freedesktop.systemd1',"
662                              "interface='org.freedesktop.systemd1.Manager',"
663                              "member='Reloading',"
664                              "path='/org/freedesktop/systemd1'",
665                              match_reloading, m);
666         if (r < 0)
667                 return log_error_errno(r, "Failed to add match for Reloading: %m");
668
669         r = sd_bus_call_method(
670                         m->bus,
671                         "org.freedesktop.systemd1",
672                         "/org/freedesktop/systemd1",
673                         "org.freedesktop.systemd1.Manager",
674                         "Subscribe",
675                         &error,
676                         NULL, NULL);
677         if (r < 0) {
678                 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
679                 return r;
680         }
681
682         r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
683         if (r < 0)
684                 return log_error_errno(r, "Failed to register name: %m");
685
686         r = sd_bus_attach_event(m->bus, m->event, 0);
687         if (r < 0)
688                 return log_error_errno(r, "Failed to attach bus to event loop: %m");
689
690         return 0;
691 }
692
693 static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
694         Manager *m = data;
695         Session *active, *iter;
696
697         /*
698          * We got a VT-switch signal and we have to acknowledge it immediately.
699          * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
700          * old user-space might run multiple sessions on a single VT, *sigh*.
701          * Therefore, we have to iterate all sessions and find one with a vtfd
702          * on the requested VT.
703          * As only VTs with active controllers have VT_PROCESS set, our current
704          * notion of the active VT might be wrong (for instance if the switch
705          * happens while we setup VT_PROCESS). Therefore, read the current VT
706          * first and then use s->active->vtnr as reference. Note that this is
707          * not racy, as no further VT-switch can happen as long as we're in
708          * synchronous VT_PROCESS mode.
709          */
710
711         assert(m->seat0);
712         seat_read_active_vt(m->seat0);
713
714         active = m->seat0->active;
715         if (!active || active->vtnr < 1) {
716                 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
717                 return 0;
718         }
719
720         if (active->vtfd >= 0) {
721                 session_leave_vt(active);
722         } else {
723                 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
724                         if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
725                                 session_leave_vt(iter);
726                                 break;
727                         }
728                 }
729         }
730
731         return 0;
732 }
733
734 static int manager_connect_console(Manager *m) {
735         int r;
736
737         assert(m);
738         assert(m->console_active_fd < 0);
739
740         /* On certain architectures (S390 and Xen, and containers),
741            /dev/tty0 does not exist, so don't fail if we can't open
742            it. */
743         if (access("/dev/tty0", F_OK) < 0)
744                 return 0;
745
746         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
747         if (m->console_active_fd < 0) {
748
749                 /* On some systems the device node /dev/tty0 may exist
750                  * even though /sys/class/tty/tty0 does not. */
751                 if (errno == ENOENT)
752                         return 0;
753
754                 log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
755                 return -errno;
756         }
757
758         r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
759         if (r < 0) {
760                 log_error("Failed to watch foreground console");
761                 return r;
762         }
763
764         /*
765          * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
766          * as VT-acquire signal. We ignore any acquire-events (yes, we still
767          * have to provide a valid signal-number for it!) and acknowledge all
768          * release events immediately.
769          */
770
771         if (SIGRTMIN + 1 > SIGRTMAX) {
772                 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
773                 return -EINVAL;
774         }
775
776         r = ignore_signals(SIGRTMIN + 1, -1);
777         if (r < 0)
778                 return log_error_errno(r, "Cannot ignore SIGRTMIN + 1: %m");
779
780         r = sigprocmask_many(SIG_BLOCK, SIGRTMIN, -1);
781         if (r < 0)
782                 return log_error_errno(r, "Cannot block SIGRTMIN: %m");
783
784         r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
785         if (r < 0)
786                 return r;
787
788         return 0;
789 }
790
791 static int manager_connect_udev(Manager *m) {
792         int r;
793
794         assert(m);
795         assert(!m->udev_seat_monitor);
796         assert(!m->udev_device_monitor);
797         assert(!m->udev_vcsa_monitor);
798         assert(!m->udev_button_monitor);
799
800         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
801         if (!m->udev_seat_monitor)
802                 return -ENOMEM;
803
804         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
805         if (r < 0)
806                 return r;
807
808         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
809         if (r < 0)
810                 return r;
811
812         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);
813         if (r < 0)
814                 return r;
815
816         m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
817         if (!m->udev_device_monitor)
818                 return -ENOMEM;
819
820         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
821         if (r < 0)
822                 return r;
823
824         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
825         if (r < 0)
826                 return r;
827
828         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
829         if (r < 0)
830                 return r;
831
832         r = udev_monitor_enable_receiving(m->udev_device_monitor);
833         if (r < 0)
834                 return r;
835
836         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);
837         if (r < 0)
838                 return r;
839
840         /* Don't watch keys if nobody cares */
841         if (m->handle_power_key != HANDLE_IGNORE ||
842             m->handle_suspend_key != HANDLE_IGNORE ||
843             m->handle_hibernate_key != HANDLE_IGNORE ||
844             m->handle_lid_switch != HANDLE_IGNORE ||
845             m->handle_lid_switch_docked != HANDLE_IGNORE) {
846
847                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
848                 if (!m->udev_button_monitor)
849                         return -ENOMEM;
850
851                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
852                 if (r < 0)
853                         return r;
854
855                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
856                 if (r < 0)
857                         return r;
858
859                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
860                 if (r < 0)
861                         return r;
862
863                 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);
864                 if (r < 0)
865                         return r;
866         }
867
868         /* Don't bother watching VCSA devices, if nobody cares */
869         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
870
871                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
872                 if (!m->udev_vcsa_monitor)
873                         return -ENOMEM;
874
875                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
876                 if (r < 0)
877                         return r;
878
879                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
880                 if (r < 0)
881                         return r;
882
883                 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);
884                 if (r < 0)
885                         return r;
886         }
887
888         return 0;
889 }
890
891 void manager_gc(Manager *m, bool drop_not_started) {
892         Seat *seat;
893         Session *session;
894         User *user;
895
896         assert(m);
897
898         while ((seat = m->seat_gc_queue)) {
899                 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
900                 seat->in_gc_queue = false;
901
902                 if (!seat_check_gc(seat, drop_not_started)) {
903                         seat_stop(seat, false);
904                         seat_free(seat);
905                 }
906         }
907
908         while ((session = m->session_gc_queue)) {
909                 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
910                 session->in_gc_queue = false;
911
912                 /* First, if we are not closing yet, initiate stopping */
913                 if (!session_check_gc(session, drop_not_started) &&
914                     session_get_state(session) != SESSION_CLOSING)
915                         session_stop(session, false);
916
917                 /* Normally, this should make the session busy again,
918                  * if it doesn't then let's get rid of it
919                  * immediately */
920                 if (!session_check_gc(session, drop_not_started)) {
921                         session_finalize(session);
922                         session_free(session);
923                 }
924         }
925
926         while ((user = m->user_gc_queue)) {
927                 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
928                 user->in_gc_queue = false;
929
930                 /* First step: queue stop jobs */
931                 if (!user_check_gc(user, drop_not_started))
932                         user_stop(user, false);
933
934                 /* Second step: finalize user */
935                 if (!user_check_gc(user, drop_not_started)) {
936                         user_finalize(user);
937                         user_free(user);
938                 }
939         }
940 }
941
942 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
943         Manager *m = userdata;
944         struct dual_timestamp since;
945         usec_t n, elapse;
946         int r;
947
948         assert(m);
949
950         if (m->idle_action == HANDLE_IGNORE ||
951             m->idle_action_usec <= 0)
952                 return 0;
953
954         n = now(CLOCK_MONOTONIC);
955
956         r = manager_get_idle_hint(m, &since);
957         if (r <= 0)
958                 /* Not idle. Let's check if after a timeout it might be idle then. */
959                 elapse = n + m->idle_action_usec;
960         else {
961                 /* Idle! Let's see if it's time to do something, or if
962                  * we shall sleep for longer. */
963
964                 if (n >= since.monotonic + m->idle_action_usec &&
965                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
966                         log_info("System idle. Taking action.");
967
968                         manager_handle_action(m, 0, m->idle_action, false, false);
969                         m->idle_action_not_before_usec = n;
970                 }
971
972                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
973         }
974
975         if (!m->idle_action_event_source) {
976
977                 r = sd_event_add_time(
978                                 m->event,
979                                 &m->idle_action_event_source,
980                                 CLOCK_MONOTONIC,
981                                 elapse, USEC_PER_SEC*30,
982                                 manager_dispatch_idle_action, m);
983                 if (r < 0)
984                         return log_error_errno(r, "Failed to add idle event source: %m");
985
986                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
987                 if (r < 0)
988                         return log_error_errno(r, "Failed to set idle event source priority: %m");
989         } else {
990                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
991                 if (r < 0)
992                         return log_error_errno(r, "Failed to set idle event timer: %m");
993
994                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
995                 if (r < 0)
996                         return log_error_errno(r, "Failed to enable idle event timer: %m");
997         }
998
999         return 0;
1000 }
1001
1002 int manager_startup(Manager *m) {
1003         int r;
1004         Seat *seat;
1005         Session *session;
1006         User *user;
1007         Button *button;
1008         Inhibitor *inhibitor;
1009         Iterator i;
1010
1011         assert(m);
1012
1013         /* Connect to console */
1014         r = manager_connect_console(m);
1015         if (r < 0)
1016                 return r;
1017
1018         /* Connect to udev */
1019         r = manager_connect_udev(m);
1020         if (r < 0)
1021                 return log_error_errno(r, "Failed to create udev watchers: %m");
1022
1023         /* Connect to the bus */
1024         r = manager_connect_bus(m);
1025         if (r < 0)
1026                 return r;
1027
1028         /* Instantiate magic seat 0 */
1029         r = manager_add_seat(m, "seat0", &m->seat0);
1030         if (r < 0)
1031                 return log_error_errno(r, "Failed to add seat0: %m");
1032
1033         r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
1034         if (r < 0)
1035                 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
1036
1037         /* Deserialize state */
1038         r = manager_enumerate_devices(m);
1039         if (r < 0)
1040                 log_warning_errno(r, "Device enumeration failed: %m");
1041
1042         r = manager_enumerate_seats(m);
1043         if (r < 0)
1044                 log_warning_errno(r, "Seat enumeration failed: %m");
1045
1046         r = manager_enumerate_users(m);
1047         if (r < 0)
1048                 log_warning_errno(r, "User enumeration failed: %m");
1049
1050         r = manager_enumerate_sessions(m);
1051         if (r < 0)
1052                 log_warning_errno(r, "Session enumeration failed: %m");
1053
1054         r = manager_enumerate_inhibitors(m);
1055         if (r < 0)
1056                 log_warning_errno(r, "Inhibitor enumeration failed: %m");
1057
1058         r = manager_enumerate_buttons(m);
1059         if (r < 0)
1060                 log_warning_errno(r, "Button enumeration failed: %m");
1061
1062         /* Remove stale objects before we start them */
1063         manager_gc(m, false);
1064
1065         /* Reserve the special reserved VT */
1066         manager_reserve_vt(m);
1067
1068         /* And start everything */
1069         HASHMAP_FOREACH(seat, m->seats, i)
1070                 seat_start(seat);
1071
1072         HASHMAP_FOREACH(user, m->users, i)
1073                 user_start(user);
1074
1075         HASHMAP_FOREACH(session, m->sessions, i)
1076                 session_start(session);
1077
1078         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1079                 inhibitor_start(inhibitor);
1080
1081         HASHMAP_FOREACH(button, m->buttons, i)
1082                 button_check_switches(button);
1083
1084         manager_dispatch_idle_action(NULL, 0, m);
1085
1086         return 0;
1087 }
1088
1089 int manager_run(Manager *m) {
1090         int r;
1091
1092         assert(m);
1093
1094         for (;;) {
1095                 usec_t us = (uint64_t) -1;
1096
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                 if (manager_dispatch_delayed(m) > 0)
1106                         continue;
1107
1108                 if (m->action_what != 0 && !m->action_job) {
1109                         usec_t x, y;
1110
1111                         x = now(CLOCK_MONOTONIC);
1112                         y = m->action_timestamp + m->inhibit_delay_max;
1113
1114                         us = x >= y ? 0 : y - x;
1115                 }
1116
1117                 r = sd_event_run(m->event, us);
1118                 if (r < 0)
1119                         return r;
1120         }
1121 }
1122
1123 static int manager_parse_config_file(Manager *m) {
1124         assert(m);
1125
1126         return config_parse_many("/etc/systemd/logind.conf",
1127                                  CONF_DIRS_NULSTR("systemd/logind.conf"),
1128                                  "Login\0",
1129                                  config_item_perf_lookup, logind_gperf_lookup,
1130                                  false, m);
1131 }
1132
1133 int main(int argc, char *argv[]) {
1134         Manager *m = NULL;
1135         int r;
1136
1137         log_set_target(LOG_TARGET_AUTO);
1138         log_set_facility(LOG_AUTH);
1139         log_parse_environment();
1140         log_open();
1141
1142         umask(0022);
1143
1144         if (argc != 1) {
1145                 log_error("This program takes no arguments.");
1146                 r = -EINVAL;
1147                 goto finish;
1148         }
1149
1150         /* Always create the directories people can create inotify
1151          * watches in. Note that some applications might check for the
1152          * existence of /run/systemd/seats/ to determine whether
1153          * logind is available, so please always make sure this check
1154          * stays in. */
1155         mkdir_label("/run/systemd/seats", 0755);
1156         mkdir_label("/run/systemd/users", 0755);
1157         mkdir_label("/run/systemd/sessions", 0755);
1158
1159         m = manager_new();
1160         if (!m) {
1161                 r = log_oom();
1162                 goto finish;
1163         }
1164
1165         manager_parse_config_file(m);
1166
1167         r = manager_startup(m);
1168         if (r < 0) {
1169                 log_error_errno(r, "Failed to fully start up daemon: %m");
1170                 goto finish;
1171         }
1172
1173         log_debug("systemd-logind running as pid "PID_FMT, getpid());
1174
1175         sd_notify(false,
1176                   "READY=1\n"
1177                   "STATUS=Processing requests...");
1178
1179         r = manager_run(m);
1180
1181         log_debug("systemd-logind stopped as pid "PID_FMT, getpid());
1182
1183 finish:
1184         sd_notify(false,
1185                   "STOPPING=1\n"
1186                   "STATUS=Shutting down...");
1187
1188         if (m)
1189                 manager_free(m);
1190
1191         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1192 }