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