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