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