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