1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2011 Lennart Poettering
10 #include <sys/ioctl.h>
11 #include <sys/types.h>
14 #include "alloc-util.h"
15 #include "bus-error.h"
17 #include "cgroup-util.h"
18 #include "conf-parser.h"
21 #include "parse-util.h"
22 #include "process-util.h"
24 #include "terminal-util.h"
25 #include "udev-util.h"
26 #include "user-util.h"
28 void manager_reset_config(Manager
*m
) {
34 m
->inhibit_delay_max
= 5 * USEC_PER_SEC
;
35 m
->handle_power_key
= HANDLE_POWEROFF
;
36 m
->handle_suspend_key
= HANDLE_SUSPEND
;
37 m
->handle_hibernate_key
= HANDLE_HIBERNATE
;
38 m
->handle_lid_switch
= HANDLE_SUSPEND
;
39 m
->handle_lid_switch_ep
= _HANDLE_ACTION_INVALID
;
40 m
->handle_lid_switch_docked
= HANDLE_IGNORE
;
41 m
->power_key_ignore_inhibited
= false;
42 m
->suspend_key_ignore_inhibited
= false;
43 m
->hibernate_key_ignore_inhibited
= false;
44 m
->lid_switch_ignore_inhibited
= true;
46 m
->holdoff_timeout_usec
= 30 * USEC_PER_SEC
;
48 m
->idle_action_usec
= 30 * USEC_PER_MINUTE
;
49 m
->idle_action
= HANDLE_IGNORE
;
51 m
->runtime_dir_size
= physical_memory_scale(10U, 100U); /* 10% */
52 m
->user_tasks_max
= system_tasks_max_scale(DEFAULT_USER_TASKS_MAX_PERCENTAGE
, 100U); /* 33% */
53 m
->sessions_max
= 8192;
54 m
->inhibitors_max
= 8192;
56 m
->kill_user_processes
= KILL_USER_PROCESSES
;
58 m
->kill_only_users
= strv_free(m
->kill_only_users
);
59 m
->kill_exclude_users
= strv_free(m
->kill_exclude_users
);
62 int manager_parse_config_file(Manager
*m
) {
65 return config_parse_many_nulstr(PKGSYSCONFDIR
"/logind.conf",
66 CONF_PATHS_NULSTR("systemd/logind.conf.d"),
68 config_item_perf_lookup
, logind_gperf_lookup
,
69 CONFIG_PARSE_WARN
, m
);
72 int manager_add_device(Manager
*m
, const char *sysfs
, bool master
, Device
**_device
) {
78 d
= hashmap_get(m
->devices
, sysfs
);
80 /* we support adding master-flags, but not removing them */
81 d
->master
= d
->master
|| master
;
83 d
= device_new(m
, sysfs
, master
);
94 int manager_add_seat(Manager
*m
, const char *id
, Seat
**_seat
) {
100 s
= hashmap_get(m
->seats
, id
);
113 int manager_add_session(Manager
*m
, const char *id
, Session
**_session
) {
119 s
= hashmap_get(m
->sessions
, id
);
121 s
= session_new(m
, id
);
132 int manager_add_user(Manager
*m
, uid_t uid
, gid_t gid
, const char *name
, User
**_user
) {
139 u
= hashmap_get(m
->users
, UID_TO_PTR(uid
));
141 r
= user_new(&u
, m
, uid
, gid
, name
);
152 int manager_add_user_by_name(Manager
*m
, const char *name
, User
**_user
) {
160 r
= get_user_creds(&name
, &uid
, &gid
, NULL
, NULL
);
164 return manager_add_user(m
, uid
, gid
, name
, _user
);
167 int manager_add_user_by_uid(Manager
*m
, uid_t uid
, User
**_user
) {
175 return errno
> 0 ? -errno
: -ENOENT
;
177 return manager_add_user(m
, uid
, p
->pw_gid
, p
->pw_name
, _user
);
180 int manager_add_inhibitor(Manager
*m
, const char* id
, Inhibitor
**_inhibitor
) {
186 i
= hashmap_get(m
->inhibitors
, id
);
194 i
= inhibitor_new(m
, id
);
204 int manager_add_button(Manager
*m
, const char *name
, Button
**_button
) {
210 b
= hashmap_get(m
->buttons
, name
);
212 b
= button_new(m
, name
);
223 int manager_process_seat_device(Manager
*m
, struct udev_device
*d
) {
229 if (streq_ptr(udev_device_get_action(d
), "remove")) {
231 device
= hashmap_get(m
->devices
, udev_device_get_syspath(d
));
235 seat_add_to_gc_queue(device
->seat
);
243 sn
= udev_device_get_property_value(d
, "ID_SEAT");
247 if (!seat_name_is_valid(sn
)) {
248 log_warning("Device with invalid seat name %s found, ignoring.", sn
);
252 seat
= hashmap_get(m
->seats
, sn
);
253 master
= udev_device_has_tag(d
, "master-of-seat");
255 /* Ignore non-master devices for unknown seats */
256 if (!master
&& !seat
)
259 r
= manager_add_device(m
, udev_device_get_syspath(d
), master
, &device
);
264 r
= manager_add_seat(m
, sn
, &seat
);
273 device_attach(device
, seat
);
280 int manager_process_button_device(Manager
*m
, struct udev_device
*d
) {
287 if (streq_ptr(udev_device_get_action(d
), "remove")) {
289 b
= hashmap_get(m
->buttons
, udev_device_get_sysname(d
));
298 r
= manager_add_button(m
, udev_device_get_sysname(d
), &b
);
302 sn
= udev_device_get_property_value(d
, "ID_SEAT");
306 button_set_seat(b
, sn
);
309 if (r
< 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
310 * opening the device?) let's close the button again. */
317 int manager_get_session_by_pid(Manager
*m
, pid_t pid
, Session
**ret
) {
318 _cleanup_free_
char *unit
= NULL
;
324 if (!pid_is_valid(pid
))
327 r
= cg_pid_get_unit(pid
, &unit
);
331 s
= hashmap_get(m
->session_units
, unit
);
346 int manager_get_user_by_pid(Manager
*m
, pid_t pid
, User
**ret
) {
347 _cleanup_free_
char *unit
= NULL
;
353 if (!pid_is_valid(pid
))
356 r
= cg_pid_get_slice(pid
, &unit
);
360 u
= hashmap_get(m
->user_units
, unit
);
376 int manager_get_idle_hint(Manager
*m
, dual_timestamp
*t
) {
379 dual_timestamp ts
= DUAL_TIMESTAMP_NULL
;
384 idle_hint
= !manager_is_inhibited(m
, INHIBIT_IDLE
, INHIBIT_BLOCK
, t
, false, false, 0, NULL
);
386 HASHMAP_FOREACH(s
, m
->sessions
, i
) {
390 ih
= session_get_idle_hint(s
, &k
);
396 if (k
.monotonic
< ts
.monotonic
)
402 } else if (idle_hint
) {
404 if (k
.monotonic
> ts
.monotonic
)
415 bool manager_shall_kill(Manager
*m
, const char *user
) {
419 if (!m
->kill_exclude_users
&& streq(user
, "root"))
422 if (strv_contains(m
->kill_exclude_users
, user
))
425 if (!strv_isempty(m
->kill_only_users
))
426 return strv_contains(m
->kill_only_users
, user
);
428 return m
->kill_user_processes
;
431 int config_parse_n_autovts(
433 const char *filename
,
436 unsigned section_line
,
452 r
= safe_atou(rvalue
, &o
);
454 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Failed to parse number of autovts, ignoring: %s", rvalue
);
459 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "A maximum of 15 autovts are supported, ignoring: %s", rvalue
);
467 static int vt_is_busy(unsigned int vtnr
) {
468 struct vt_stat vt_stat
;
470 _cleanup_close_
int fd
;
474 /* VT_GETSTATE "cannot return state for more than 16 VTs, since v_state is short" */
477 /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
478 * we'd open the latter we'd open the foreground tty which
479 * hence would be unconditionally busy. By opening /dev/tty1
480 * we avoid this. Since tty1 is special and needs to be an
481 * explicitly loaded getty or DM this is safe. */
483 fd
= open_terminal("/dev/tty1", O_RDWR
|O_NOCTTY
|O_CLOEXEC
);
487 if (ioctl(fd
, VT_GETSTATE
, &vt_stat
) < 0)
490 r
= !!(vt_stat
.v_state
& (1 << vtnr
));
495 int manager_spawn_autovt(Manager
*m
, unsigned int vtnr
) {
496 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
497 char name
[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned int)];
503 if (vtnr
> m
->n_autovts
&&
504 vtnr
!= m
->reserve_vt
)
507 if (vtnr
!= m
->reserve_vt
) {
508 /* If this is the reserved TTY, we'll start the getty
509 * on it in any case, but otherwise only if it is not
512 r
= vt_is_busy(vtnr
);
519 snprintf(name
, sizeof(name
), "autovt@tty%u.service", vtnr
);
520 r
= sd_bus_call_method(
522 "org.freedesktop.systemd1",
523 "/org/freedesktop/systemd1",
524 "org.freedesktop.systemd1.Manager",
530 log_error("Failed to start %s: %s", name
, bus_error_message(&error
, r
));
535 static bool manager_is_docked(Manager
*m
) {
539 HASHMAP_FOREACH(b
, m
->buttons
, i
)
546 static int manager_count_external_displays(Manager
*m
) {
547 _cleanup_(udev_enumerate_unrefp
) struct udev_enumerate
*e
= NULL
;
548 struct udev_list_entry
*item
= NULL
, *first
= NULL
;
552 e
= udev_enumerate_new(m
->udev
);
556 r
= udev_enumerate_add_match_subsystem(e
, "drm");
560 r
= udev_enumerate_scan_devices(e
);
564 first
= udev_enumerate_get_list_entry(e
);
565 udev_list_entry_foreach(item
, first
) {
566 _cleanup_(udev_device_unrefp
) struct udev_device
*d
= NULL
;
567 struct udev_device
*p
;
568 const char *status
, *enabled
, *dash
, *nn
, *i
;
569 bool external
= false;
571 d
= udev_device_new_from_syspath(m
->udev
, udev_list_entry_get_name(item
));
575 p
= udev_device_get_parent(d
);
579 /* If the parent shares the same subsystem as the
580 * device we are looking at then it is a connector,
581 * which is what we are interested in. */
582 if (!streq_ptr(udev_device_get_subsystem(p
), "drm"))
585 nn
= udev_device_get_sysname(d
);
589 /* Ignore internal displays: the type is encoded in
590 * the sysfs name, as the second dash separated item
591 * (the first is the card name, the last the connector
592 * number). We implement a whitelist of external
593 * displays here, rather than a whitelist, to ensure
594 * we don't block suspends too eagerly. */
595 dash
= strchr(nn
, '-');
600 FOREACH_STRING(i
, "VGA-", "DVI-I-", "DVI-D-", "DVI-A-"
601 "Composite-", "SVIDEO-", "Component-",
602 "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-") {
604 if (startswith(dash
, i
)) {
612 /* Ignore ports that are not enabled */
613 enabled
= udev_device_get_sysattr_value(d
, "enabled");
616 if (!streq_ptr(enabled
, "enabled"))
619 /* We count any connector which is not explicitly
620 * "disconnected" as connected. */
621 status
= udev_device_get_sysattr_value(d
, "status");
622 if (!streq_ptr(status
, "disconnected"))
629 bool manager_is_docked_or_external_displays(Manager
*m
) {
632 /* If we are docked don't react to lid closing */
633 if (manager_is_docked(m
)) {
634 log_debug("System is docked.");
638 /* If we have more than one display connected,
639 * assume that we are docked. */
640 n
= manager_count_external_displays(m
);
642 log_warning_errno(n
, "Display counting failed: %m");
644 log_debug("External (%i) displays connected.", n
);
651 bool manager_is_on_external_power(void) {
654 /* For now we only check for AC power, but 'external power' can apply
655 * to anything that isn't an internal battery */
658 log_warning_errno(r
, "Failed to read AC power status: %m");
665 bool manager_all_buttons_ignored(Manager
*m
) {
668 if (m
->handle_power_key
!= HANDLE_IGNORE
)
670 if (m
->handle_suspend_key
!= HANDLE_IGNORE
)
672 if (m
->handle_hibernate_key
!= HANDLE_IGNORE
)
674 if (m
->handle_lid_switch
!= HANDLE_IGNORE
)
676 if (m
->handle_lid_switch_ep
!= _HANDLE_ACTION_INVALID
&&
677 m
->handle_lid_switch_ep
!= HANDLE_IGNORE
)
679 if (m
->handle_lid_switch_docked
!= HANDLE_IGNORE
)