]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/logind.c
merge two lines in our get_output_flags() functions
[thirdparty/systemd.git] / src / login / logind.c
CommitLineData
20263082
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2011 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
20263082
LP
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 14 Lesser General Public License for more details.
20263082 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
20263082
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include <errno.h>
20263082
LP
21#include <fcntl.h>
22#include <string.h>
23#include <unistd.h>
20263082 24
b4bbcaa9 25#include "libudev.h"
cc377381 26#include "sd-daemon.h"
07630cea 27
b5efdb8a 28#include "alloc-util.h"
cc377381 29#include "bus-error.h"
07630cea
LP
30#include "bus-util.h"
31#include "conf-parser.h"
a0f29c76 32#include "def.h"
a0956174 33#include "dirent-util.h"
3ffd4af2 34#include "fd-util.h"
f97b34a6 35#include "format-util.h"
3ffd4af2 36#include "logind.h"
4b51966c 37#include "selinux-util.h"
24882e06 38#include "signal-util.h"
07630cea
LP
39#include "strv.h"
40#include "udev-util.h"
f5058264 41#include "cgroup-util.h"
20263082 42
905f0a39
DM
43static void manager_free(Manager *m);
44
a2ed7077 45static void manager_reset_config(Manager *m) {
20263082 46 m->n_autovts = 6;
98a77df5 47 m->reserve_vt = 6;
66cdd0f2 48 m->remove_ipc = true;
eecd1362 49 m->inhibit_delay_max = 5 * USEC_PER_SEC;
beaafb2e 50 m->handle_power_key = HANDLE_POWEROFF;
8e7fd6ad
LP
51 m->handle_suspend_key = HANDLE_SUSPEND;
52 m->handle_hibernate_key = HANDLE_HIBERNATE;
beaafb2e 53 m->handle_lid_switch = HANDLE_SUSPEND;
3c56cab4 54 m->handle_lid_switch_docked = HANDLE_IGNORE;
a2ed7077
ZJS
55 m->power_key_ignore_inhibited = false;
56 m->suspend_key_ignore_inhibited = false;
57 m->hibernate_key_ignore_inhibited = false;
beaafb2e 58 m->lid_switch_ignore_inhibited = true;
a2ed7077 59
9d10cbee 60 m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
20263082 61
23406ce5
LP
62 m->idle_action_usec = 30 * USEC_PER_MINUTE;
63 m->idle_action = HANDLE_IGNORE;
23406ce5 64
d8cf2ac7 65 m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
f5058264 66 m->user_tasks_max = system_tasks_max_scale(DEFAULT_USER_TASKS_MAX_PERCENTAGE, 100U); /* 33% */
64b56896
LP
67 m->sessions_max = 8192;
68 m->inhibitors_max = 8192;
1c231f56 69
95365a57 70 m->kill_user_processes = KILL_USER_PROCESSES;
a2ed7077
ZJS
71
72 m->kill_only_users = strv_free(m->kill_only_users);
73 m->kill_exclude_users = strv_free(m->kill_exclude_users);
74}
75
76static Manager *manager_new(void) {
77 Manager *m;
78 int r;
79
80 m = new0(Manager, 1);
81 if (!m)
82 return NULL;
83
84 m->console_active_fd = -1;
85 m->reserve_vt_fd = -1;
86
87 m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
88
d5099efc
MS
89 m->devices = hashmap_new(&string_hash_ops);
90 m->seats = hashmap_new(&string_hash_ops);
91 m->sessions = hashmap_new(&string_hash_ops);
92 m->users = hashmap_new(NULL);
93 m->inhibitors = hashmap_new(&string_hash_ops);
94 m->buttons = hashmap_new(&string_hash_ops);
f8e2fb7b 95
d5099efc
MS
96 m->user_units = hashmap_new(&string_hash_ops);
97 m->session_units = hashmap_new(&string_hash_ops);
8c8c4351 98
3cde9e8f 99 if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units)
ed4ba7e4 100 goto fail;
25d93491 101
20263082 102 m->udev = udev_new();
ed4ba7e4
LP
103 if (!m->udev)
104 goto fail;
20263082 105
afc6adb5 106 r = sd_event_default(&m->event);
ed4ba7e4
LP
107 if (r < 0)
108 goto fail;
cc377381 109
cde93897
LP
110 sd_event_set_watchdog(m->event, true);
111
a2ed7077
ZJS
112 manager_reset_config(m);
113
20263082 114 return m;
ed4ba7e4
LP
115
116fail:
117 manager_free(m);
118 return NULL;
20263082
LP
119}
120
905f0a39 121static void manager_free(Manager *m) {
20263082
LP
122 Session *session;
123 User *u;
124 Device *d;
125 Seat *s;
f8e2fb7b 126 Inhibitor *i;
069cfc85 127 Button *b;
20263082 128
84a4e660
LP
129 if (!m)
130 return;
20263082
LP
131
132 while ((session = hashmap_first(m->sessions)))
133 session_free(session);
134
135 while ((u = hashmap_first(m->users)))
136 user_free(u);
137
138 while ((d = hashmap_first(m->devices)))
139 device_free(d);
140
141 while ((s = hashmap_first(m->seats)))
142 seat_free(s);
143
f8e2fb7b
LP
144 while ((i = hashmap_first(m->inhibitors)))
145 inhibitor_free(i);
146
069cfc85
LP
147 while ((b = hashmap_first(m->buttons)))
148 button_free(b);
149
20263082
LP
150 hashmap_free(m->devices);
151 hashmap_free(m->seats);
f8e2fb7b
LP
152 hashmap_free(m->sessions);
153 hashmap_free(m->users);
154 hashmap_free(m->inhibitors);
069cfc85 155 hashmap_free(m->buttons);
f8e2fb7b 156
fb6becb4
LP
157 hashmap_free(m->user_units);
158 hashmap_free(m->session_units);
8c8c4351 159
cc377381 160 sd_event_source_unref(m->idle_action_event_source);
c0f32805 161 sd_event_source_unref(m->inhibit_timeout_source);
8aaa023a 162 sd_event_source_unref(m->scheduled_shutdown_timeout_source);
867c37f6 163 sd_event_source_unref(m->nologin_timeout_source);
e2fa5721 164 sd_event_source_unref(m->wall_message_timeout_source);
cc377381
LP
165
166 sd_event_source_unref(m->console_active_event_source);
167 sd_event_source_unref(m->udev_seat_event_source);
168 sd_event_source_unref(m->udev_device_event_source);
169 sd_event_source_unref(m->udev_vcsa_event_source);
170 sd_event_source_unref(m->udev_button_event_source);
f9cd6be1 171 sd_event_source_unref(m->lid_switch_ignore_event_source);
20263082 172
03e334a1 173 safe_close(m->console_active_fd);
20263082 174
3e044c49
ME
175 udev_monitor_unref(m->udev_seat_monitor);
176 udev_monitor_unref(m->udev_device_monitor);
177 udev_monitor_unref(m->udev_vcsa_monitor);
178 udev_monitor_unref(m->udev_button_monitor);
179
180 udev_unref(m->udev);
20263082 181
867c37f6 182 if (m->unlink_nologin)
a790812c 183 (void) unlink("/run/nologin");
867c37f6 184
36e34057 185 bus_verify_polkit_async_registry_free(m->polkit_registry);
20263082 186
cc377381
LP
187 sd_bus_unref(m->bus);
188 sd_event_unref(m->event);
20263082 189
03e334a1 190 safe_close(m->reserve_vt_fd);
98a77df5 191
193197e8
LP
192 strv_free(m->kill_only_users);
193 strv_free(m->kill_exclude_users);
194
8aaa023a 195 free(m->scheduled_shutdown_type);
e2fa5721
DM
196 free(m->scheduled_shutdown_tty);
197 free(m->wall_message);
af9792ac 198 free(m->action_job);
20263082
LP
199 free(m);
200}
201
9588bc32 202static int manager_enumerate_devices(Manager *m) {
20263082 203 struct udev_list_entry *item = NULL, *first = NULL;
bf5332d2 204 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
14c3baca 205 int r;
20263082
LP
206
207 assert(m);
208
209 /* Loads devices from udev and creates seats for them as
210 * necessary */
211
212 e = udev_enumerate_new(m->udev);
bf5332d2
LP
213 if (!e)
214 return -ENOMEM;
20263082 215
2d96536d 216 r = udev_enumerate_add_match_tag(e, "master-of-seat");
14c3baca 217 if (r < 0)
bf5332d2 218 return r;
20263082 219
e1202047
LP
220 r = udev_enumerate_add_match_is_initialized(e);
221 if (r < 0)
222 return r;
223
14c3baca
LP
224 r = udev_enumerate_scan_devices(e);
225 if (r < 0)
bf5332d2 226 return r;
20263082
LP
227
228 first = udev_enumerate_get_list_entry(e);
229 udev_list_entry_foreach(item, first) {
bf5332d2 230 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
20263082
LP
231 int k;
232
233 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
bf5332d2
LP
234 if (!d)
235 return -ENOMEM;
20263082 236
bf5332d2 237 k = manager_process_seat_device(m, d);
20263082
LP
238 if (k < 0)
239 r = k;
240 }
241
20263082
LP
242 return r;
243}
244
9588bc32 245static int manager_enumerate_buttons(Manager *m) {
bf5332d2 246 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
069cfc85 247 struct udev_list_entry *item = NULL, *first = NULL;
069cfc85
LP
248 int r;
249
250 assert(m);
251
252 /* Loads buttons from udev */
253
beaafb2e 254 if (m->handle_power_key == HANDLE_IGNORE &&
8e7fd6ad
LP
255 m->handle_suspend_key == HANDLE_IGNORE &&
256 m->handle_hibernate_key == HANDLE_IGNORE &&
3c56cab4
BW
257 m->handle_lid_switch == HANDLE_IGNORE &&
258 m->handle_lid_switch_docked == HANDLE_IGNORE)
6de0e0e5
LP
259 return 0;
260
069cfc85 261 e = udev_enumerate_new(m->udev);
bf5332d2
LP
262 if (!e)
263 return -ENOMEM;
069cfc85
LP
264
265 r = udev_enumerate_add_match_subsystem(e, "input");
266 if (r < 0)
bf5332d2 267 return r;
069cfc85
LP
268
269 r = udev_enumerate_add_match_tag(e, "power-switch");
270 if (r < 0)
bf5332d2 271 return r;
069cfc85 272
e1202047
LP
273 r = udev_enumerate_add_match_is_initialized(e);
274 if (r < 0)
275 return r;
276
069cfc85
LP
277 r = udev_enumerate_scan_devices(e);
278 if (r < 0)
bf5332d2 279 return r;
069cfc85
LP
280
281 first = udev_enumerate_get_list_entry(e);
282 udev_list_entry_foreach(item, first) {
bf5332d2 283 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
069cfc85
LP
284 int k;
285
286 d = udev_device_new_from_syspath(m->udev, udev_list_entry_get_name(item));
bf5332d2
LP
287 if (!d)
288 return -ENOMEM;
069cfc85 289
bf5332d2 290 k = manager_process_button_device(m, d);
069cfc85
LP
291 if (k < 0)
292 r = k;
293 }
294
069cfc85
LP
295 return r;
296}
297
9588bc32 298static int manager_enumerate_seats(Manager *m) {
9444b1f2 299 _cleanup_closedir_ DIR *d = NULL;
20263082
LP
300 struct dirent *de;
301 int r = 0;
302
303 assert(m);
304
305 /* This loads data about seats stored on disk, but does not
306 * actually create any seats. Removes data of seats that no
307 * longer exist. */
308
309 d = opendir("/run/systemd/seats");
310 if (!d) {
311 if (errno == ENOENT)
312 return 0;
313
e1427b13 314 return log_error_errno(errno, "Failed to open /run/systemd/seats: %m");
20263082
LP
315 }
316
9444b1f2 317 FOREACH_DIRENT(de, d, return -errno) {
20263082
LP
318 Seat *s;
319 int k;
320
321 if (!dirent_is_file(de))
322 continue;
323
324 s = hashmap_get(m->seats, de->d_name);
325 if (!s) {
326 unlinkat(dirfd(d), de->d_name, 0);
327 continue;
328 }
329
330 k = seat_load(s);
331 if (k < 0)
332 r = k;
333 }
334
14c3baca
LP
335 return r;
336}
20263082 337
14c3baca 338static int manager_enumerate_linger_users(Manager *m) {
9444b1f2 339 _cleanup_closedir_ DIR *d = NULL;
14c3baca
LP
340 struct dirent *de;
341 int r = 0;
342
9444b1f2
LP
343 assert(m);
344
14c3baca
LP
345 d = opendir("/var/lib/systemd/linger");
346 if (!d) {
347 if (errno == ENOENT)
348 return 0;
349
e1427b13 350 return log_error_errno(errno, "Failed to open /var/lib/systemd/linger/: %m");
14c3baca
LP
351 }
352
9444b1f2 353 FOREACH_DIRENT(de, d, return -errno) {
14c3baca
LP
354 int k;
355
356 if (!dirent_is_file(de))
20263082
LP
357 continue;
358
14c3baca
LP
359 k = manager_add_user_by_name(m, de->d_name, NULL);
360 if (k < 0) {
da927ba9 361 log_notice_errno(k, "Couldn't add lingering user %s: %m", de->d_name);
14c3baca 362 r = k;
20263082
LP
363 }
364 }
365
20263082
LP
366 return r;
367}
368
9588bc32 369static int manager_enumerate_users(Manager *m) {
9444b1f2 370 _cleanup_closedir_ DIR *d = NULL;
20263082 371 struct dirent *de;
14c3baca 372 int r, k;
20263082
LP
373
374 assert(m);
375
9444b1f2 376 /* Add lingering users */
b3629c7d 377 r = manager_enumerate_linger_users(m);
14c3baca 378
9444b1f2 379 /* Read in user data stored on disk */
20263082
LP
380 d = opendir("/run/systemd/users");
381 if (!d) {
382 if (errno == ENOENT)
383 return 0;
384
e1427b13 385 return log_error_errno(errno, "Failed to open /run/systemd/users: %m");
20263082
LP
386 }
387
9444b1f2 388 FOREACH_DIRENT(de, d, return -errno) {
20263082 389 User *u;
20263082
LP
390
391 if (!dirent_is_file(de))
392 continue;
393
9444b1f2 394 k = manager_add_user_by_name(m, de->d_name, &u);
20263082 395 if (k < 0) {
da927ba9 396 log_error_errno(k, "Failed to add user by file name %s: %m", de->d_name);
20263082 397
9444b1f2 398 r = k;
20263082
LP
399 continue;
400 }
401
9444b1f2
LP
402 user_add_to_gc_queue(u);
403
20263082
LP
404 k = user_load(u);
405 if (k < 0)
406 r = k;
407 }
408
20263082
LP
409 return r;
410}
411
aed24c4c
FB
412static int manager_attach_fds(Manager *m) {
413 _cleanup_strv_free_ char **fdnames = NULL;
414 int n, i, fd;
415
416 /* Upon restart, PID1 will send us back all fds of session devices
417 * that we previously opened. Each file descriptor is associated
418 * with a given session. The session ids are passed through FDNAMES. */
419
420 n = sd_listen_fds_with_names(true, &fdnames);
421 if (n <= 0)
422 return n;
423
424 for (i = 0; i < n; i++) {
425 struct stat st;
426 SessionDevice *sd;
427 Session *s;
428 char *id;
429
430 fd = SD_LISTEN_FDS_START + i;
431
432 id = startswith(fdnames[i], "session-");
433 if (!id)
434 continue;
435
436 s = hashmap_get(m->sessions, id);
437 if (!s) {
438 /* If the session doesn't exist anymore, the associated session
439 * device attached to this fd doesn't either. Let's simply close
440 * this fd. */
441 log_debug("Failed to attach fd for unknown session: %s", id);
442 close_nointr(fd);
443 continue;
444 }
445
446 if (fstat(fd, &st) < 0) {
447 /* The device is allowed to go away at a random point, in which
448 * case fstat failing is expected. */
449 log_debug_errno(errno, "Failed to stat device fd for session %s: %m", id);
450 close_nointr(fd);
451 continue;
452 }
453
454 sd = hashmap_get(s->devices, &st.st_rdev);
455 if (!sd) {
456 /* Weird we got an fd for a session device which wasn't
457 * recorded in the session state file... */
458 log_warning("Got fd for missing session device [%u:%u] in session %s",
459 major(st.st_rdev), minor(st.st_rdev), s->id);
460 close_nointr(fd);
461 continue;
462 }
463
464 log_debug("Attaching fd to session device [%u:%u] for session %s",
465 major(st.st_rdev), minor(st.st_rdev), s->id);
466
467 session_device_attach_fd(sd, fd, s->was_active);
468 }
469
470 return 0;
471}
472
9588bc32 473static int manager_enumerate_sessions(Manager *m) {
9444b1f2
LP
474 _cleanup_closedir_ DIR *d = NULL;
475 struct dirent *de;
aed24c4c 476 int r = 0, k;
20263082 477
9444b1f2
LP
478 assert(m);
479
480 /* Read in session data stored on disk */
481 d = opendir("/run/systemd/sessions");
482 if (!d) {
483 if (errno == ENOENT)
484 return 0;
485
e1427b13 486 return log_error_errno(errno, "Failed to open /run/systemd/sessions: %m");
9444b1f2
LP
487 }
488
489 FOREACH_DIRENT(de, d, return -errno) {
490 struct Session *s;
20263082 491
9444b1f2 492 if (!dirent_is_file(de))
14c3baca
LP
493 continue;
494
4b549144
ZJS
495 if (!session_id_valid(de->d_name)) {
496 log_warning("Invalid session file name '%s', ignoring.", de->d_name);
497 r = -EINVAL;
498 continue;
499 }
500
9444b1f2 501 k = manager_add_session(m, de->d_name, &s);
20263082 502 if (k < 0) {
da927ba9 503 log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
20263082
LP
504 r = k;
505 continue;
506 }
507
9444b1f2 508 session_add_to_gc_queue(s);
20263082 509
9444b1f2 510 k = session_load(s);
20263082
LP
511 if (k < 0)
512 r = k;
513 }
514
aed24c4c
FB
515 /* We might be restarted and PID1 could have sent us back the
516 * session device fds we previously saved. */
517 k = manager_attach_fds(m);
518 if (k < 0)
519 log_warning_errno(k, "Failed to reattach session device fds: %m");
520
20263082
LP
521 return r;
522}
523
9588bc32 524static int manager_enumerate_inhibitors(Manager *m) {
9444b1f2 525 _cleanup_closedir_ DIR *d = NULL;
20263082
LP
526 struct dirent *de;
527 int r = 0;
528
529 assert(m);
530
9444b1f2 531 d = opendir("/run/systemd/inhibit");
20263082
LP
532 if (!d) {
533 if (errno == ENOENT)
534 return 0;
535
e1427b13 536 return log_error_errno(errno, "Failed to open /run/systemd/inhibit: %m");
20263082
LP
537 }
538
9444b1f2 539 FOREACH_DIRENT(de, d, return -errno) {
20263082 540 int k;
9444b1f2 541 Inhibitor *i;
20263082
LP
542
543 if (!dirent_is_file(de))
544 continue;
545
9444b1f2
LP
546 k = manager_add_inhibitor(m, de->d_name, &i);
547 if (k < 0) {
da927ba9 548 log_notice_errno(k, "Couldn't add inhibitor %s: %m", de->d_name);
9444b1f2 549 r = k;
20263082
LP
550 continue;
551 }
552
9444b1f2 553 k = inhibitor_load(i);
20263082
LP
554 if (k < 0)
555 r = k;
556 }
557
20263082
LP
558 return r;
559}
560
cc377381 561static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
7b77ed8c 562 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
cc377381 563 Manager *m = userdata;
20263082
LP
564
565 assert(m);
566
30ed21ce 567 d = udev_monitor_receive_device(m->udev_seat_monitor);
20263082
LP
568 if (!d)
569 return -ENOMEM;
570
7b77ed8c
LP
571 manager_process_seat_device(m, d);
572 return 0;
30ed21ce
LP
573}
574
cc377381 575static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
7b77ed8c 576 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
cc377381 577 Manager *m = userdata;
718d006a
DH
578
579 assert(m);
580
581 d = udev_monitor_receive_device(m->udev_device_monitor);
582 if (!d)
583 return -ENOMEM;
584
7b77ed8c
LP
585 manager_process_seat_device(m, d);
586 return 0;
718d006a
DH
587}
588
cc377381 589static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
7b77ed8c 590 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
cc377381 591 Manager *m = userdata;
30ed21ce
LP
592 const char *name;
593
594 assert(m);
595
596 d = udev_monitor_receive_device(m->udev_vcsa_monitor);
597 if (!d)
598 return -ENOMEM;
599
600 name = udev_device_get_sysname(d);
601
602 /* Whenever a VCSA device is removed try to reallocate our
603 * VTs, to make sure our auto VTs never go away. */
604
605 if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
7b77ed8c 606 seat_preallocate_vts(m->seat0);
30ed21ce 607
7b77ed8c 608 return 0;
20263082
LP
609}
610
cc377381 611static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
7b77ed8c 612 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
cc377381 613 Manager *m = userdata;
069cfc85
LP
614
615 assert(m);
616
617 d = udev_monitor_receive_device(m->udev_button_monitor);
618 if (!d)
619 return -ENOMEM;
620
7b77ed8c
LP
621 manager_process_button_device(m, d);
622 return 0;
069cfc85
LP
623}
624
cc377381
LP
625static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
626 Manager *m = userdata;
627
20263082 628 assert(m);
92432fcc 629 assert(m->seat0);
cc377381 630 assert(m->console_active_fd == fd);
20263082 631
92432fcc 632 seat_read_active_vt(m->seat0);
20263082
LP
633 return 0;
634}
635
98a77df5
LP
636static int manager_reserve_vt(Manager *m) {
637 _cleanup_free_ char *p = NULL;
638
639 assert(m);
640
641 if (m->reserve_vt <= 0)
642 return 0;
643
644 if (asprintf(&p, "/dev/tty%u", m->reserve_vt) < 0)
645 return log_oom();
646
647 m->reserve_vt_fd = open(p, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
648 if (m->reserve_vt_fd < 0) {
d4d882e5
LP
649
650 /* Don't complain on VT-less systems */
651 if (errno != ENOENT)
56f64d95 652 log_warning_errno(errno, "Failed to pin reserved VT: %m");
98a77df5
LP
653 return -errno;
654 }
655
656 return 0;
657}
658
cc377381 659static int manager_connect_bus(Manager *m) {
4afd3348 660 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
cc377381 661 int r;
31b79c2b 662
cc377381
LP
663 assert(m);
664 assert(!m->bus);
31b79c2b 665
76b54375 666 r = sd_bus_default_system(&m->bus);
f647962d
MS
667 if (r < 0)
668 return log_error_errno(r, "Failed to connect to system bus: %m");
31b79c2b 669
19befb2d 670 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", manager_vtable, m);
f647962d
MS
671 if (r < 0)
672 return log_error_errno(r, "Failed to add manager object vtable: %m");
f8e2fb7b 673
19befb2d 674 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/seat", "org.freedesktop.login1.Seat", seat_vtable, seat_object_find, m);
f647962d
MS
675 if (r < 0)
676 return log_error_errno(r, "Failed to add seat object vtable: %m");
069cfc85 677
19befb2d 678 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/seat", seat_node_enumerator, m);
f647962d
MS
679 if (r < 0)
680 return log_error_errno(r, "Failed to add seat enumerator: %m");
20263082 681
19befb2d 682 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/session", "org.freedesktop.login1.Session", session_vtable, session_object_find, m);
f647962d
MS
683 if (r < 0)
684 return log_error_errno(r, "Failed to add session object vtable: %m");
20263082 685
19befb2d 686 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/session", session_node_enumerator, m);
f647962d
MS
687 if (r < 0)
688 return log_error_errno(r, "Failed to add session enumerator: %m");
20263082 689
19befb2d 690 r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/login1/user", "org.freedesktop.login1.User", user_vtable, user_object_find, m);
f647962d
MS
691 if (r < 0)
692 return log_error_errno(r, "Failed to add user object vtable: %m");
20263082 693
19befb2d 694 r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/login1/user", user_node_enumerator, m);
f647962d
MS
695 if (r < 0)
696 return log_error_errno(r, "Failed to add user enumerator: %m");
20263082 697
cc377381 698 r = sd_bus_add_match(m->bus,
19befb2d 699 NULL,
cc377381
LP
700 "type='signal',"
701 "sender='org.freedesktop.systemd1',"
702 "interface='org.freedesktop.systemd1.Manager',"
703 "member='JobRemoved',"
704 "path='/org/freedesktop/systemd1'",
705 match_job_removed, m);
f647962d
MS
706 if (r < 0)
707 return log_error_errno(r, "Failed to add match for JobRemoved: %m");
943aca8e 708
cc377381 709 r = sd_bus_add_match(m->bus,
19befb2d 710 NULL,
cc377381
LP
711 "type='signal',"
712 "sender='org.freedesktop.systemd1',"
713 "interface='org.freedesktop.systemd1.Manager',"
714 "member='UnitRemoved',"
715 "path='/org/freedesktop/systemd1'",
716 match_unit_removed, m);
f647962d
MS
717 if (r < 0)
718 return log_error_errno(r, "Failed to add match for UnitRemoved: %m");
fb6becb4 719
cc377381 720 r = sd_bus_add_match(m->bus,
19befb2d 721 NULL,
cc377381
LP
722 "type='signal',"
723 "sender='org.freedesktop.systemd1',"
724 "interface='org.freedesktop.DBus.Properties',"
725 "member='PropertiesChanged'",
726 match_properties_changed, m);
f647962d
MS
727 if (r < 0)
728 return log_error_errno(r, "Failed to add match for PropertiesChanged: %m");
fb6becb4 729
cc377381 730 r = sd_bus_add_match(m->bus,
19befb2d 731 NULL,
cc377381
LP
732 "type='signal',"
733 "sender='org.freedesktop.systemd1',"
734 "interface='org.freedesktop.systemd1.Manager',"
735 "member='Reloading',"
736 "path='/org/freedesktop/systemd1'",
737 match_reloading, m);
f647962d
MS
738 if (r < 0)
739 return log_error_errno(r, "Failed to add match for Reloading: %m");
6797c324 740
cc377381 741 r = sd_bus_call_method(
fb6becb4
LP
742 m->bus,
743 "org.freedesktop.systemd1",
744 "/org/freedesktop/systemd1",
745 "org.freedesktop.systemd1.Manager",
746 "Subscribe",
fb6becb4 747 &error,
cc377381 748 NULL, NULL);
fb6becb4 749 if (r < 0) {
cc377381
LP
750 log_error("Failed to enable subscription: %s", bus_error_message(&error, r));
751 return r;
20263082
LP
752 }
753
5bb658a1 754 r = sd_bus_request_name(m->bus, "org.freedesktop.login1", 0);
f647962d
MS
755 if (r < 0)
756 return log_error_errno(r, "Failed to register name: %m");
bafd4449 757
e11544a8 758 r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL);
f647962d
MS
759 if (r < 0)
760 return log_error_errno(r, "Failed to attach bus to event loop: %m");
20263082 761
20263082 762 return 0;
20263082
LP
763}
764
92683ad2
DH
765static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo *si, void *data) {
766 Manager *m = data;
767 Session *active, *iter;
768
769 /*
770 * We got a VT-switch signal and we have to acknowledge it immediately.
771 * Preferably, we'd just use m->seat0->active->vtfd, but unfortunately,
772 * old user-space might run multiple sessions on a single VT, *sigh*.
773 * Therefore, we have to iterate all sessions and find one with a vtfd
774 * on the requested VT.
775 * As only VTs with active controllers have VT_PROCESS set, our current
776 * notion of the active VT might be wrong (for instance if the switch
777 * happens while we setup VT_PROCESS). Therefore, read the current VT
778 * first and then use s->active->vtnr as reference. Note that this is
779 * not racy, as no further VT-switch can happen as long as we're in
780 * synchronous VT_PROCESS mode.
781 */
782
783 assert(m->seat0);
784 seat_read_active_vt(m->seat0);
785
786 active = m->seat0->active;
787 if (!active || active->vtnr < 1) {
788 log_warning("Received VT_PROCESS signal without a registered session on that VT.");
789 return 0;
790 }
791
792 if (active->vtfd >= 0) {
2ec3ff66 793 session_leave_vt(active);
92683ad2
DH
794 } else {
795 LIST_FOREACH(sessions_by_seat, iter, m->seat0->sessions) {
796 if (iter->vtnr == active->vtnr && iter->vtfd >= 0) {
2ec3ff66 797 session_leave_vt(iter);
92683ad2
DH
798 break;
799 }
800 }
801 }
802
803 return 0;
804}
805
20263082 806static int manager_connect_console(Manager *m) {
cc377381 807 int r;
20263082
LP
808
809 assert(m);
810 assert(m->console_active_fd < 0);
811
74afee9c
LP
812 /* On certain architectures (S390 and Xen, and containers),
813 /dev/tty0 does not exist, so don't fail if we can't open
814 it. */
cc377381 815 if (access("/dev/tty0", F_OK) < 0)
74afee9c 816 return 0;
74afee9c 817
20263082
LP
818 m->console_active_fd = open("/sys/class/tty/tty0/active", O_RDONLY|O_NOCTTY|O_CLOEXEC);
819 if (m->console_active_fd < 0) {
cdc564d2
MS
820
821 /* On some systems the device node /dev/tty0 may exist
822 * even though /sys/class/tty/tty0 does not. */
823 if (errno == ENOENT)
824 return 0;
825
e1427b13 826 return log_error_errno(errno, "Failed to open /sys/class/tty/tty0/active: %m");
20263082
LP
827 }
828
151b9b96 829 r = sd_event_add_io(m->event, &m->console_active_event_source, m->console_active_fd, 0, manager_dispatch_console, m);
cc377381
LP
830 if (r < 0) {
831 log_error("Failed to watch foreground console");
832 return r;
833 }
20263082 834
92683ad2
DH
835 /*
836 * SIGRTMIN is used as global VT-release signal, SIGRTMIN + 1 is used
837 * as VT-acquire signal. We ignore any acquire-events (yes, we still
838 * have to provide a valid signal-number for it!) and acknowledge all
839 * release events immediately.
840 */
841
842 if (SIGRTMIN + 1 > SIGRTMAX) {
843 log_error("Not enough real-time signals available: %u-%u", SIGRTMIN, SIGRTMAX);
844 return -EINVAL;
845 }
846
72c0a2c2
LP
847 assert_se(ignore_signals(SIGRTMIN + 1, -1) >= 0);
848 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGRTMIN, -1) >= 0);
92683ad2
DH
849
850 r = sd_event_add_signal(m->event, NULL, SIGRTMIN, manager_vt_switch, m);
851 if (r < 0)
852 return r;
853
20263082
LP
854 return 0;
855}
856
857static int manager_connect_udev(Manager *m) {
14c3baca 858 int r;
20263082
LP
859
860 assert(m);
30ed21ce 861 assert(!m->udev_seat_monitor);
718d006a 862 assert(!m->udev_device_monitor);
30ed21ce 863 assert(!m->udev_vcsa_monitor);
069cfc85 864 assert(!m->udev_button_monitor);
20263082 865
30ed21ce
LP
866 m->udev_seat_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
867 if (!m->udev_seat_monitor)
20263082
LP
868 return -ENOMEM;
869
2d96536d 870 r = udev_monitor_filter_add_match_tag(m->udev_seat_monitor, "master-of-seat");
14c3baca
LP
871 if (r < 0)
872 return r;
20263082 873
30ed21ce 874 r = udev_monitor_enable_receiving(m->udev_seat_monitor);
14c3baca
LP
875 if (r < 0)
876 return r;
20263082 877
151b9b96 878 r = sd_event_add_io(m->event, &m->udev_seat_event_source, udev_monitor_get_fd(m->udev_seat_monitor), EPOLLIN, manager_dispatch_seat_udev, m);
cc377381
LP
879 if (r < 0)
880 return r;
069cfc85 881
718d006a
DH
882 m->udev_device_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
883 if (!m->udev_device_monitor)
884 return -ENOMEM;
885
886 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "input", NULL);
887 if (r < 0)
888 return r;
889
890 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "graphics", NULL);
891 if (r < 0)
892 return r;
893
894 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_device_monitor, "drm", NULL);
895 if (r < 0)
896 return r;
897
898 r = udev_monitor_enable_receiving(m->udev_device_monitor);
899 if (r < 0)
900 return r;
901
151b9b96 902 r = sd_event_add_io(m->event, &m->udev_device_event_source, udev_monitor_get_fd(m->udev_device_monitor), EPOLLIN, manager_dispatch_device_udev, m);
cc377381
LP
903 if (r < 0)
904 return r;
718d006a 905
6de0e0e5 906 /* Don't watch keys if nobody cares */
beaafb2e 907 if (m->handle_power_key != HANDLE_IGNORE ||
8e7fd6ad
LP
908 m->handle_suspend_key != HANDLE_IGNORE ||
909 m->handle_hibernate_key != HANDLE_IGNORE ||
3c56cab4
BW
910 m->handle_lid_switch != HANDLE_IGNORE ||
911 m->handle_lid_switch_docked != HANDLE_IGNORE) {
069cfc85 912
6de0e0e5
LP
913 m->udev_button_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
914 if (!m->udev_button_monitor)
915 return -ENOMEM;
069cfc85 916
6de0e0e5
LP
917 r = udev_monitor_filter_add_match_tag(m->udev_button_monitor, "power-switch");
918 if (r < 0)
919 return r;
069cfc85 920
6de0e0e5
LP
921 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_button_monitor, "input", NULL);
922 if (r < 0)
923 return r;
069cfc85 924
6de0e0e5
LP
925 r = udev_monitor_enable_receiving(m->udev_button_monitor);
926 if (r < 0)
927 return r;
069cfc85 928
151b9b96 929 r = sd_event_add_io(m->event, &m->udev_button_event_source, udev_monitor_get_fd(m->udev_button_monitor), EPOLLIN, manager_dispatch_button_udev, m);
cc377381
LP
930 if (r < 0)
931 return r;
6de0e0e5 932 }
069cfc85 933
976c088a 934 /* Don't bother watching VCSA devices, if nobody cares */
6de0e0e5 935 if (m->n_autovts > 0 && m->console_active_fd >= 0) {
30ed21ce 936
6de0e0e5
LP
937 m->udev_vcsa_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
938 if (!m->udev_vcsa_monitor)
939 return -ENOMEM;
30ed21ce 940
6de0e0e5
LP
941 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_vcsa_monitor, "vc", NULL);
942 if (r < 0)
943 return r;
30ed21ce 944
6de0e0e5
LP
945 r = udev_monitor_enable_receiving(m->udev_vcsa_monitor);
946 if (r < 0)
947 return r;
30ed21ce 948
151b9b96 949 r = sd_event_add_io(m->event, &m->udev_vcsa_event_source, udev_monitor_get_fd(m->udev_vcsa_monitor), EPOLLIN, manager_dispatch_vcsa_udev, m);
cc377381
LP
950 if (r < 0)
951 return r;
6de0e0e5 952 }
20263082
LP
953
954 return 0;
955}
956
905f0a39 957static void manager_gc(Manager *m, bool drop_not_started) {
14c3baca
LP
958 Seat *seat;
959 Session *session;
960 User *user;
961
962 assert(m);
963
964 while ((seat = m->seat_gc_queue)) {
71fda00f 965 LIST_REMOVE(gc_queue, m->seat_gc_queue, seat);
14c3baca
LP
966 seat->in_gc_queue = false;
967
cc377381 968 if (!seat_check_gc(seat, drop_not_started)) {
9bb69af4 969 seat_stop(seat, false);
14c3baca
LP
970 seat_free(seat);
971 }
972 }
973
974 while ((session = m->session_gc_queue)) {
71fda00f 975 LIST_REMOVE(gc_queue, m->session_gc_queue, session);
14c3baca
LP
976 session->in_gc_queue = false;
977
5f41d1f1
LP
978 /* First, if we are not closing yet, initiate stopping */
979 if (!session_check_gc(session, drop_not_started) &&
980 session_get_state(session) != SESSION_CLOSING)
9bb69af4 981 session_stop(session, false);
5f41d1f1 982
491ac9f2
LP
983 /* Normally, this should make the session referenced
984 * again, if it doesn't then let's get rid of it
5f41d1f1
LP
985 * immediately */
986 if (!session_check_gc(session, drop_not_started)) {
405e0255 987 session_finalize(session);
14c3baca
LP
988 session_free(session);
989 }
990 }
991
992 while ((user = m->user_gc_queue)) {
71fda00f 993 LIST_REMOVE(gc_queue, m->user_gc_queue, user);
14c3baca
LP
994 user->in_gc_queue = false;
995
b58b227a
DH
996 /* First step: queue stop jobs */
997 if (!user_check_gc(user, drop_not_started))
9bb69af4 998 user_stop(user, false);
5f41d1f1 999
b58b227a 1000 /* Second step: finalize user */
5f41d1f1 1001 if (!user_check_gc(user, drop_not_started)) {
405e0255 1002 user_finalize(user);
14c3baca
LP
1003 user_free(user);
1004 }
1005 }
1006}
1007
cc377381
LP
1008static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *userdata) {
1009 Manager *m = userdata;
23406ce5 1010 struct dual_timestamp since;
cc377381 1011 usec_t n, elapse;
23406ce5 1012 int r;
23406ce5
LP
1013
1014 assert(m);
1015
1016 if (m->idle_action == HANDLE_IGNORE ||
cc377381
LP
1017 m->idle_action_usec <= 0)
1018 return 0;
23406ce5 1019
23406ce5
LP
1020 n = now(CLOCK_MONOTONIC);
1021
1022 r = manager_get_idle_hint(m, &since);
1023 if (r <= 0)
39ccc87c 1024 /* Not idle. Let's check if after a timeout it might be idle then. */
cc377381 1025 elapse = n + m->idle_action_usec;
23406ce5
LP
1026 else {
1027 /* Idle! Let's see if it's time to do something, or if
1028 * we shall sleep for longer. */
1029
1030 if (n >= since.monotonic + m->idle_action_usec &&
1031 (m->idle_action_not_before_usec <= 0 || n >= m->idle_action_not_before_usec + m->idle_action_usec)) {
1032 log_info("System idle. Taking action.");
1033
1034 manager_handle_action(m, 0, m->idle_action, false, false);
1035 m->idle_action_not_before_usec = n;
1036 }
1037
cc377381 1038 elapse = MAX(since.monotonic, m->idle_action_not_before_usec) + m->idle_action_usec;
23406ce5
LP
1039 }
1040
cc377381 1041 if (!m->idle_action_event_source) {
23406ce5 1042
6a0f1f6d
LP
1043 r = sd_event_add_time(
1044 m->event,
1045 &m->idle_action_event_source,
1046 CLOCK_MONOTONIC,
1047 elapse, USEC_PER_SEC*30,
1048 manager_dispatch_idle_action, m);
f647962d
MS
1049 if (r < 0)
1050 return log_error_errno(r, "Failed to add idle event source: %m");
23406ce5 1051
718db961 1052 r = sd_event_source_set_priority(m->idle_action_event_source, SD_EVENT_PRIORITY_IDLE+10);
f647962d
MS
1053 if (r < 0)
1054 return log_error_errno(r, "Failed to set idle event source priority: %m");
cc377381
LP
1055 } else {
1056 r = sd_event_source_set_time(m->idle_action_event_source, elapse);
f647962d
MS
1057 if (r < 0)
1058 return log_error_errno(r, "Failed to set idle event timer: %m");
23406ce5 1059
cc377381 1060 r = sd_event_source_set_enabled(m->idle_action_event_source, SD_EVENT_ONESHOT);
f647962d
MS
1061 if (r < 0)
1062 return log_error_errno(r, "Failed to enable idle event timer: %m");
23406ce5
LP
1063 }
1064
1065 return 0;
23406ce5 1066}
cc377381 1067
a2ed7077
ZJS
1068static int manager_parse_config_file(Manager *m) {
1069 assert(m);
1070
43688c49 1071 return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf",
da412854
YW
1072 CONF_PATHS_NULSTR("systemd/logind.conf.d"),
1073 "Login\0",
1074 config_item_perf_lookup, logind_gperf_lookup,
1075 false, m);
a2ed7077
ZJS
1076}
1077
1078static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
1079 Manager *m = userdata;
1080 int r;
1081
1082 manager_reset_config(m);
1083 r = manager_parse_config_file(m);
1084 if (r < 0)
1085 log_warning_errno(r, "Failed to parse config file, using defaults: %m");
1086 else
1087 log_info("Config file reloaded.");
1088
1089 return 0;
1090}
1091
905f0a39 1092static int manager_startup(Manager *m) {
20263082 1093 int r;
14c3baca
LP
1094 Seat *seat;
1095 Session *session;
1096 User *user;
ed4ba7e4 1097 Button *button;
f8e2fb7b 1098 Inhibitor *inhibitor;
14c3baca 1099 Iterator i;
20263082
LP
1100
1101 assert(m);
20263082 1102
a2ed7077
ZJS
1103 assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGHUP, -1) >= 0);
1104
1105 r = sd_event_add_signal(m->event, NULL, SIGHUP, manager_dispatch_reload_signal, m);
1106 if (r < 0)
1107 return log_error_errno(r, "Failed to register SIGHUP handler: %m");
1108
976c088a
LP
1109 /* Connect to console */
1110 r = manager_connect_console(m);
20263082
LP
1111 if (r < 0)
1112 return r;
1113
976c088a
LP
1114 /* Connect to udev */
1115 r = manager_connect_udev(m);
f647962d
MS
1116 if (r < 0)
1117 return log_error_errno(r, "Failed to create udev watchers: %m");
20263082
LP
1118
1119 /* Connect to the bus */
1120 r = manager_connect_bus(m);
1121 if (r < 0)
1122 return r;
1123
14c3baca 1124 /* Instantiate magic seat 0 */
92432fcc 1125 r = manager_add_seat(m, "seat0", &m->seat0);
f647962d
MS
1126 if (r < 0)
1127 return log_error_errno(r, "Failed to add seat0: %m");
14c3baca 1128
9d10cbee 1129 r = manager_set_lid_switch_ignore(m, 0 + m->holdoff_timeout_usec);
f9cd6be1 1130 if (r < 0)
da927ba9 1131 log_warning_errno(r, "Failed to set up lid switch ignore event source: %m");
f9cd6be1 1132
20263082 1133 /* Deserialize state */
042f5988
ZJS
1134 r = manager_enumerate_devices(m);
1135 if (r < 0)
da927ba9 1136 log_warning_errno(r, "Device enumeration failed: %m");
042f5988
ZJS
1137
1138 r = manager_enumerate_seats(m);
1139 if (r < 0)
da927ba9 1140 log_warning_errno(r, "Seat enumeration failed: %m");
042f5988
ZJS
1141
1142 r = manager_enumerate_users(m);
1143 if (r < 0)
da927ba9 1144 log_warning_errno(r, "User enumeration failed: %m");
042f5988
ZJS
1145
1146 r = manager_enumerate_sessions(m);
1147 if (r < 0)
da927ba9 1148 log_warning_errno(r, "Session enumeration failed: %m");
042f5988
ZJS
1149
1150 r = manager_enumerate_inhibitors(m);
1151 if (r < 0)
da927ba9 1152 log_warning_errno(r, "Inhibitor enumeration failed: %m");
042f5988
ZJS
1153
1154 r = manager_enumerate_buttons(m);
1155 if (r < 0)
da927ba9 1156 log_warning_errno(r, "Button enumeration failed: %m");
20263082 1157
4a4b033f
LP
1158 /* Remove stale objects before we start them */
1159 manager_gc(m, false);
1160
98a77df5
LP
1161 /* Reserve the special reserved VT */
1162 manager_reserve_vt(m);
1163
14c3baca
LP
1164 /* And start everything */
1165 HASHMAP_FOREACH(seat, m->seats, i)
1166 seat_start(seat);
1167
1168 HASHMAP_FOREACH(user, m->users, i)
1169 user_start(user);
1170
1171 HASHMAP_FOREACH(session, m->sessions, i)
1172 session_start(session);
20263082 1173
f8e2fb7b
LP
1174 HASHMAP_FOREACH(inhibitor, m->inhibitors, i)
1175 inhibitor_start(inhibitor);
1176
ed4ba7e4 1177 HASHMAP_FOREACH(button, m->buttons, i)
2d62c530 1178 button_check_switches(button);
ed4ba7e4 1179
cc377381 1180 manager_dispatch_idle_action(NULL, 0, m);
23406ce5 1181
20263082
LP
1182 return 0;
1183}
1184
905f0a39 1185static int manager_run(Manager *m) {
cc377381
LP
1186 int r;
1187
20263082
LP
1188 assert(m);
1189
1190 for (;;) {
cc377381
LP
1191 r = sd_event_get_state(m->event);
1192 if (r < 0)
1193 return r;
1194 if (r == SD_EVENT_FINISHED)
1195 return 0;
20263082 1196
4a4b033f 1197 manager_gc(m, true);
14c3baca 1198
418b22b8
DM
1199 r = manager_dispatch_delayed(m, false);
1200 if (r < 0)
1201 return r;
1202 if (r > 0)
1203 continue;
1204
c0f32805 1205 r = sd_event_run(m->event, (uint64_t) -1);
cc377381
LP
1206 if (r < 0)
1207 return r;
20263082 1208 }
20263082
LP
1209}
1210
1211int main(int argc, char *argv[]) {
1212 Manager *m = NULL;
5eda94dd 1213 int r;
20263082
LP
1214
1215 log_set_target(LOG_TARGET_AUTO);
3eff4208 1216 log_set_facility(LOG_AUTH);
20263082
LP
1217 log_parse_environment();
1218 log_open();
1219
4c12626c
LP
1220 umask(0022);
1221
20263082
LP
1222 if (argc != 1) {
1223 log_error("This program takes no arguments.");
1224 r = -EINVAL;
1225 goto finish;
1226 }
1227
c3dacc8b 1228 r = mac_selinux_init();
4b51966c
NI
1229 if (r < 0) {
1230 log_error_errno(r, "Could not initialize labelling: %m");
1231 goto finish;
1232 }
1233
bb27ff66
LP
1234 /* Always create the directories people can create inotify
1235 * watches in. Note that some applications might check for the
ab06eef8 1236 * existence of /run/systemd/seats/ to determine whether
bb27ff66
LP
1237 * logind is available, so please always make sure this check
1238 * stays in. */
1239 mkdir_label("/run/systemd/seats", 0755);
1240 mkdir_label("/run/systemd/users", 0755);
1241 mkdir_label("/run/systemd/sessions", 0755);
1242
20263082
LP
1243 m = manager_new();
1244 if (!m) {
0d0f0c50 1245 r = log_oom();
20263082
LP
1246 goto finish;
1247 }
1248
193197e8
LP
1249 manager_parse_config_file(m);
1250
20263082
LP
1251 r = manager_startup(m);
1252 if (r < 0) {
da927ba9 1253 log_error_errno(r, "Failed to fully start up daemon: %m");
20263082
LP
1254 goto finish;
1255 }
1256
df0ff127 1257 log_debug("systemd-logind running as pid "PID_FMT, getpid_cached());
e6960940
LP
1258
1259 sd_notify(false,
1260 "READY=1\n"
1261 "STATUS=Processing requests...");
1262
20263082
LP
1263 r = manager_run(m);
1264
df0ff127 1265 log_debug("systemd-logind stopped as pid "PID_FMT, getpid_cached());
e6960940 1266
20263082 1267finish:
e6960940 1268 sd_notify(false,
af4ec430 1269 "STOPPING=1\n"
e6960940
LP
1270 "STATUS=Shutting down...");
1271
3e044c49 1272 manager_free(m);
20263082
LP
1273
1274 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1275}