Вопрос или проблема
Я экспериментирую с настройками systemd-logind
на Lenovo ThinkPad X270 (у которого есть дополнительная батарея) и хочу, чтобы моя система вела себя по-разному, когда подключена к внешнему источнику питания и когда работает на батарее. В частности, я установил следующий параметр в моем /etc/systemd/logind.conf
:
HandleLidSwitchExternalPower=ignore
Мои ожидания, когда я закрываю крышку:
- На AC: не приостанавливать
- Без AC: приостанавливать
Однако я заметил, что система не приостанавливается, когда я закрываю крышку, независимо от того, подключен адаптер переменного тока или нет. Я подозреваю, что systemd может не определять, что я подключен (или отключен) от внешнего источника питания, возможно, из-за дополнительной батареи или какой-то особенности в обнаружении источника питания. Я хотел бы подтвердить, как systemd определяет, подключен ли компьютер к внешнему питанию или нет.
-
Детали системы:
❯ neofetch _,met$$$$$gg. yashi@leno ,g$$$$$$$$$$$$$$$P. ---------- ,g$$P" """Y$$.". OS: Debian GNU/Linux trixie/sid x86_64 ,$$P' `$$$. Host: 20HNCTO1WW ThinkPad X270 ',$$P ,ggs. `$$b: Kernel: 6.12.9-amd64 `d$$' ,$P"' . $$$ Uptime: 58 mins $$P d$' , $$P Packages: 4447 (dpkg), 6 (flatpak) $$: $$. - ,d$$' Shell: zsh 5.9 $$; Y$b._ _,d$P' Resolution: 1920x1080 Y$$. `.`"Y$$$$P"' Terminal: /dev/pts/1 `$$b "-.__ CPU: Intel i7-7600U (4) @ 3.900GHz `Y$$ GPU: Intel HD Graphics 620 `Y$$. Memory: 1328MiB / 15879MiB `$$b. `Y$$b. `"Y$b._ `"""
-
Что я пробовал:
-
Проверил вывод таких инструментов, как upower -d или acpi -V, которые показывают правильные состояния питания для системы в целом.
-
Использовал journalctl -u systemd-logind, чтобы посмотреть, есть ли какие-либо журналы, указывающие на состояние внешнего/батарейного питания.
-
Проверил, что поведение при срабатывании переключателя крышки изменяется, если я использую HandleLidSwitch=suspend, но настройка, специфичная для внешнего питания, не работает как ожидается.
-
-
Вопрос:
- Как запросить systemd (или logind), чтобы понять, считает ли он в данный момент, что мой ноутбук подключен к внешнему питанию или нет?
- Как только я пойму, как systemd определяет источник питания, я смогу выяснить, почему HandleLidSwitchExternalPower=ignore не работает по назначению на этом ноутбуке.
Я открыт для любых предложений по командам, запросам D-Bus или журналам, которые могут подтвердить, как systemd/logind интерпретирует состояние питания. Также, если есть альтернативный подход для управления различным поведением при закрытии крышки для батареи и переменного тока, я хотел бы услышать и об этом.
Любые рекомендации или советы по устранению неполадок будут очень полезны!
Детали
Различия в upower -d
с или без AC:
Daemon:
daemon-version: 1.90.7
- on-battery: yes
+ on-battery: no
lid-is-closed: no
lid-is-present: yes
critical-action: HybridSleep
Различия в acpi -V
с или без AC:
@@ -1,8 +1,8 @@
Battery 0: Full, 100%
Battery 0: design capacity 1867 mAh, last full capacity 1153 mAh = 61%
-Battery 1: Discharging, 100%, discharging at zero rate - will never fully discharge.
-Battery 1: design capacity 5592 mAh, last full capacity 3708 mAh = 66%
-Adapter 0: off-line
+Battery 1: Charging, 100%, until charged
+Battery 1: design capacity 5561 mAh, last full capacity 3688 mAh = 66%
+Adapter 0: on-line
Thermal 0: ok, 37.0 degrees C
Thermal 0: trip point 0 switches to mode critical at temperature 128.0 degrees C
Cooling 0: Processor 0 of 10
Логи logind:
Jan 20 14:52:53 leno systemd-logind[710]: Lid closed.
Jan 20 14:52:57 leno systemd-logind[710]: Lid opened.
Jan 20 14:53:37 leno systemd-logind[710]: Lid closed.
Jan 20 14:53:40 leno systemd-logind[710]: Lid opened.
Jan 20 15:49:25 leno systemd-logind[705]: Lid closed.
Jan 20 15:49:25 leno systemd-logind[705]: Suspending...
Jan 20 15:49:37 leno systemd-logind[705]: Lid opened.
Jan 20 15:49:38 leno systemd-logind[705]: Operation 'suspend' finished.
Jan 20 15:51:12 leno systemd-logind[705]: Lid closed.
Jan 20 15:51:12 leno systemd-logind[705]: Suspending...
Jan 20 15:51:24 leno systemd-logind[705]: Lid opened.
Jan 20 15:51:25 leno systemd-logind[705]: Operation 'suspend' finished.
Программа /usr/bin/systemd-ac-power
использует ту же логику, что и systemd в целом. Она завершается со статусом 0, если считает, что система подключена к источнику переменного тока, >0 в противном случае.
$ SYSTEMD_LOG_LEVEL=debug systemd-ac-power
BAT0: The battery status is 'Charging', assuming the battery is not used as a power source of this machine.
hidpp_battery_0: The power supply is a device battery, ignoring device.
AC: The power supply is currently online.
port0: The USB type-C port is in power sink mode.
port1: The USB type-C port is in power sink mode.
ucsi-source-psy-USBC000:001: The USB type-C device has at least one port in power sink mode.
ucsi-source-psy-USBC000:001: The power supply is currently offline.
port0: The USB type-C port is in power sink mode.
port1: The USB type-C port is in power sink mode.
ucsi-source-psy-USBC000:002: The USB type-C device has at least one port in power sink mode.
ucsi-source-psy-USBC000:002: The power supply is currently online.
Found at least one online non-battery power supply, system is running on AC.
$ echo $?
0
Для всех устройств типа “power_supply”, найденных в /sys/class/power_supply
(или udevadm trigger -vns power_supply
), она проверяет:
- Если у устройства
type = Battery
,
тогда еслиscope != Device
,present = 1
, иstatus = Discharging
; - Если у устройства
type = USB
,
тогда еслиonline = 1
и у его родительского устройства “typec”power_role = [sink]
; - В противном случае, если
online = 1
.
Если находится хотя бы одно online
устройство питания, тогда система работает от сети. В противном случае, если находится хотя бы одна батарея в состоянии Discharging
, то система работает не от сети. Если ни то, ни другое не найдено, то предполагается, что система должна быть подключена к сети.
Логика находится в src/shared/battery-util.c
(ранее в udev-util.c
).
Старые версии systemd (v250 и ранее) не проверяли роль порта Type-C и могли ошибочно предположить, что система работает от сети, если было найдено любое online = 1
устройство питания, даже если оно было подключено к порту, выступающему в качестве источника питания (т.е. заряжающему ваш смартфон).
Наконец, имейте в виду, что некоторые окружения рабочего стола берут на себя управление кнопкой питания и/или обработкой переключателя крышки (через инхибиторы “handle-*” в systemd-inhibit --list
), в этом случае именно окружение рабочего стола мониторит события ввода и вручную вызывает соответствующее действие logind.
.
Ответ или решение
Когда дело касается настройки поведения вашей системы в зависимости от того, подключена ли она к внешнему источнику питания или работает от батареи, важно понимать, как systemd-logind
определяет текущий источник питания. Рассмотрим этот вопрос более детально.
Теория
Система systemd-logind
в значительной степени полагается на информацию, предоставляемую подсистемой питания Linux для определения того, подключена ли система к внешнему источнику питания (например, в случае подключения к блоку питания) или работает от аккумулятора. Эта информация обычно содержится в /sys/class/power_supply/*
, где различные файлы и директории представляют собой параметры и устройства, относящиеся к питанию.
Каждое устройство питания описывается рядом атрибутов, среди которых критическими являются status
, online
, и present
. status
показывает состояние батареи (например, "Charging", "Discharging"), online
определяет, подключено ли устройство, и present
показывает, установлено ли устройство в системе.
Пример
Вы привели серию диагностических команд upower -d
, acpi -V
и использование журнала journalctl -u systemd-logind
. Эти инструменты предоставляют информацию о текущем состоянии батареи и адаптера. В частности, ключевую роль играет утилита systemd-ac-power
, которая проверяет состояние питания системы и возвращает статус 0, если система находится на внешнем питании, и больше 0, если нет.
Вывод этой утилиты может быть, например, следующим:
$ SYSTEMD_LOG_LEVEL=debug systemd-ac-power
BAT0: The battery status is 'Charging', assuming the battery is not used as a power source of this machine.
AC: The power supply is currently online.
Found at least one online non-battery power supply, system is running on AC.
$ echo $?
0
Этот отладочный вывод показывает, что устройство питания действительно использует внешнее питание. Это подтверждается выводом echo $?
, возвращающим 0, указывающим, что система воспринимается как работающая от внешнего источника питания.
Применение
Теперь, когда у нас есть понимание, как именно systemd-logind
определяет источник питания, можно применить это знание для диагностики и решения проблем. Вот несколько шагов, которые вы можете предпринять:
-
Проверьте логи и выходы утилит: Используйте
journalctl -u systemd-logind
для проверки своевременности изменения состояния питания. Также можно периодически запускатьupower -d
иsystemd-ac-power
для диагностирования состояния системы. -
Поймите поведение устройства: Убедитесь, что система правильно различает состояние "зарядка" и "разрядка", особенно если задействованы вторичные батареи или сложные сценарии с USB-питанием.
-
Обновите и протестируйте настройки: Проверьте наличие обновлений для
systemd
, так как более поздние версии могут включать исправления, связанные с обнаружением источников питания, особенно для современных устройств с поддержкой USB-C. -
Рассмотрите влияние рабочих сред: Некоторые рабочие среды могут замещать поведение
systemd-logind
. Используйтеsystemd-inhibit --list
, чтобы проверить, есть ли какие-либо запреты, связанные с обработкой событий кнопок или крышки.
Если указанные методы не решают проблему, возможно, стоит рассмотреть обновление или патчинг systemd
до последней версии или обратиться к документации и справочным материалам, предлагающим более подробное API для управления поведением питания на низком уровне. Это может включать запросы к D-Bus методам, используемым logind
, для получения текущей информации о состоянии питания или управления настройками.