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