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