O temporizador Systemd começa a usar 90% da CPU aleatoriamente

0

Meu laptop não envia eventos de descarga da ACPI de forma confiável, então criei um timer e um serviço Systemd para periodicamente verificar o nível da bateria e decidir se o computador deve hibernar. No entanto, uma quantidade aleatória de tempo após a inicialização (geralmente dentro de uma hora ou mais), o Systemd começa a usar cerca de 90% da CPU e continua a fazê-lo até eu systemctl stop do timer. Especificamente, os processos são (pelo uso da CPU)

~ 90%: /usr/lib/systemd/systemd --switched-root --system --deserialize 32
~ 80%: /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
~ 20%: /usr/lib/systemd/systemd-logind

Todos estes voltam a zero quando paro o temporizador. Os arquivos relevantes estão abaixo. Estou executando o Arch Linux, a versão 235.8-1 do Systemd. É importante notar que esse problema acontece mesmo quando conectado à energia da parede, quando hibernate-if-low-battery não deveria estar rodando.

auto-hibernate.timer

[Unit]
Description=Check battery level periodically and hibernate when low

[Timer]
OnBootSec=30s
OnUnitActiveSec=30s

[Install]
WantedBy=timers.target

auto-hibernate.service

[Unit]
Description=Check battery level and hibernate if low
ConditionACPower=false

[Service]
Type=oneshot
ExecStart=/usr/local/bin/hibernate-if-low-battery

hibernar-se-bateria fraca

#!/usr/bin/env bash

# Configuration.
BATTERY_PATH=/sys/class/power_supply/BAT0
CRITICAL_BATTERY_PERCENTAGE=5

# Calculate (the floor of) the battery percentage.
current_battery_level=$(< ${BATTERY_PATH}/energy_now)
max_battery_level=$(< ${BATTERY_PATH}/energy_full)
current_battery_percentage=$(((current_battery_level * 100)/max_battery_level))

if ((current_battery_percentage <= critical_battery_percentage)); then
    logger 'Hibernating due to low battery.'
    systemctl hibernate
fi
    
por Will Kunkel 28.10.2017 / 04:17

1 resposta

0

Isso parece ser um bug do systemd causado pelo uso de um timer para acionar um serviço que usa ConditionACPower ; veja link . Mover a verificação de energia CA para o script hibernate-if-low-battery deve corrigir o problema. Especificamente, isso funciona:

auto-hibernate.service

[Unit]
Description=Check battery level and hibernate if low

[Service]
Type=oneshot
ExecStart=/usr/local/bin/hibernate-if-low-battery

hibernar-se-bateria fraca

#!/usr/bin/env bash

# Configuration.
BATTERY_PATH=/sys/class/power_supply/BAT0
AC_PATH=/sys/class/power_supply/AC
CRITICAL_BATTERY_PERCENTAGE=5

# Get AC power status.
ac_power_active=$(< "${AC_PATH}/online")

# Calculate (the floor of) the battery percentage.
current_battery_level=$(< "${BATTERY_PATH}/energy_now")
max_battery_level=$(< "${BATTERY_PATH}/energy_full")
current_battery_percentage=$(((current_battery_level * 100)/max_battery_level))
battery_level_critical=$((current_battery_percentage <= critical_battery_percentage))

if (( ! ac_power_active && battery_level_critical )); then
    logger 'Hibernating due to low battery.'
    systemctl hibernate
fi
    
por 29.10.2017 / 03:49