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