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