chiark / gitweb /
2e4342b0aedf4af9792bae02018107ac46fca38e
[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 "udev-util.h"
34 #include "formats-util.h"
35 #include "signal-util.h"
36 #include "label.h"
37 #include "logind.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(SYSTEMD_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                 (void) 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() <= 0)
222                 (void) cg_uninstall_release_agent(SYSTEMD_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         assert_se(ignore_signals(SIGRTMIN + 1, -1) >= 0);
873         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN, -1) >= 0);
874
875         r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
876         if (r < 0)
877                 return r;
878
879         return 0;
880 }
881
882 static int manager_connect_udev(Manager *m) {
883         int r;
884
885         assert(m);
886         assert(!m->udev_seat_monitor);
887         assert(!m->udev_device_monitor);
888         assert(!m->udev_vcsa_monitor);
889         assert(!m->udev_button_monitor);
890
891         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
892         if (!m->udev_seat_monitor)
893                 return -ENOMEM;
894
895         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
896         if (r < 0)
897                 return r;
898
899         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
900         if (r < 0)
901                 return r;
902
903         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);
904         if (r < 0)
905                 return r;
906
907         m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
908         if (!m->udev_device_monitor)
909                 return -ENOMEM;
910
911         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
912         if (r < 0)
913                 return r;
914
915         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
916         if (r < 0)
917                 return r;
918
919         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
920         if (r < 0)
921                 return r;
922
923         r = udev_monitor_enable_receiving(m->udev_device_monitor);
924         if (r < 0)
925                 return r;
926
927         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);
928         if (r < 0)
929                 return r;
930
931         /* Don't watch keys if nobody cares */
932         if (m->handle_power_key != HANDLE_IGNORE ||
933             m->handle_suspend_key != HANDLE_IGNORE ||
934             m->handle_hibernate_key != HANDLE_IGNORE ||
935             m->handle_lid_switch != HANDLE_IGNORE ||
936             m->handle_lid_switch_docked != HANDLE_IGNORE) {
937
938                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
939                 if (!m->udev_button_monitor)
940                         return -ENOMEM;
941
942                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
943                 if (r < 0)
944                         return r;
945
946                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
947                 if (r < 0)
948                         return r;
949
950                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
951                 if (r < 0)
952                         return r;
953
954                 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);
955                 if (r < 0)
956                         return r;
957         }
958
959         /* Don't bother watching VCSA devices, if nobody cares */
960 /// elogind does not support autospawning of vts
961 #if 0
962         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
963
964                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
965                 if (!m->udev_vcsa_monitor)
966                         return -ENOMEM;
967
968                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
969                 if (r < 0)
970                         return r;
971
972                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
973                 if (r < 0)
974                         return r;
975
976                 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);
977                 if (r < 0)
978                         return r;
979         }
980 #endif // 0
981
982         return 0;
983 }
984
985 static void manager_gc(Manager *m, bool drop_not_started) {
986         Seat *seat;
987         Session *session;
988         User *user;
989
990         assert(m);
991
992         while ((seat = m->seat_gc_queue)) {
993                 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
994                 seat->in_gc_queue = false;
995
996                 if (!seat_check_gc(seat, drop_not_started)) {
997                         seat_stop(seat, false);
998                         seat_free(seat);
999                 }
1000         }
1001
1002         while ((session = m->session_gc_queue)) {
1003                 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
1004                 session->in_gc_queue = false;
1005
1006                 /* First, if we are not closing yet, initiate stopping */
1007                 if (!session_check_gc(session, drop_not_started) &&
1008                     session_get_state(session) != SESSION_CLOSING)
1009                         session_stop(session, false);
1010
1011                 /* Normally, this should make the session referenced
1012                  * again, if it doesn't then let's get rid of it
1013                  * immediately */
1014                 if (!session_check_gc(session, drop_not_started)) {
1015                         session_finalize(session);
1016                         session_free(session);
1017                 }
1018         }
1019
1020         while ((user = m->user_gc_queue)) {
1021                 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
1022                 user->in_gc_queue = false;
1023
1024                 /* First step: queue stop jobs */
1025                 if (!user_check_gc(user, drop_not_started))
1026                         user_stop(user, false);
1027
1028                 /* Second step: finalize user */
1029                 if (!user_check_gc(user, drop_not_started)) {
1030                         user_finalize(user);
1031                         user_free(user);
1032                 }
1033         }
1034 }
1035
1036 static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
1037         Manager *m = userdata;
1038         struct dual_timestamp since;
1039         usec_t n, elapse;
1040         int r;
1041
1042         assert(m);
1043
1044         if (m->idle_action == HANDLE_IGNORE ||
1045             m->idle_action_usec <= 0)
1046                 return 0;
1047
1048         n = now(CLOCK_MONOTONIC);
1049
1050         r = manager_get_idle_hint(m, &since);
1051         if (r <= 0)
1052                 /* Not idle. Let's check if after a timeout it might be idle then. */
1053                 elapse = n + m->idle_action_usec;
1054         else {
1055                 /* Idle! Let's see if it's time to do something, or if
1056                  * we shall sleep for longer. */
1057
1058                 if (n >= since.monotonic + m->idle_action_usec &&
1059                     (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1060                         log_info("System idle. Taking action.");
1061
1062                         manager_handle_action(m, 0, m->idle_action, false, false);
1063                         m->idle_action_not_before_usec = n;
1064                 }
1065
1066                 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
1067         }
1068
1069         if (!m->idle_action_event_source) {
1070
1071                 r = sd_event_add_time(
1072                                 m->event,
1073                                 &m->idle_action_event_source,
1074                                 CLOCK_MONOTONIC,
1075                                 elapse, USEC_PER_SEC*30,
1076                                 manager_dispatch_idle_action, m);
1077                 if (r < 0)
1078                         return log_error_errno(r, "Failed to add idle event source: %m");
1079
1080                 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
1081                 if (r < 0)
1082                         return log_error_errno(r, "Failed to set idle event source priority: %m");
1083         } else {
1084                 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
1085                 if (r < 0)
1086                         return log_error_errno(r, "Failed to set idle event timer: %m");
1087
1088                 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
1089                 if (r < 0)
1090                         return log_error_errno(r, "Failed to enable idle event timer: %m");
1091         }
1092
1093         return 0;
1094 }
1095
1096 static int manager_startup(Manager *m) {
1097         int r;
1098         Seat *seat;
1099         Session *session;
1100         User *user;
1101         Button *button;
1102         Inhibitor *inhibitor;
1103         Iterator i;
1104
1105         assert(m);
1106
1107         /* Connect to console */
1108         r = manager_connect_console(m);
1109         if (r < 0)
1110                 return r;
1111
1112         /* Connect to udev */
1113         r = manager_connect_udev(m);
1114         if (r < 0)
1115                 return log_error_errno(r, "Failed to create udev watchers: %m");
1116
1117         /* Connect to the bus */
1118         r = manager_connect_bus(m);
1119         if (r < 0)
1120                 return r;
1121
1122         /* Instantiate magic seat 0 */
1123         r = manager_add_seat(m, "seat0", &m->seat0);
1124         if (r < 0)
1125                 return log_error_errno(r, "Failed to add seat0: %m");
1126
1127         r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
1128         if (r < 0)
1129                 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
1130
1131         /* Deserialize state */
1132         r = manager_enumerate_devices(m);
1133         if (r < 0)
1134                 log_warning_errno(r, "Device enumeration failed: %m");
1135
1136         r = manager_enumerate_seats(m);
1137         if (r < 0)
1138                 log_warning_errno(r, "Seat enumeration failed: %m");
1139
1140         r = manager_enumerate_users(m);
1141         if (r < 0)
1142                 log_warning_errno(r, "User enumeration failed: %m");
1143
1144         r = manager_enumerate_sessions(m);
1145         if (r < 0)
1146                 log_warning_errno(r, "Session enumeration failed: %m");
1147
1148         r = manager_enumerate_inhibitors(m);
1149         if (r < 0)
1150                 log_warning_errno(r, "Inhibitor enumeration failed: %m");
1151
1152         r = manager_enumerate_buttons(m);
1153         if (r < 0)
1154                 log_warning_errno(r, "Button enumeration failed: %m");
1155
1156         /* Remove stale objects before we start them */
1157         manager_gc(m, false);
1158
1159         /* Reserve the special reserved VT */
1160 /// elogind does not support autospawning of vts
1161 #if 0
1162         manager_reserve_vt(m);
1163 #endif // 0
1164
1165         /* And start everything */
1166         HASHMAP_FOREACH(seat, m->seats, i)
1167                 seat_start(seat);
1168
1169         HASHMAP_FOREACH(user, m->users, i)
1170                 user_start(user);
1171
1172         HASHMAP_FOREACH(session, m->sessions, i)
1173                 session_start(session);
1174
1175         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1176                 inhibitor_start(inhibitor);
1177
1178         HASHMAP_FOREACH(button, m->buttons, i)
1179                 button_check_switches(button);
1180
1181         manager_dispatch_idle_action(NULL, 0, m);
1182
1183         return 0;
1184 }
1185
1186 static int manager_run(Manager *m) {
1187         int r;
1188
1189         assert(m);
1190
1191         for (;;) {
1192                 r = sd_event_get_state(m->event);
1193                 if (r < 0)
1194                         return r;
1195                 if (r == SD_EVENT_FINISHED)
1196                         return 0;
1197
1198                 manager_gc(m, true);
1199
1200                 r = manager_dispatch_delayed(m, false);
1201                 if (r < 0)
1202                         return r;
1203                 if (r > 0)
1204                         continue;
1205
1206                 r = sd_event_run(m->event, (uint64_t) -1);
1207                 if (r < 0)
1208                         return r;
1209         }
1210 }
1211
1212 static int manager_parse_config_file(Manager *m) {
1213         const char *unit = NULL, *logind_conf, *sections;
1214         FILE *file = NULL;
1215         bool relaxed = false, allow_include = false, warn = true;
1216
1217         assert(m);
1218
1219 /// elogind parses its own config file
1220 #if 0
1221         return config_parse_many("/etc/systemd/logind.conf",
1222                                  CONF_DIRS_NULSTR("systemd/logind.conf"),
1223                                  "Login\0",
1224                                  config_item_perf_lookup, logind_gperf_lookup,
1225                                  false, m);
1226 #endif // 0
1227
1228         logind_conf = getenv("ELOGIND_CONF_FILE");
1229         if (!logind_conf)
1230                 logind_conf = PKGSYSCONFDIR "/logind.conf";
1231         sections = "Login\0Sleep\0";
1232
1233         return config_parse(unit, logind_conf, file, sections,
1234                             config_item_perf_lookup, logind_gperf_lookup,
1235                             relaxed, allow_include, warn, m);
1236 }
1237
1238 int main(int argc, char *argv[]) {
1239         Manager *m = NULL;
1240         int r;
1241
1242         elogind_set_program_name(argv[0]);
1243         log_set_target(LOG_TARGET_AUTO);
1244         log_set_facility(LOG_AUTH);
1245         log_parse_environment();
1246         log_open();
1247
1248 #ifdef ENABLE_DEBUG_ELOGIND
1249         log_set_max_level(LOG_DEBUG);
1250 #endif // ENABLE_DEBUG_ELOGIND
1251
1252         umask(0022);
1253
1254         if (argc != 1) {
1255                 log_error("This program takes no arguments.");
1256                 r = -EINVAL;
1257                 goto finish;
1258         }
1259
1260         /* Always create the directories people can create inotify
1261          * watches in. Note that some applications might check for the
1262          * existence of /run/systemd/seats/ to determine whether
1263          * logind is available, so please always make sure this check
1264          * stays in. */
1265         r = mkdir_label("/run/systemd", 0755);
1266         if ( (r < 0) && (-EEXIST != r) )
1267                 return log_error_errno(r, "Failed to create /run/systemd : %m");
1268         r = mkdir_label("/run/systemd/seats", 0755);
1269         if ( r < 0 && (-EEXIST != r) )
1270                 return log_error_errno(r, "Failed to create /run/systemd/seats : %m");
1271         r = mkdir_label("/run/systemd/users", 0755);
1272         if ( r < 0 && (-EEXIST != r) )
1273                 return log_error_errno(r, "Failed to create /run/systemd/users : %m");
1274         r = mkdir_label("/run/systemd/sessions", 0755);
1275         if ( r < 0 && (-EEXIST != r) )
1276                 return log_error_errno(r, "Failed to create /run/systemd/sessions : %m");
1277         r = mkdir_label("/run/systemd/machines", 0755);
1278         if ( r < 0 && (-EEXIST != r) )
1279                 return log_error_errno(r, "Failed to create /run/systemd/machines : %m");
1280
1281         m = manager_new();
1282         if (!m) {
1283                 r = log_oom();
1284                 goto finish;
1285         }
1286
1287         manager_parse_config_file(m);
1288
1289         r = manager_startup(m);
1290         if (r < 0) {
1291                 log_error_errno(r, "Failed to fully start up daemon: %m");
1292                 goto finish;
1293         }
1294
1295         log_debug("logind running as pid "PID_FMT, getpid());
1296
1297         sd_notify(false,
1298                   "READY=1\n"
1299                   "STATUS=Processing requests...");
1300
1301         r = manager_run(m);
1302
1303         log_debug("logind stopped as pid "PID_FMT, getpid());
1304
1305 finish:
1306         sd_notify(false,
1307                   "STOPPING=1\n"
1308                   "STATUS=Shutting down...");
1309
1310                 manager_free(m);
1311
1312         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1313 }