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