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