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