chiark / gitweb /
logind: make sure there's always a getty available on TTY6
[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 <pwd.h>
24 #include <libudev.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <sys/epoll.h>
29 #include <sys/ioctl.h>
30 #include <linux/vt.h>
31
32 #include <systemd/sd-daemon.h>
33
34 #include "logind.h"
35 #include "dbus-common.h"
36 #include "dbus-loop.h"
37 #include "strv.h"
38 #include "conf-parser.h"
39
40 Manager *manager_new(void) {
41         Manager *m;
42
43         m = new0(Manager, 1);
44         if (!m)
45                 return NULL;
46
47         m->console_active_fd = -1;
48         m->bus_fd = -1;
49         m->udev_seat_fd = -1;
50         m->udev_vcsa_fd = -1;
51         m->udev_button_fd = -1;
52         m->epoll_fd = -1;
53         m->reserve_vt_fd = -1;
54
55         m->n_autovts = 6;
56         m->reserve_vt = 6;
57         m->inhibit_delay_max = 5 * USEC_PER_SEC;
58         m->handle_power_key = HANDLE_NO_SESSION;
59         m->handle_sleep_key = HANDLE_TTY_SESSION;
60         m->handle_lid_switch = HANDLE_OFF;
61
62         m->devices = hashmap_new(string_hash_func, string_compare_func);
63         m->seats = hashmap_new(string_hash_func, string_compare_func);
64         m->sessions = hashmap_new(string_hash_func, string_compare_func);
65         m->users = hashmap_new(trivial_hash_func, trivial_compare_func);
66         m->inhibitors = hashmap_new(string_hash_func, string_compare_func);
67         m->buttons = hashmap_new(string_hash_func, string_compare_func);
68
69         m->user_cgroups = hashmap_new(string_hash_func, string_compare_func);
70         m->session_cgroups = hashmap_new(string_hash_func, string_compare_func);
71
72         m->session_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
73         m->inhibitor_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
74         m->button_fds = hashmap_new(trivial_hash_func, trivial_compare_func);
75
76         if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons ||
77             !m->user_cgroups || !m->session_cgroups ||
78             !m->session_fds || !m->inhibitor_fds || !m->button_fds) {
79                 manager_free(m);
80                 return NULL;
81         }
82
83         m->reset_controllers = strv_new("cpu", NULL);
84         m->kill_exclude_users = strv_new("root", NULL);
85         if (!m->reset_controllers || !m->kill_exclude_users) {
86                 manager_free(m);
87                 return NULL;
88         }
89
90         m->udev = udev_new();
91         if (!m->udev) {
92                 manager_free(m);
93                 return NULL;
94         }
95
96         if (cg_get_user_path(&m->cgroup_path) < 0) {
97                 manager_free(m);
98                 return NULL;
99         }
100
101         return m;
102 }
103
104 void manager_free(Manager *m) {
105         Session *session;
106         User *u;
107         Device *d;
108         Seat *s;
109         Inhibitor *i;
110         Button *b;
111
112         assert(m);
113
114         while ((session = hashmap_first(m->sessions)))
115                 session_free(session);
116
117         while ((u = hashmap_first(m->users)))
118                 user_free(u);
119
120         while ((d = hashmap_first(m->devices)))
121                 device_free(d);
122
123         while ((s = hashmap_first(m->seats)))
124                 seat_free(s);
125
126         while ((i = hashmap_first(m->inhibitors)))
127                 inhibitor_free(i);
128
129         while ((b = hashmap_first(m->buttons)))
130                 button_free(b);
131
132         hashmap_free(m->devices);
133         hashmap_free(m->seats);
134         hashmap_free(m->sessions);
135         hashmap_free(m->users);
136         hashmap_free(m->inhibitors);
137         hashmap_free(m->buttons);
138
139         hashmap_free(m->user_cgroups);
140         hashmap_free(m->session_cgroups);
141
142         hashmap_free(m->session_fds);
143         hashmap_free(m->inhibitor_fds);
144         hashmap_free(m->button_fds);
145
146         if (m->console_active_fd >= 0)
147                 close_nointr_nofail(m->console_active_fd);
148
149         if (m->udev_seat_monitor)
150                 udev_monitor_unref(m->udev_seat_monitor);
151         if (m->udev_vcsa_monitor)
152                 udev_monitor_unref(m->udev_vcsa_monitor);
153         if (m->udev_button_monitor)
154                 udev_monitor_unref(m->udev_button_monitor);
155
156         if (m->udev)
157                 udev_unref(m->udev);
158
159         if (m->bus) {
160                 dbus_connection_flush(m->bus);
161                 dbus_connection_close(m->bus);
162                 dbus_connection_unref(m->bus);
163         }
164
165         if (m->bus_fd >= 0)
166                 close_nointr_nofail(m->bus_fd);
167
168         if (m->epoll_fd >= 0)
169                 close_nointr_nofail(m->epoll_fd);
170
171         if (m->reserve_vt_fd >= 0)
172                 close_nointr_nofail(m->reserve_vt_fd);
173
174         strv_free(m->controllers);
175         strv_free(m->reset_controllers);
176         strv_free(m->kill_only_users);
177         strv_free(m->kill_exclude_users);
178
179         free(m->cgroup_path);
180         free(m);
181 }
182
183 int manager_add_device(Manager *m, const char *sysfs, Device **_device) {
184         Device *d;
185
186         assert(m);
187         assert(sysfs);
188
189         d = hashmap_get(m->devices, sysfs);
190         if (d) {
191                 if (_device)
192                         *_device = d;
193
194                 return 0;
195         }
196
197         d = device_new(m, sysfs);
198         if (!d)
199                 return -ENOMEM;
200
201         if (_device)
202                 *_device = d;
203
204         return 0;
205 }
206
207 int manager_add_seat(Manager *m, const char *id, Seat **_seat) {
208         Seat *s;
209
210         assert(m);
211         assert(id);
212
213         s = hashmap_get(m->seats, id);
214         if (s) {
215                 if (_seat)
216                         *_seat = s;
217
218                 return 0;
219         }
220
221         s = seat_new(m, id);
222         if (!s)
223                 return -ENOMEM;
224
225         if (_seat)
226                 *_seat = s;
227
228         return 0;
229 }
230
231 int manager_add_session(Manager *m, User *u, const char *id, Session **_session) {
232         Session *s;
233
234         assert(m);
235         assert(id);
236
237         s = hashmap_get(m->sessions, id);
238         if (s) {
239                 if (_session)
240                         *_session = s;
241
242                 return 0;
243         }
244
245         s = session_new(m, u, id);
246         if (!s)
247                 return -ENOMEM;
248
249         if (_session)
250                 *_session = s;
251
252         return 0;
253 }
254
255 int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **_user) {
256         User *u;
257
258         assert(m);
259         assert(name);
260
261         u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
262         if (u) {
263                 if (_user)
264                         *_user = u;
265
266                 return 0;
267         }
268
269         u = user_new(m, uid, gid, name);
270         if (!u)
271                 return -ENOMEM;
272
273         if (_user)
274                 *_user = u;
275
276         return 0;
277 }
278
279 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
280         uid_t uid;
281         gid_t gid;
282         int r;
283
284         assert(m);
285         assert(name);
286
287         r = get_user_creds(&name, &uid, &gid, NULL, NULL);
288         if (r < 0)
289                 return r;
290
291         return manager_add_user(m, uid, gid, name, _user);
292 }
293
294 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
295         struct passwd *p;
296
297         assert(m);
298
299         errno = 0;
300         p = getpwuid(uid);
301         if (!p)
302                 return errno ? -errno : -ENOENT;
303
304         return manager_add_user(m, uid, p->pw_gid, p->pw_name, _user);
305 }
306
307 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **_inhibitor) {
308         Inhibitor *i;
309
310         assert(m);
311         assert(id);
312
313         i = hashmap_get(m->inhibitors, id);
314         if (i) {
315                 if (_inhibitor)
316                         *_inhibitor = i;
317
318                 return 0;
319         }
320
321         i = inhibitor_new(m, id);
322         if (!i)
323                 return -ENOMEM;
324
325         if (_inhibitor)
326                 *_inhibitor = i;
327
328         return 0;
329 }
330
331 int manager_add_button(Manager *m, const char *name, Button **_button) {
332         Button *b;
333
334         assert(m);
335         assert(name);
336
337         b = hashmap_get(m->buttons, name);
338         if (b) {
339                 if (_button)
340                         *_button = b;
341
342                 return 0;
343         }
344
345         b = button_new(m, name);
346         if (!b)
347                 return -ENOMEM;
348
349         if (_button)
350                 *_button = b;
351
352         return 0;
353 }
354
355 int manager_process_seat_device(Manager *m, struct udev_device *d) {
356         Device *device;
357         int r;
358
359         assert(m);
360
361         if (streq_ptr(udev_device_get_action(d), "remove")) {
362
363                 device = hashmap_get(m->devices, udev_device_get_syspath(d));
364                 if (!device)
365                         return 0;
366
367                 seat_add_to_gc_queue(device->seat);
368                 device_free(device);
369
370         } else {
371                 const char *sn;
372                 Seat *seat;
373
374                 sn = udev_device_get_property_value(d, "ID_SEAT");
375                 if (isempty(sn))
376                         sn = "seat0";
377
378                 if (!seat_name_is_valid(sn)) {
379                         log_warning("Device with invalid seat name %s found, ignoring.", sn);
380                         return 0;
381                 }
382
383                 r = manager_add_device(m, udev_device_get_syspath(d), &device);
384                 if (r < 0)
385                         return r;
386
387                 r = manager_add_seat(m, sn, &seat);
388                 if (r < 0) {
389                         if (!device->seat)
390                                 device_free(device);
391
392                         return r;
393                 }
394
395                 device_attach(device, seat);
396                 seat_start(seat);
397         }
398
399         return 0;
400 }
401
402 int manager_process_button_device(Manager *m, struct udev_device *d) {
403         Button *b;
404
405         int r;
406
407         assert(m);
408
409         if (streq_ptr(udev_device_get_action(d), "remove")) {
410
411                 b = hashmap_get(m->buttons, udev_device_get_sysname(d));
412                 if (!b)
413                         return 0;
414
415                 button_free(b);
416
417         } else {
418                 const char *sn;
419
420                 r = manager_add_button(m, udev_device_get_sysname(d), &b);
421                 if (r < 0)
422                         return r;
423
424                 sn = udev_device_get_property_value(d, "ID_SEAT");
425                 if (isempty(sn))
426                         sn = "seat0";
427
428                 button_set_seat(b, sn);
429                 button_open(b);
430         }
431
432         return 0;
433 }
434
435 int manager_enumerate_devices(Manager *m) {
436         struct udev_list_entry *item = NULL, *first = NULL;
437         struct udev_enumerate *e;
438         int r;
439
440         assert(m);
441
442         /* Loads devices from udev and creates seats for them as
443          * necessary */
444
445         e = udev_enumerate_new(m->udev);
446         if (!e) {
447                 r = -ENOMEM;
448                 goto finish;
449         }
450
451         r = udev_enumerate_add_match_subsystem(e, "graphics");
452         if (r < 0)
453                 goto finish;
454
455         r = udev_enumerate_add_match_tag(e, "seat");
456         if (r < 0)
457                 goto finish;
458
459         r = udev_enumerate_scan_devices(e);
460         if (r < 0)
461                 goto finish;
462
463         first = udev_enumerate_get_list_entry(e);
464         udev_list_entry_foreach(item, first) {
465                 struct udev_device *d;
466                 int k;
467
468                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
469                 if (!d) {
470                         r = -ENOMEM;
471                         goto finish;
472                 }
473
474                 k = manager_process_seat_device(m, d);
475                 udev_device_unref(d);
476
477                 if (k < 0)
478                         r = k;
479         }
480
481 finish:
482         if (e)
483                 udev_enumerate_unref(e);
484
485         return r;
486 }
487
488 int manager_enumerate_buttons(Manager *m) {
489         struct udev_list_entry *item = NULL, *first = NULL;
490         struct udev_enumerate *e;
491         int r;
492
493         assert(m);
494
495         /* Loads buttons from udev */
496
497         if (m->handle_power_key == HANDLE_OFF &&
498             m->handle_sleep_key == HANDLE_OFF &&
499             m->handle_lid_switch == HANDLE_OFF)
500                 return 0;
501
502         e = udev_enumerate_new(m->udev);
503         if (!e) {
504                 r = -ENOMEM;
505                 goto finish;
506         }
507
508         r = udev_enumerate_add_match_subsystem(e, "input");
509         if (r < 0)
510                 goto finish;
511
512         r = udev_enumerate_add_match_tag(e, "power-switch");
513         if (r < 0)
514                 goto finish;
515
516         r = udev_enumerate_scan_devices(e);
517         if (r < 0)
518                 goto finish;
519
520         first = udev_enumerate_get_list_entry(e);
521         udev_list_entry_foreach(item, first) {
522                 struct udev_device *d;
523                 int k;
524
525                 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
526                 if (!d) {
527                         r = -ENOMEM;
528                         goto finish;
529                 }
530
531                 k = manager_process_button_device(m, d);
532                 udev_device_unref(d);
533
534                 if (k < 0)
535                         r = k;
536         }
537
538 finish:
539         if (e)
540                 udev_enumerate_unref(e);
541
542         return r;
543 }
544
545 int manager_enumerate_seats(Manager *m) {
546         DIR *d;
547         struct dirent *de;
548         int r = 0;
549
550         assert(m);
551
552         /* This loads data about seats stored on disk, but does not
553          * actually create any seats. Removes data of seats that no
554          * longer exist. */
555
556         d = opendir("/run/systemd/seats");
557         if (!d) {
558                 if (errno == ENOENT)
559                         return 0;
560
561                 log_error("Failed to open /run/systemd/seats: %m");
562                 return -errno;
563         }
564
565         while ((de = readdir(d))) {
566                 Seat *s;
567                 int k;
568
569                 if (!dirent_is_file(de))
570                         continue;
571
572                 s = hashmap_get(m->seats, de->d_name);
573                 if (!s) {
574                         unlinkat(dirfd(d), de->d_name, 0);
575                         continue;
576                 }
577
578                 k = seat_load(s);
579                 if (k < 0)
580                         r = k;
581         }
582
583         closedir(d);
584
585         return r;
586 }
587
588 static int manager_enumerate_users_from_cgroup(Manager *m) {
589         int r = 0, k;
590         char *name;
591         DIR *d;
592
593         r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_path, &d);
594         if (r < 0) {
595                 if (r == -ENOENT)
596                         return 0;
597
598                 log_error("Failed to open %s: %s", m->cgroup_path, strerror(-r));
599                 return r;
600         }
601
602         while ((k = cg_read_subgroup(d, &name)) > 0) {
603                 User *user;
604
605                 k = manager_add_user_by_name(m, name, &user);
606                 if (k < 0) {
607                         free(name);
608                         r = k;
609                         continue;
610                 }
611
612                 user_add_to_gc_queue(user);
613
614                 if (!user->cgroup_path)
615                         if (asprintf(&user->cgroup_path, "%s/%s", m->cgroup_path, name) < 0) {
616                                 r = -ENOMEM;
617                                 free(name);
618                                 break;
619                         }
620
621                 free(name);
622         }
623
624         if (r >= 0 && k < 0)
625                 r = k;
626
627         closedir(d);
628
629         return r;
630 }
631
632 static int manager_enumerate_linger_users(Manager *m) {
633         DIR *d;
634         struct dirent *de;
635         int r = 0;
636
637         d = opendir("/var/lib/systemd/linger");
638         if (!d) {
639                 if (errno == ENOENT)
640                         return 0;
641
642                 log_error("Failed to open /var/lib/systemd/linger/: %m");
643                 return -errno;
644         }
645
646         while ((de = readdir(d))) {
647                 int k;
648
649                 if (!dirent_is_file(de))
650                         continue;
651
652                 k = manager_add_user_by_name(m, de->d_name, NULL);
653                 if (k < 0) {
654                         log_notice("Couldn't add lingering user %s: %s", de->d_name, strerror(-k));
655                         r = k;
656                 }
657         }
658
659         closedir(d);
660
661         return r;
662 }
663
664 int manager_enumerate_users(Manager *m) {
665         DIR *d;
666         struct dirent *de;
667         int r, k;
668
669         assert(m);
670
671         /* First, enumerate user cgroups */
672         r = manager_enumerate_users_from_cgroup(m);
673
674         /* Second, add lingering users on top */
675         k = manager_enumerate_linger_users(m);
676         if (k < 0)
677                 r = k;
678
679         /* Third, read in user data stored on disk */
680         d = opendir("/run/systemd/users");
681         if (!d) {
682                 if (errno == ENOENT)
683                         return 0;
684
685                 log_error("Failed to open /run/systemd/users: %m");
686                 return -errno;
687         }
688
689         while ((de = readdir(d))) {
690                 uid_t uid;
691                 User *u;
692
693                 if (!dirent_is_file(de))
694                         continue;
695
696                 k = parse_uid(de->d_name, &uid);
697                 if (k < 0) {
698                         log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
699                         continue;
700                 }
701
702                 u = hashmap_get(m->users, ULONG_TO_PTR(uid));
703                 if (!u) {
704                         unlinkat(dirfd(d), de->d_name, 0);
705                         continue;
706                 }
707
708                 k = user_load(u);
709                 if (k < 0)
710                         r = k;
711         }
712
713         closedir(d);
714
715         return r;
716 }
717
718 static int manager_enumerate_sessions_from_cgroup(Manager *m) {
719         User *u;
720         Iterator i;
721         int r = 0;
722
723         HASHMAP_FOREACH(u, m->users, i) {
724                 DIR *d;
725                 char *name;
726                 int k;
727
728                 if (!u->cgroup_path)
729                         continue;
730
731                 k = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, &d);
732                 if (k < 0) {
733                         if (k == -ENOENT)
734                                 continue;
735
736                         log_error("Failed to open %s: %s", u->cgroup_path, strerror(-k));
737                         r = k;
738                         continue;
739                 }
740
741                 while ((k = cg_read_subgroup(d, &name)) > 0) {
742                         Session *session;
743
744                         if (streq(name, "shared"))
745                                 continue;
746
747                         k = manager_add_session(m, u, name, &session);
748                         if (k < 0) {
749                                 free(name);
750                                 break;
751                         }
752
753                         session_add_to_gc_queue(session);
754
755                         if (!session->cgroup_path)
756                                 if (asprintf(&session->cgroup_path, "%s/%s", u->cgroup_path, name) < 0) {
757                                         k = -ENOMEM;
758                                         free(name);
759                                         break;
760                                 }
761
762                         free(name);
763                 }
764
765                 closedir(d);
766
767                 if (k < 0)
768                         r = k;
769         }
770
771         return r;
772 }
773
774 int manager_enumerate_sessions(Manager *m) {
775         DIR *d;
776         struct dirent *de;
777         int r = 0;
778
779         assert(m);
780
781         /* First enumerate session cgroups */
782         r = manager_enumerate_sessions_from_cgroup(m);
783
784         /* Second, read in session data stored on disk */
785         d = opendir("/run/systemd/sessions");
786         if (!d) {
787                 if (errno == ENOENT)
788                         return 0;
789
790                 log_error("Failed to open /run/systemd/sessions: %m");
791                 return -errno;
792         }
793
794         while ((de = readdir(d))) {
795                 struct Session *s;
796                 int k;
797
798                 if (!dirent_is_file(de))
799                         continue;
800
801                 s = hashmap_get(m->sessions, de->d_name);
802                 if (!s) {
803                         unlinkat(dirfd(d), de->d_name, 0);
804                         continue;
805                 }
806
807                 k = session_load(s);
808                 if (k < 0)
809                         r = k;
810         }
811
812         closedir(d);
813
814         return r;
815 }
816
817 int manager_enumerate_inhibitors(Manager *m) {
818         DIR *d;
819         struct dirent *de;
820         int r = 0;
821
822         assert(m);
823
824         d = opendir("/run/systemd/inhibit");
825         if (!d) {
826                 if (errno == ENOENT)
827                         return 0;
828
829                 log_error("Failed to open /run/systemd/inhibit: %m");
830                 return -errno;
831         }
832
833         while ((de = readdir(d))) {
834                 int k;
835                 Inhibitor *i;
836
837                 if (!dirent_is_file(de))
838                         continue;
839
840                 k = manager_add_inhibitor(m, de->d_name, &i);
841                 if (k < 0) {
842                         log_notice("Couldn't add inhibitor %s: %s", de->d_name, strerror(-k));
843                         r = k;
844                         continue;
845                 }
846
847                 k = inhibitor_load(i);
848                 if (k < 0)
849                         r = k;
850         }
851
852         closedir(d);
853
854         return r;
855 }
856
857 int manager_dispatch_seat_udev(Manager *m) {
858         struct udev_device *d;
859         int r;
860
861         assert(m);
862
863         d = udev_monitor_receive_device(m->udev_seat_monitor);
864         if (!d)
865                 return -ENOMEM;
866
867         r = manager_process_seat_device(m, d);
868         udev_device_unref(d);
869
870         return r;
871 }
872
873 int manager_dispatch_vcsa_udev(Manager *m) {
874         struct udev_device *d;
875         int r = 0;
876         const char *name;
877
878         assert(m);
879
880         d = udev_monitor_receive_device(m->udev_vcsa_monitor);
881         if (!d)
882                 return -ENOMEM;
883
884         name = udev_device_get_sysname(d);
885
886         /* Whenever a VCSA device is removed try to reallocate our
887          * VTs, to make sure our auto VTs never go away. */
888
889         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
890                 r = seat_preallocate_vts(m->vtconsole);
891
892         udev_device_unref(d);
893
894         return r;
895 }
896
897 int manager_dispatch_button_udev(Manager *m) {
898         struct udev_device *d;
899         int r;
900
901         assert(m);
902
903         d = udev_monitor_receive_device(m->udev_button_monitor);
904         if (!d)
905                 return -ENOMEM;
906
907         r = manager_process_button_device(m, d);
908         udev_device_unref(d);
909
910         return r;
911 }
912
913 int manager_dispatch_console(Manager *m) {
914         assert(m);
915
916         if (m->vtconsole)
917                 seat_read_active_vt(m->vtconsole);
918
919         return 0;
920 }
921
922 static int vt_is_busy(int vtnr) {
923         struct vt_stat vt_stat;
924         int r = 0, fd;
925
926         assert(vtnr >= 1);
927
928         /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
929          * we'd open the latter we'd open the foreground tty which
930          * hence would be unconditionally busy. By opening /dev/tty1
931          * we avoid this. Since tty1 is special and needs to be an
932          * explicitly loaded getty or DM this is safe. */
933
934         fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
935         if (fd < 0)
936                 return -errno;
937
938         if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
939                 r = -errno;
940         else
941                 r = !!(vt_stat.v_state & (1 << vtnr));
942
943         close_nointr_nofail(fd);
944
945         return r;
946 }
947
948 int manager_spawn_autovt(Manager *m, int vtnr) {
949         int r;
950         char *name = NULL;
951         const char *mode = "fail";
952
953         assert(m);
954         assert(vtnr >= 1);
955
956         if ((unsigned) vtnr > m->n_autovts &&
957             (unsigned) vtnr != m->reserve_vt)
958                 return 0;
959
960         if ((unsigned) vtnr != m->reserve_vt) {
961                 /* If this is the reserved TTY, we'll start the getty
962                  * on it in any case, but otherwise only if it is not
963                  * busy. */
964
965                 r = vt_is_busy(vtnr);
966                 if (r < 0)
967                         return r;
968                 else if (r > 0)
969                         return -EBUSY;
970         }
971
972         if (asprintf(&name, "autovt@tty%i.service", vtnr) < 0) {
973                 log_error("Could not allocate service name.");
974                 r = -ENOMEM;
975                 goto finish;
976         }
977
978         r = bus_method_call_with_reply (
979                         m->bus,
980                         "org.freedesktop.systemd1",
981                         "/org/freedesktop/systemd1",
982                         "org.freedesktop.systemd1.Manager",
983                         "StartUnit",
984                         NULL,
985                         NULL,
986                         DBUS_TYPE_STRING, &name,
987                         DBUS_TYPE_STRING, &mode,
988                         DBUS_TYPE_INVALID);
989
990 finish:
991         free(name);
992
993         return r;
994 }
995
996 static int manager_reserve_vt(Manager *m) {
997         _cleanup_free_ char *p = NULL;
998
999         assert(m);
1000
1001         if (m->reserve_vt <= 0)
1002                 return 0;
1003
1004         if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
1005                 return log_oom();
1006
1007         m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
1008         if (m->reserve_vt_fd < 0) {
1009                 log_warning("Failed to pin reserved VT: %m");
1010                 return -errno;
1011         }
1012
1013         return 0;
1014 }
1015
1016 int manager_get_session_by_cgroup(Manager *m, const char *cgroup, Session **session) {
1017         Session *s;
1018         char *p;
1019
1020         assert(m);
1021         assert(cgroup);
1022         assert(session);
1023
1024         s = hashmap_get(m->session_cgroups, cgroup);
1025         if (s) {
1026                 *session = s;
1027                 return 1;
1028         }
1029
1030         p = strdup(cgroup);
1031         if (!p)
1032                 return log_oom();
1033
1034         for (;;) {
1035                 char *e;
1036
1037                 e = strrchr(p, '/');
1038                 if (!e || e == p) {
1039                         free(p);
1040                         *session = NULL;
1041                         return 0;
1042                 }
1043
1044                 *e = 0;
1045
1046                 s = hashmap_get(m->session_cgroups, p);
1047                 if (s) {
1048                         free(p);
1049                         *session = s;
1050                         return 1;
1051                 }
1052         }
1053 }
1054
1055 int manager_get_user_by_cgroup(Manager *m, const char *cgroup, User **user) {
1056         User *u;
1057         char *p;
1058
1059         assert(m);
1060         assert(cgroup);
1061         assert(user);
1062
1063         u = hashmap_get(m->user_cgroups, cgroup);
1064         if (u) {
1065                 *user = u;
1066                 return 1;
1067         }
1068
1069         p = strdup(cgroup);
1070         if (!p)
1071                 return log_oom();
1072
1073         for (;;) {
1074                 char *e;
1075
1076                 e = strrchr(p, '/');
1077                 if (!e || e == p) {
1078                         free(p);
1079                         *user = NULL;
1080                         return 0;
1081                 }
1082
1083                 *e = 0;
1084
1085                 u = hashmap_get(m->user_cgroups, p);
1086                 if (u) {
1087                         free(p);
1088                         *user = u;
1089                         return 1;
1090                 }
1091         }
1092 }
1093
1094 int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
1095         char *p;
1096         int r;
1097
1098         assert(m);
1099         assert(pid >= 1);
1100         assert(session);
1101
1102         r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &p);
1103         if (r < 0)
1104                 return r;
1105
1106         r = manager_get_session_by_cgroup(m, p, session);
1107         free(p);
1108
1109         return r;
1110 }
1111
1112 void manager_cgroup_notify_empty(Manager *m, const char *cgroup) {
1113         Session *s;
1114         User *u;
1115         int r;
1116
1117         r = manager_get_session_by_cgroup(m, cgroup, &s);
1118         if (r > 0)
1119                 session_add_to_gc_queue(s);
1120
1121         r = manager_get_user_by_cgroup(m, cgroup, &u);
1122         if (r > 0)
1123                 user_add_to_gc_queue(u);
1124 }
1125
1126 static void manager_dispatch_other(Manager *m, int fd) {
1127         Session *s;
1128         Inhibitor *i;
1129         Button *b;
1130
1131         assert_se(m);
1132         assert_se(fd >= 0);
1133
1134         s = hashmap_get(m->session_fds, INT_TO_PTR(fd + 1));
1135         if (s) {
1136                 assert(s->fifo_fd == fd);
1137                 session_remove_fifo(s);
1138                 session_stop(s);
1139                 return;
1140         }
1141
1142         i = hashmap_get(m->inhibitor_fds, INT_TO_PTR(fd + 1));
1143         if (i) {
1144                 assert(i->fifo_fd == fd);
1145                 inhibitor_stop(i);
1146                 inhibitor_free(i);
1147                 return;
1148         }
1149
1150         b = hashmap_get(m->button_fds, INT_TO_PTR(fd + 1));
1151         if (b) {
1152                 assert(b->fd == fd);
1153                 button_process(b);
1154                 return;
1155         }
1156
1157         assert_not_reached("Got event for unknown fd");
1158 }
1159
1160 static int manager_connect_bus(Manager *m) {
1161         DBusError error;
1162         int r;
1163         struct epoll_event ev;
1164
1165         assert(m);
1166         assert(!m->bus);
1167         assert(m->bus_fd < 0);
1168
1169         dbus_error_init(&error);
1170
1171         m->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
1172         if (!m->bus) {
1173                 log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
1174                 r = -ECONNREFUSED;
1175                 goto fail;
1176         }
1177
1178         if (!dbus_connection_register_object_path(m->bus, "/org/freedesktop/login1", &bus_manager_vtable, m) ||
1179             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/seat", &bus_seat_vtable, m) ||
1180             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/session", &bus_session_vtable, m) ||
1181             !dbus_connection_register_fallback(m->bus, "/org/freedesktop/login1/user", &bus_user_vtable, m) ||
1182             !dbus_connection_add_filter(m->bus, bus_message_filter, m, NULL)) {
1183                 r = log_oom();
1184                 goto fail;
1185         }
1186
1187         dbus_bus_add_match(m->bus,
1188                            "type='signal',"
1189                            "interface='org.freedesktop.systemd1.Agent',"
1190                            "member='Released',"
1191                            "path='/org/freedesktop/systemd1/agent'",
1192                            &error);
1193
1194         if (dbus_error_is_set(&error)) {
1195                 log_error("Failed to register match: %s", bus_error_message(&error));
1196                 r = -EIO;
1197                 goto fail;
1198         }
1199
1200         r = dbus_bus_request_name(m->bus, "org.freedesktop.login1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
1201         if (dbus_error_is_set(&error)) {
1202                 log_error("Failed to register name on bus: %s", bus_error_message(&error));
1203                 r = -EIO;
1204                 goto fail;
1205         }
1206
1207         if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)  {
1208                 log_error("Failed to acquire name.");
1209                 r = -EEXIST;
1210                 goto fail;
1211         }
1212
1213         m->bus_fd = bus_loop_open(m->bus);
1214         if (m->bus_fd < 0) {
1215                 r = m->bus_fd;
1216                 goto fail;
1217         }
1218
1219         zero(ev);
1220         ev.events = EPOLLIN;
1221         ev.data.u32 = FD_BUS;
1222
1223         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->bus_fd, &ev) < 0)
1224                 goto fail;
1225
1226         return 0;
1227
1228 fail:
1229         dbus_error_free(&error);
1230
1231         return r;
1232 }
1233
1234 static int manager_connect_console(Manager *m) {
1235         struct epoll_event ev;
1236
1237         assert(m);
1238         assert(m->console_active_fd < 0);
1239
1240         /* On certain architectures (S390 and Xen, and containers),
1241            /dev/tty0 does not exist, so don't fail if we can't open
1242            it. */
1243         if (access("/dev/tty0", F_OK) < 0) {
1244                 m->console_active_fd = -1;
1245                 return 0;
1246         }
1247
1248         m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
1249         if (m->console_active_fd < 0) {
1250
1251                 /* On some systems the device node /dev/tty0 may exist
1252                  * even though /sys/class/tty/tty0 does not. */
1253                 if (errno == ENOENT)
1254                         return 0;
1255
1256                 log_error("Failed to open /sys/class/tty/tty0/active: %m");
1257                 return -errno;
1258         }
1259
1260         zero(ev);
1261         ev.events = 0;
1262         ev.data.u32 = FD_CONSOLE;
1263
1264         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->console_active_fd, &ev) < 0)
1265                 return -errno;
1266
1267         return 0;
1268 }
1269
1270 static int manager_connect_udev(Manager *m) {
1271         struct epoll_event ev;
1272         int r;
1273
1274         assert(m);
1275         assert(!m->udev_seat_monitor);
1276         assert(!m->udev_vcsa_monitor);
1277         assert(!m->udev_button_monitor);
1278
1279         m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1280         if (!m->udev_seat_monitor)
1281                 return -ENOMEM;
1282
1283         r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "seat");
1284         if (r < 0)
1285                 return r;
1286
1287         r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_seat_monitor, "graphics", NULL);
1288         if (r < 0)
1289                 return r;
1290
1291         r = udev_monitor_enable_receiving(m->udev_seat_monitor);
1292         if (r < 0)
1293                 return r;
1294
1295         m->udev_seat_fd = udev_monitor_get_fd(m->udev_seat_monitor);
1296
1297         zero(ev);
1298         ev.events = EPOLLIN;
1299         ev.data.u32 = FD_SEAT_UDEV;
1300         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_seat_fd, &ev) < 0)
1301                 return -errno;
1302
1303         /* Don't watch keys if nobody cares */
1304         if (m->handle_power_key != HANDLE_OFF ||
1305             m->handle_sleep_key != HANDLE_OFF ||
1306             m->handle_lid_switch != HANDLE_OFF) {
1307
1308                 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1309                 if (!m->udev_button_monitor)
1310                         return -ENOMEM;
1311
1312                 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
1313                 if (r < 0)
1314                         return r;
1315
1316                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
1317                 if (r < 0)
1318                         return r;
1319
1320                 r = udev_monitor_enable_receiving(m->udev_button_monitor);
1321                 if (r < 0)
1322                         return r;
1323
1324                 m->udev_button_fd = udev_monitor_get_fd(m->udev_button_monitor);
1325
1326                 zero(ev);
1327                 ev.events = EPOLLIN;
1328                 ev.data.u32 = FD_BUTTON_UDEV;
1329                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_button_fd, &ev) < 0)
1330                         return -errno;
1331         }
1332
1333         /* Don't bother watching VCSA devices, if nobody cares */
1334         if (m->n_autovts > 0 && m->console_active_fd >= 0) {
1335
1336                 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
1337                 if (!m->udev_vcsa_monitor)
1338                         return -ENOMEM;
1339
1340                 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
1341                 if (r < 0)
1342                         return r;
1343
1344                 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
1345                 if (r < 0)
1346                         return r;
1347
1348                 m->udev_vcsa_fd = udev_monitor_get_fd(m->udev_vcsa_monitor);
1349
1350                 zero(ev);
1351                 ev.events = EPOLLIN;
1352                 ev.data.u32 = FD_VCSA_UDEV;
1353                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->udev_vcsa_fd, &ev) < 0)
1354                         return -errno;
1355         }
1356
1357         return 0;
1358 }
1359
1360 void manager_gc(Manager *m, bool drop_not_started) {
1361         Seat *seat;
1362         Session *session;
1363         User *user;
1364
1365         assert(m);
1366
1367         while ((seat = m->seat_gc_queue)) {
1368                 LIST_REMOVE(Seat, gc_queue, m->seat_gc_queue, seat);
1369                 seat->in_gc_queue = false;
1370
1371                 if (seat_check_gc(seat, drop_not_started) == 0) {
1372                         seat_stop(seat);
1373                         seat_free(seat);
1374                 }
1375         }
1376
1377         while ((session = m->session_gc_queue)) {
1378                 LIST_REMOVE(Session, gc_queue, m->session_gc_queue, session);
1379                 session->in_gc_queue = false;
1380
1381                 if (session_check_gc(session, drop_not_started) == 0) {
1382                         session_stop(session);
1383                         session_free(session);
1384                 }
1385         }
1386
1387         while ((user = m->user_gc_queue)) {
1388                 LIST_REMOVE(User, gc_queue, m->user_gc_queue, user);
1389                 user->in_gc_queue = false;
1390
1391                 if (user_check_gc(user, drop_not_started) == 0) {
1392                         user_stop(user);
1393                         user_free(user);
1394                 }
1395         }
1396 }
1397
1398 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
1399         Session *s;
1400         bool idle_hint;
1401         dual_timestamp ts = { 0, 0 };
1402         Iterator i;
1403
1404         assert(m);
1405
1406         idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t);
1407
1408         HASHMAP_FOREACH(s, m->sessions, i) {
1409                 dual_timestamp k;
1410                 int ih;
1411
1412                 ih = session_get_idle_hint(s, &k);
1413                 if (ih < 0)
1414                         return ih;
1415
1416                 if (!ih) {
1417                         if (!idle_hint) {
1418                                 if (k.monotonic < ts.monotonic)
1419                                         ts = k;
1420                         } else {
1421                                 idle_hint = false;
1422                                 ts = k;
1423                         }
1424                 } else if (idle_hint) {
1425
1426                         if (k.monotonic > ts.monotonic)
1427                                 ts = k;
1428                 }
1429         }
1430
1431         if (t)
1432                 *t = ts;
1433
1434         return idle_hint;
1435 }
1436
1437 int manager_startup(Manager *m) {
1438         int r;
1439         Seat *seat;
1440         Session *session;
1441         User *user;
1442         Inhibitor *inhibitor;
1443         Iterator i;
1444
1445         assert(m);
1446         assert(m->epoll_fd <= 0);
1447
1448         cg_shorten_controllers(m->reset_controllers);
1449         cg_shorten_controllers(m->controllers);
1450
1451         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
1452         if (m->epoll_fd < 0)
1453                 return -errno;
1454
1455         /* Connect to console */
1456         r = manager_connect_console(m);
1457         if (r < 0)
1458                 return r;
1459
1460         /* Connect to udev */
1461         r = manager_connect_udev(m);
1462         if (r < 0)
1463                 return r;
1464
1465         /* Connect to the bus */
1466         r = manager_connect_bus(m);
1467         if (r < 0)
1468                 return r;
1469
1470         /* Instantiate magic seat 0 */
1471         r = manager_add_seat(m, "seat0", &m->vtconsole);
1472         if (r < 0)
1473                 return r;
1474
1475         /* Deserialize state */
1476         manager_enumerate_devices(m);
1477         manager_enumerate_seats(m);
1478         manager_enumerate_users(m);
1479         manager_enumerate_sessions(m);
1480         manager_enumerate_inhibitors(m);
1481         manager_enumerate_buttons(m);
1482
1483         /* Remove stale objects before we start them */
1484         manager_gc(m, false);
1485
1486         /* Reserve the special reserved VT */
1487         manager_reserve_vt(m);
1488
1489         /* And start everything */
1490         HASHMAP_FOREACH(seat, m->seats, i)
1491                 seat_start(seat);
1492
1493         HASHMAP_FOREACH(user, m->users, i)
1494                 user_start(user);
1495
1496         HASHMAP_FOREACH(session, m->sessions, i)
1497                 session_start(session);
1498
1499         HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1500                 inhibitor_start(inhibitor);
1501
1502         return 0;
1503 }
1504
1505 int manager_run(Manager *m) {
1506         assert(m);
1507
1508         for (;;) {
1509                 struct epoll_event event;
1510                 int n;
1511                 int msec = -1;
1512
1513                 manager_gc(m, true);
1514
1515                 if (manager_dispatch_delayed(m) > 0)
1516                         continue;
1517
1518                 if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE)
1519                         continue;
1520
1521                 manager_gc(m, true);
1522
1523                 if (m->delayed_unit) {
1524                         usec_t x, y;
1525
1526                         x = now(CLOCK_MONOTONIC);
1527                         y = m->delayed_timestamp + m->inhibit_delay_max;
1528
1529                         msec = x >= y ? 0 : (int) ((y - x) / USEC_PER_MSEC);
1530                 }
1531
1532                 n = epoll_wait(m->epoll_fd, &event, 1, msec);
1533                 if (n < 0) {
1534                         if (errno == EINTR || errno == EAGAIN)
1535                                 continue;
1536
1537                         log_error("epoll() failed: %m");
1538                         return -errno;
1539                 }
1540
1541                 if (n == 0)
1542                         continue;
1543
1544                 switch (event.data.u32) {
1545
1546                 case FD_SEAT_UDEV:
1547                         manager_dispatch_seat_udev(m);
1548                         break;
1549
1550                 case FD_VCSA_UDEV:
1551                         manager_dispatch_vcsa_udev(m);
1552                         break;
1553
1554                 case FD_BUTTON_UDEV:
1555                         manager_dispatch_button_udev(m);
1556                         break;
1557
1558                 case FD_CONSOLE:
1559                         manager_dispatch_console(m);
1560                         break;
1561
1562                 case FD_BUS:
1563                         bus_loop_dispatch(m->bus_fd);
1564                         break;
1565
1566                 default:
1567                         if (event.data.u32 >= FD_OTHER_BASE)
1568                                 manager_dispatch_other(m, event.data.u32 - FD_OTHER_BASE);
1569                 }
1570         }
1571
1572         return 0;
1573 }
1574
1575 static int manager_parse_config_file(Manager *m) {
1576         FILE *f;
1577         const char *fn;
1578         int r;
1579
1580         assert(m);
1581
1582         fn = "/etc/systemd/logind.conf";
1583         f = fopen(fn, "re");
1584         if (!f) {
1585                 if (errno == ENOENT)
1586                         return 0;
1587
1588                 log_warning("Failed to open configuration file %s: %m", fn);
1589                 return -errno;
1590         }
1591
1592         r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
1593         if (r < 0)
1594                 log_warning("Failed to parse configuration file: %s", strerror(-r));
1595
1596         fclose(f);
1597
1598         return r;
1599 }
1600
1601 int main(int argc, char *argv[]) {
1602         Manager *m = NULL;
1603         int r;
1604
1605         log_set_target(LOG_TARGET_AUTO);
1606         log_set_facility(LOG_AUTH);
1607         log_parse_environment();
1608         log_open();
1609
1610         umask(0022);
1611
1612         if (argc != 1) {
1613                 log_error("This program takes no arguments.");
1614                 r = -EINVAL;
1615                 goto finish;
1616         }
1617
1618         m = manager_new();
1619         if (!m) {
1620                 r = log_oom();
1621                 goto finish;
1622         }
1623
1624         manager_parse_config_file(m);
1625
1626         r = manager_startup(m);
1627         if (r < 0) {
1628                 log_error("Failed to fully start up daemon: %s", strerror(-r));
1629                 goto finish;
1630         }
1631
1632         log_debug("systemd-logind running as pid %lu", (unsigned long) getpid());
1633
1634         sd_notify(false,
1635                   "READY=1\n"
1636                   "STATUS=Processing requests...");
1637
1638         r = manager_run(m);
1639
1640         log_debug("systemd-logind stopped as pid %lu", (unsigned long) getpid());
1641
1642 finish:
1643         sd_notify(false,
1644                   "STATUS=Shutting down...");
1645
1646         if (m)
1647                 manager_free(m);
1648
1649         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1650 }