]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/logind-core.c
pam_systemd: always check if session is busy
[thirdparty/systemd.git] / src / login / logind-core.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <fcntl.h>
4 #include <sys/ioctl.h>
5 #include <sys/types.h>
6 #include <linux/vt.h>
7
8 #include "sd-device.h"
9
10 #include "alloc-util.h"
11 #include "battery-util.h"
12 #include "bus-error.h"
13 #include "bus-locator.h"
14 #include "bus-util.h"
15 #include "cgroup-util.h"
16 #include "conf-parser.h"
17 #include "device-util.h"
18 #include "efi-loader.h"
19 #include "errno-util.h"
20 #include "fd-util.h"
21 #include "limits-util.h"
22 #include "logind.h"
23 #include "parse-util.h"
24 #include "path-util.h"
25 #include "process-util.h"
26 #include "stdio-util.h"
27 #include "strv.h"
28 #include "terminal-util.h"
29 #include "udev-util.h"
30 #include "user-util.h"
31 #include "userdb.h"
32 #include "utmp-wtmp.h"
33
34 void manager_reset_config(Manager *m) {
35 assert(m);
36
37 m->n_autovts = 6;
38 m->reserve_vt = 6;
39 m->remove_ipc = true;
40 m->inhibit_delay_max = 5 * USEC_PER_SEC;
41 m->user_stop_delay = 10 * USEC_PER_SEC;
42
43 m->handle_action_sleep_mask = HANDLE_ACTION_SLEEP_MASK_DEFAULT;
44
45 m->handle_power_key = HANDLE_POWEROFF;
46 m->handle_power_key_long_press = HANDLE_IGNORE;
47 m->handle_reboot_key = HANDLE_REBOOT;
48 m->handle_reboot_key_long_press = HANDLE_POWEROFF;
49 m->handle_suspend_key = HANDLE_SUSPEND;
50 m->handle_suspend_key_long_press = HANDLE_HIBERNATE;
51 m->handle_hibernate_key = HANDLE_HIBERNATE;
52 m->handle_hibernate_key_long_press = HANDLE_IGNORE;
53
54 m->handle_lid_switch = HANDLE_SUSPEND;
55 m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
56 m->handle_lid_switch_docked = HANDLE_IGNORE;
57
58 m->power_key_ignore_inhibited = false;
59 m->suspend_key_ignore_inhibited = false;
60 m->hibernate_key_ignore_inhibited = false;
61 m->lid_switch_ignore_inhibited = true;
62 m->reboot_key_ignore_inhibited = false;
63
64 m->holdoff_timeout_usec = 30 * USEC_PER_SEC;
65
66 m->idle_action_usec = 30 * USEC_PER_MINUTE;
67 m->idle_action = HANDLE_IGNORE;
68
69 m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
70 m->runtime_dir_inodes = DIV_ROUND_UP(m->runtime_dir_size, 4096); /* 4k per inode */
71 m->sessions_max = 8192;
72 m->inhibitors_max = 8192;
73
74 m->kill_user_processes = KILL_USER_PROCESSES;
75
76 m->kill_only_users = strv_free(m->kill_only_users);
77 m->kill_exclude_users = strv_free(m->kill_exclude_users);
78
79 m->stop_idle_session_usec = USEC_INFINITY;
80 }
81
82 int manager_parse_config_file(Manager *m) {
83 assert(m);
84
85 return config_parse_config_file("logind.conf", "Login\0",
86 config_item_perf_lookup, logind_gperf_lookup,
87 CONFIG_PARSE_WARN, m);
88 }
89
90 int manager_add_device(Manager *m, const char *sysfs, bool master, Device **ret_device) {
91 Device *d;
92
93 assert(m);
94 assert(sysfs);
95
96 d = hashmap_get(m->devices, sysfs);
97 if (d)
98 /* we support adding master-flags, but not removing them */
99 d->master = d->master || master;
100 else {
101 d = device_new(m, sysfs, master);
102 if (!d)
103 return -ENOMEM;
104 }
105
106 if (ret_device)
107 *ret_device = d;
108
109 return 0;
110 }
111
112 int manager_add_seat(Manager *m, const char *id, Seat **ret_seat) {
113 Seat *s;
114 int r;
115
116 assert(m);
117 assert(id);
118
119 s = hashmap_get(m->seats, id);
120 if (!s) {
121 r = seat_new(&s, m, id);
122 if (r < 0)
123 return r;
124 }
125
126 if (ret_seat)
127 *ret_seat = s;
128
129 return 0;
130 }
131
132 int manager_add_session(Manager *m, const char *id, Session **ret_session) {
133 Session *s;
134 int r;
135
136 assert(m);
137 assert(id);
138
139 s = hashmap_get(m->sessions, id);
140 if (!s) {
141 r = session_new(&s, m, id);
142 if (r < 0)
143 return r;
144 }
145
146 if (ret_session)
147 *ret_session = s;
148
149 return 0;
150 }
151
152 int manager_add_user(
153 Manager *m,
154 UserRecord *ur,
155 User **ret_user) {
156
157 User *u;
158 int r;
159
160 assert(m);
161 assert(ur);
162
163 u = hashmap_get(m->users, UID_TO_PTR(ur->uid));
164 if (!u) {
165 r = user_new(&u, m, ur);
166 if (r < 0)
167 return r;
168 }
169
170 if (ret_user)
171 *ret_user = u;
172
173 return 0;
174 }
175
176 int manager_add_user_by_name(
177 Manager *m,
178 const char *name,
179 User **ret_user) {
180
181 _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
182 int r;
183
184 assert(m);
185 assert(name);
186
187 r = userdb_by_name(name, USERDB_SUPPRESS_SHADOW, &ur);
188 if (r < 0)
189 return r;
190
191 return manager_add_user(m, ur, ret_user);
192 }
193
194 int manager_add_user_by_uid(
195 Manager *m,
196 uid_t uid,
197 User **ret_user) {
198
199 _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
200 int r;
201
202 assert(m);
203 assert(uid_is_valid(uid));
204
205 r = userdb_by_uid(uid, USERDB_SUPPRESS_SHADOW, &ur);
206 if (r < 0)
207 return r;
208
209 return manager_add_user(m, ur, ret_user);
210 }
211
212 int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret) {
213 Inhibitor *i;
214 int r;
215
216 assert(m);
217 assert(id);
218
219 i = hashmap_get(m->inhibitors, id);
220 if (!i) {
221 r = inhibitor_new(&i, m, id);
222 if (r < 0)
223 return r;
224 }
225
226 if (ret)
227 *ret = i;
228
229 return 0;
230 }
231
232 int manager_add_button(Manager *m, const char *name, Button **ret_button) {
233 Button *b;
234
235 assert(m);
236 assert(name);
237
238 b = hashmap_get(m->buttons, name);
239 if (!b) {
240 b = button_new(m, name);
241 if (!b)
242 return -ENOMEM;
243 }
244
245 if (ret_button)
246 *ret_button = b;
247
248 return 0;
249 }
250
251 int manager_process_seat_device(Manager *m, sd_device *d) {
252 Device *device;
253 int r;
254
255 assert(m);
256
257 if (device_for_action(d, SD_DEVICE_REMOVE) ||
258 sd_device_has_current_tag(d, "seat") <= 0) {
259 const char *syspath;
260
261 r = sd_device_get_syspath(d, &syspath);
262 if (r < 0)
263 return 0;
264
265 device = hashmap_get(m->devices, syspath);
266 if (!device)
267 return 0;
268
269 seat_add_to_gc_queue(device->seat);
270 device_free(device);
271
272 } else {
273 const char *sn, *syspath;
274 bool master;
275 Seat *seat;
276
277 if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn))
278 sn = "seat0";
279
280 if (!seat_name_is_valid(sn)) {
281 log_device_warning(d, "Device with invalid seat name %s found, ignoring.", sn);
282 return 0;
283 }
284
285 seat = hashmap_get(m->seats, sn);
286 master = sd_device_has_current_tag(d, "master-of-seat") > 0;
287
288 /* Ignore non-master devices for unknown seats */
289 if (!master && !seat)
290 return 0;
291
292 r = sd_device_get_syspath(d, &syspath);
293 if (r < 0)
294 return r;
295
296 r = manager_add_device(m, syspath, master, &device);
297 if (r < 0)
298 return r;
299
300 if (!seat) {
301 r = manager_add_seat(m, sn, &seat);
302 if (r < 0) {
303 if (!device->seat)
304 device_free(device);
305
306 return r;
307 }
308 }
309
310 device_attach(device, seat);
311 seat_start(seat);
312 }
313
314 return 0;
315 }
316
317 int manager_process_button_device(Manager *m, sd_device *d) {
318 const char *sysname;
319 Button *b;
320 int r;
321
322 assert(m);
323
324 r = sd_device_get_sysname(d, &sysname);
325 if (r < 0)
326 return r;
327
328 if (device_for_action(d, SD_DEVICE_REMOVE) ||
329 sd_device_has_current_tag(d, "power-switch") <= 0)
330
331 button_free(hashmap_get(m->buttons, sysname));
332
333 else {
334 const char *sn;
335
336 r = manager_add_button(m, sysname, &b);
337 if (r < 0)
338 return r;
339
340 if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn))
341 sn = "seat0";
342
343 button_set_seat(b, sn);
344
345 r = button_open(b);
346 if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
347 * opening the device?) let's close the button again. */
348 button_free(b);
349 }
350
351 return 0;
352 }
353
354 int manager_get_session_by_pidref(Manager *m, const PidRef *pid, Session **ret) {
355 _cleanup_free_ char *unit = NULL;
356 Session *s;
357 int r;
358
359 assert(m);
360
361 if (!pidref_is_set(pid))
362 return -EINVAL;
363
364 s = hashmap_get(m->sessions_by_leader, pid);
365 if (s) {
366 r = pidref_verify(pid);
367 if (r < 0)
368 return r;
369 } else {
370 r = cg_pidref_get_unit(pid, &unit);
371 if (r < 0)
372 return r;
373
374 s = hashmap_get(m->session_units, unit);
375 }
376
377 if (ret)
378 *ret = s;
379
380 return !!s;
381 }
382
383 int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret) {
384 _cleanup_free_ char *unit = NULL;
385 User *u = NULL;
386 int r;
387
388 assert(m);
389
390 if (!pid_is_valid(pid))
391 return -EINVAL;
392
393 r = cg_pid_get_slice(pid, &unit);
394 if (r >= 0)
395 u = hashmap_get(m->user_units, unit);
396
397 if (ret)
398 *ret = u;
399
400 return !!u;
401 }
402
403 int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
404 Session *s;
405 bool idle_hint;
406 dual_timestamp ts = DUAL_TIMESTAMP_NULL;
407
408 assert(m);
409
410 idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0, NULL);
411
412 HASHMAP_FOREACH(s, m->sessions) {
413 dual_timestamp k;
414 int ih;
415
416 if (!SESSION_CLASS_CAN_IDLE(s->class))
417 continue;
418
419 ih = session_get_idle_hint(s, &k);
420 if (ih < 0)
421 return ih;
422
423 if (!ih) {
424 if (!idle_hint) {
425 if (k.monotonic < ts.monotonic)
426 ts = k;
427 } else {
428 idle_hint = false;
429 ts = k;
430 }
431 } else if (idle_hint) {
432
433 if (k.monotonic > ts.monotonic)
434 ts = k;
435 }
436 }
437
438 if (t)
439 *t = ts;
440
441 return idle_hint;
442 }
443
444 bool manager_shall_kill(Manager *m, const char *user) {
445 assert(m);
446 assert(user);
447
448 if (!m->kill_exclude_users && streq(user, "root"))
449 return false;
450
451 if (strv_contains(m->kill_exclude_users, user))
452 return false;
453
454 if (!strv_isempty(m->kill_only_users))
455 return strv_contains(m->kill_only_users, user);
456
457 return m->kill_user_processes;
458 }
459
460 int config_parse_n_autovts(
461 const char *unit,
462 const char *filename,
463 unsigned line,
464 const char *section,
465 unsigned section_line,
466 const char *lvalue,
467 int ltype,
468 const char *rvalue,
469 void *data,
470 void *userdata) {
471
472 unsigned *n = ASSERT_PTR(data);
473 unsigned o;
474 int r;
475
476 assert(filename);
477 assert(lvalue);
478 assert(rvalue);
479
480 r = safe_atou(rvalue, &o);
481 if (r < 0) {
482 log_syntax(unit, LOG_WARNING, filename, line, r,
483 "Failed to parse number of autovts, ignoring: %s", rvalue);
484 return 0;
485 }
486
487 if (o > 15) {
488 log_syntax(unit, LOG_WARNING, filename, line, 0,
489 "A maximum of 15 autovts are supported, ignoring: %s", rvalue);
490 return 0;
491 }
492
493 *n = o;
494 return 0;
495 }
496
497 static int vt_is_busy(unsigned vtnr) {
498 struct vt_stat vt_stat;
499 int r;
500 _cleanup_close_ int fd = -EBADF;
501
502 assert(vtnr >= 1);
503
504 /* VT_GETSTATE "cannot return state for more than 16 VTs, since v_state is short" */
505 assert(vtnr <= 15);
506
507 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
508 * we'd open the latter we'd open the foreground tty which
509 * hence would be unconditionally busy. By opening /dev/tty1
510 * we avoid this. Since tty1 is special and needs to be an
511 * explicitly loaded getty or DM this is safe. */
512
513 fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
514 if (fd < 0)
515 return -errno;
516
517 if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
518 r = -errno;
519 else
520 r = !!(vt_stat.v_state & (1 << vtnr));
521
522 return r;
523 }
524
525 int manager_spawn_autovt(Manager *m, unsigned vtnr) {
526 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
527 char name[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned)];
528 int r;
529
530 assert(m);
531 assert(vtnr >= 1);
532
533 if (vtnr > m->n_autovts &&
534 vtnr != m->reserve_vt)
535 return 0;
536
537 if (vtnr != m->reserve_vt) {
538 /* If this is the reserved TTY, we'll start the getty
539 * on it in any case, but otherwise only if it is not
540 * busy. */
541
542 r = vt_is_busy(vtnr);
543 if (r < 0)
544 return r;
545 else if (r > 0)
546 return -EBUSY;
547 }
548
549 xsprintf(name, "autovt@tty%u.service", vtnr);
550 r = bus_call_method(m->bus, bus_systemd_mgr, "StartUnit", &error, NULL, "ss", name, "fail");
551 if (r < 0)
552 return log_error_errno(r, "Failed to start %s: %s", name, bus_error_message(&error, r));
553
554 return 0;
555 }
556
557 bool manager_is_lid_closed(Manager *m) {
558 Button *b;
559
560 HASHMAP_FOREACH(b, m->buttons)
561 if (b->lid_closed)
562 return true;
563
564 return false;
565 }
566
567 static bool manager_is_docked(Manager *m) {
568 Button *b;
569
570 HASHMAP_FOREACH(b, m->buttons)
571 if (b->docked)
572 return true;
573
574 return false;
575 }
576
577 static int manager_count_external_displays(Manager *m) {
578 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
579 int r, n = 0;
580
581 r = sd_device_enumerator_new(&e);
582 if (r < 0)
583 return r;
584
585 r = sd_device_enumerator_allow_uninitialized(e);
586 if (r < 0)
587 return r;
588
589 r = sd_device_enumerator_add_match_subsystem(e, "drm", true);
590 if (r < 0)
591 return r;
592
593 FOREACH_DEVICE(e, d) {
594 const char *status, *enabled, *dash, *nn;
595 sd_device *p;
596
597 if (sd_device_get_parent(d, &p) < 0)
598 continue;
599
600 /* If the parent shares the same subsystem as the
601 * device we are looking at then it is a connector,
602 * which is what we are interested in. */
603 if (!device_in_subsystem(p, "drm"))
604 continue;
605
606 if (sd_device_get_sysname(d, &nn) < 0)
607 continue;
608
609 /* Ignore internal displays: the type is encoded in the sysfs name, as the second dash
610 * separated item (the first is the card name, the last the connector number). We implement a
611 * deny list of external displays here, rather than an allow list of internal ones, to ensure
612 * we don't block suspends too eagerly. */
613 dash = strchr(nn, '-');
614 if (!dash)
615 continue;
616
617 dash++;
618 if (!STARTSWITH_SET(dash,
619 "VGA-", "DVI-I-", "DVI-D-", "DVI-A-"
620 "Composite-", "SVIDEO-", "Component-",
621 "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-"))
622 continue;
623
624 /* Ignore ports that are not enabled */
625 if (sd_device_get_sysattr_value(d, "enabled", &enabled) < 0 || !streq(enabled, "enabled"))
626 continue;
627
628 /* We count any connector which is not explicitly
629 * "disconnected" as connected. */
630 if (sd_device_get_sysattr_value(d, "status", &status) < 0 || !streq(status, "disconnected"))
631 n++;
632 }
633
634 return n;
635 }
636
637 bool manager_is_docked_or_external_displays(Manager *m) {
638 int n;
639
640 /* If we are docked don't react to lid closing */
641 if (manager_is_docked(m)) {
642 log_debug("System is docked.");
643 return true;
644 }
645
646 /* If we have more than one display connected,
647 * assume that we are docked. */
648 n = manager_count_external_displays(m);
649 if (n < 0)
650 log_warning_errno(n, "Display counting failed: %m");
651 else if (n >= 1) {
652 log_debug("External (%i) displays connected.", n);
653 return true;
654 }
655
656 return false;
657 }
658
659 bool manager_is_on_external_power(void) {
660 int r;
661
662 /* For now we only check for AC power, but 'external power' can apply to anything that isn't an internal
663 * battery */
664 r = on_ac_power();
665 if (r < 0)
666 log_warning_errno(r, "Failed to read AC power status: %m");
667
668 return r != 0; /* Treat failure as 'on AC' */
669 }
670
671 bool manager_all_buttons_ignored(Manager *m) {
672 assert(m);
673
674 if (m->handle_power_key != HANDLE_IGNORE)
675 return false;
676 if (m->handle_power_key_long_press != HANDLE_IGNORE)
677 return false;
678 if (m->handle_suspend_key != HANDLE_IGNORE)
679 return false;
680 if (m->handle_suspend_key_long_press != HANDLE_IGNORE)
681 return false;
682 if (m->handle_hibernate_key != HANDLE_IGNORE)
683 return false;
684 if (m->handle_hibernate_key_long_press != HANDLE_IGNORE)
685 return false;
686 if (m->handle_reboot_key != HANDLE_IGNORE)
687 return false;
688 if (m->handle_reboot_key_long_press != HANDLE_IGNORE)
689 return false;
690 if (m->handle_lid_switch != HANDLE_IGNORE)
691 return false;
692 if (!IN_SET(m->handle_lid_switch_ep, _HANDLE_ACTION_INVALID, HANDLE_IGNORE))
693 return false;
694 if (m->handle_lid_switch_docked != HANDLE_IGNORE)
695 return false;
696
697 return true;
698 }
699
700 int manager_read_utmp(Manager *m) {
701 #if ENABLE_UTMP
702 int r;
703 _unused_ _cleanup_(utxent_cleanup) bool utmpx = false;
704
705 assert(m);
706
707 if (utmpxname(_PATH_UTMPX) < 0)
708 return log_error_errno(errno, "Failed to set utmp path to " _PATH_UTMPX ": %m");
709
710 utmpx = utxent_start();
711
712 for (;;) {
713 _cleanup_free_ char *t = NULL;
714 struct utmpx *u;
715 const char *c;
716 Session *s;
717
718 errno = 0;
719 u = getutxent();
720 if (!u) {
721 if (errno == ENOENT)
722 log_debug_errno(errno, _PATH_UTMPX " does not exist, ignoring.");
723 else if (errno != 0)
724 log_warning_errno(errno, "Failed to read " _PATH_UTMPX ", ignoring: %m");
725 return 0;
726 }
727
728 if (u->ut_type != USER_PROCESS)
729 continue;
730
731 if (!pid_is_valid(u->ut_pid))
732 continue;
733
734 t = strndup(u->ut_line, sizeof(u->ut_line));
735 if (!t)
736 return log_oom();
737
738 c = path_startswith(t, "/dev/");
739 if (c) {
740 r = free_and_strdup(&t, c);
741 if (r < 0)
742 return log_oom();
743 }
744
745 if (isempty(t))
746 continue;
747
748 if (manager_get_session_by_pidref(m, &PIDREF_MAKE_FROM_PID(u->ut_pid), &s) <= 0)
749 continue;
750
751 if (s->tty_validity == TTY_FROM_UTMP && !streq_ptr(s->tty, t)) {
752 /* This may happen on multiplexed SSH connection (i.e. 'SSH connection sharing'). In
753 * this case PAM and utmp sessions don't match. In such a case let's invalidate the TTY
754 * information and never acquire it again. */
755
756 s->tty = mfree(s->tty);
757 s->tty_validity = TTY_UTMP_INCONSISTENT;
758 log_debug("Session '%s' has inconsistent TTY information, dropping TTY information.", s->id);
759 continue;
760 }
761
762 /* Never override what we figured out once */
763 if (s->tty || s->tty_validity >= 0)
764 continue;
765
766 s->tty = TAKE_PTR(t);
767 s->tty_validity = TTY_FROM_UTMP;
768 log_debug("Acquired TTY information '%s' from utmp for session '%s'.", s->tty, s->id);
769 }
770
771 #else
772 return 0;
773 #endif
774 }
775
776 #if ENABLE_UTMP
777 static int manager_dispatch_utmp(sd_event_source *s, const struct inotify_event *event, void *userdata) {
778 Manager *m = ASSERT_PTR(userdata);
779
780 /* If there's indication the file itself might have been removed or became otherwise unavailable, then let's
781 * reestablish the watch on whatever there's now. */
782 if ((event->mask & (IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF|IN_Q_OVERFLOW|IN_UNMOUNT)) != 0)
783 manager_connect_utmp(m);
784
785 (void) manager_read_utmp(m);
786 return 0;
787 }
788 #endif
789
790 void manager_connect_utmp(Manager *m) {
791 #if ENABLE_UTMP
792 sd_event_source *s = NULL;
793 int r;
794
795 assert(m);
796
797 /* Watch utmp for changes via inotify. We do this to deal with tools such as ssh, which will register the PAM
798 * session early, and acquire a TTY only much later for the connection. Thus during PAM the TTY won't be known
799 * yet. ssh will register itself with utmp when it finally acquired the TTY. Hence, let's make use of this, and
800 * watch utmp for the TTY asynchronously. We use the PAM session's leader PID as key, to find the right entry.
801 *
802 * Yes, relying on utmp is pretty ugly, but it's good enough for informational purposes, as well as idle
803 * detection (which, for tty sessions, relies on the TTY used) */
804
805 r = sd_event_add_inotify(m->event, &s, _PATH_UTMPX, IN_MODIFY|IN_MOVE_SELF|IN_DELETE_SELF|IN_ATTRIB, manager_dispatch_utmp, m);
806 if (r < 0)
807 log_full_errno(r == -ENOENT ? LOG_DEBUG: LOG_WARNING, r, "Failed to create inotify watch on " _PATH_UTMPX ", ignoring: %m");
808 else {
809 r = sd_event_source_set_priority(s, SD_EVENT_PRIORITY_IDLE);
810 if (r < 0)
811 log_warning_errno(r, "Failed to adjust utmp event source priority, ignoring: %m");
812
813 (void) sd_event_source_set_description(s, "utmp");
814 }
815
816 sd_event_source_unref(m->utmp_event_source);
817 m->utmp_event_source = s;
818 #endif
819 }
820
821 void manager_reconnect_utmp(Manager *m) {
822 #if ENABLE_UTMP
823 assert(m);
824
825 if (m->utmp_event_source)
826 return;
827
828 manager_connect_utmp(m);
829 #endif
830 }
831
832 int manager_read_efi_boot_loader_entries(Manager *m) {
833 #if ENABLE_EFI
834 int r;
835
836 assert(m);
837 if (m->efi_boot_loader_entries_set)
838 return 0;
839
840 r = efi_loader_get_entries(&m->efi_boot_loader_entries);
841 if (r < 0) {
842 if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r)) {
843 log_debug_errno(r, "Boot loader reported no entries.");
844 m->efi_boot_loader_entries_set = true;
845 return 0;
846 }
847 return log_error_errno(r, "Failed to determine entries reported by boot loader: %m");
848 }
849
850 m->efi_boot_loader_entries_set = true;
851 return 1;
852 #else
853 return 0;
854 #endif
855 }