Как я могу проверить, считает ли systemd, что я подключен к внешнему питанию?

Вопрос или проблема

Я экспериментирую с настройками systemd-logind на Lenovo ThinkPad X270 (у которого есть дополнительная батарея) и хочу, чтобы моя система вела себя по-разному, когда подключена к внешнему источнику питания и когда работает на батарее. В частности, я установил следующий параметр в моем /etc/systemd/logind.conf:

HandleLidSwitchExternalPower=ignore

Мои ожидания, когда я закрываю крышку:

  • На AC: не приостанавливать
  • Без AC: приостанавливать

Однако я заметил, что система не приостанавливается, когда я закрываю крышку, независимо от того, подключен адаптер переменного тока или нет. Я подозреваю, что systemd может не определять, что я подключен (или отключен) от внешнего источника питания, возможно, из-за дополнительной батареи или какой-то особенности в обнаружении источника питания. Я хотел бы подтвердить, как systemd определяет, подключен ли компьютер к внешнему питанию или нет.

  1. Детали системы:

    ❯ 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._                                     
                  `"""
    
  2. Что я пробовал:

    • Проверил вывод таких инструментов, как upower -d или acpi -V, которые показывают правильные состояния питания для системы в целом.

    • Использовал journalctl -u systemd-logind, чтобы посмотреть, есть ли какие-либо журналы, указывающие на состояние внешнего/батарейного питания.

    • Проверил, что поведение при срабатывании переключателя крышки изменяется, если я использую HandleLidSwitch=suspend, но настройка, специфичная для внешнего питания, не работает как ожидается.

  3. Вопрос:

    • Как запросить 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 определяет источник питания, можно применить это знание для диагностики и решения проблем. Вот несколько шагов, которые вы можете предпринять:

  1. Проверьте логи и выходы утилит: Используйте journalctl -u systemd-logind для проверки своевременности изменения состояния питания. Также можно периодически запускать upower -d и systemd-ac-power для диагностирования состояния системы.

  2. Поймите поведение устройства: Убедитесь, что система правильно различает состояние "зарядка" и "разрядка", особенно если задействованы вторичные батареи или сложные сценарии с USB-питанием.

  3. Обновите и протестируйте настройки: Проверьте наличие обновлений для systemd, так как более поздние версии могут включать исправления, связанные с обнаружением источников питания, особенно для современных устройств с поддержкой USB-C.

  4. Рассмотрите влияние рабочих сред: Некоторые рабочие среды могут замещать поведение systemd-logind. Используйте systemd-inhibit --list, чтобы проверить, есть ли какие-либо запреты, связанные с обработкой событий кнопок или крышки.

Если указанные методы не решают проблему, возможно, стоит рассмотреть обновление или патчинг systemd до последней версии или обратиться к документации и справочным материалам, предлагающим более подробное API для управления поведением питания на низком уровне. Это может включать запросы к D-Bus методам, используемым logind, для получения текущей информации о состоянии питания или управления настройками.

Оцените материал
Добавить комментарий

Капча загружается...