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