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