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