1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-07 17:17:44 +03:00

ac-power: check battery existence and status

If a battery is not present or its status is not discharging, then
the battery should not be used as a power source.
Let's count batteries currently discharging.

Fixes #25316.

(cherry picked from commit 1c03f7f4ba)
(cherry picked from commit f791ecd0c5)
This commit is contained in:
Yu Watanabe 2022-11-11 13:54:03 +09:00 committed by Zbigniew Jędrzejewski-Szmek
parent fdb251e0dd
commit 59cff705e7

View File

@ -646,9 +646,46 @@ static int device_is_power_sink(sd_device *device) {
return found_sink || !found_source;
}
static bool battery_is_discharging(sd_device *d) {
const char *val;
int r;
assert(d);
r = sd_device_get_sysattr_value(d, "scope", &val);
if (r < 0) {
if (r != -ENOENT)
log_device_debug_errno(d, r, "Failed to read 'scope' sysfs attribute, ignoring: %m");
} else if (streq(val, "Device")) {
log_device_debug(d, "The power supply is a device battery, ignoring device.");
return false;
}
r = device_get_sysattr_bool(d, "present");
if (r < 0)
log_device_debug_errno(d, r, "Failed to read 'present' sysfs attribute, assuming the battery is present: %m");
else if (r == 0) {
log_device_debug(d, "The battery is not present, ignoring the power supply.");
return false;
}
/* Possible values: "Unknown", "Charging", "Discharging", "Not charging", "Full" */
r = sd_device_get_sysattr_value(d, "status", &val);
if (r < 0) {
log_device_debug_errno(d, r, "Failed to read 'status' sysfs attribute, assuming the battery is discharging: %m");
return true;
}
if (!streq(val, "Discharging")) {
log_device_debug(d, "The battery status is '%s', assuming the battery is not used as a power source of this machine.", val);
return false;
}
return true;
}
int on_ac_power(void) {
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
bool found_ac_online = false, found_battery = false;
bool found_ac_online = false, found_discharging_battery = false;
sd_device *d;
int r;
@ -690,17 +727,10 @@ int on_ac_power(void) {
}
if (streq(val, "Battery")) {
r = sd_device_get_sysattr_value(d, "scope", &val);
if (r < 0) {
if (r != -ENOENT)
log_device_debug_errno(d, r, "Failed to read 'scope' sysfs attribute, ignoring: %m");
} else if (streq(val, "Device")) {
log_device_debug(d, "The power supply is a device battery, ignoring device.");
continue;
if (battery_is_discharging(d)) {
found_discharging_battery = true;
log_device_debug(d, "The power supply is a battery and currently discharging.");
}
found_battery = true;
log_device_debug(d, "The power supply is battery.");
continue;
}
@ -717,11 +747,11 @@ int on_ac_power(void) {
if (found_ac_online) {
log_debug("Found at least one online non-battery power supply, system is running on AC.");
return true;
} else if (found_battery) {
log_debug("Found battery and no online power sources, assuming system is running from battery.");
} else if (found_discharging_battery) {
log_debug("Found at least one discharging battery and no online power sources, assuming system is running from battery.");
return false;
} else {
log_debug("No power supply reported online and no battery, assuming system is running on AC.");
log_debug("No power supply reported online and no discharging battery found, assuming system is running on AC.");
return true;
}
}