mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-12 21:57:27 +03:00
on-ac-power: rework logic
History of the function: 96788d2aa4f4b0b49874b4a240ce47d9e8485d1b assume system is running on AC power when no battery found 795e86b4f1e8a1fd440f8c817621779c6aedbdb5 ignore USB-C ports in power source mode when detecting system is running on AC power c19a51bec40ae5e5073464e72411e7920d05d683 invert ac_power() source type check 6d89003462484c8656b698e07b9cf0a337e3818e assume ac when /sys/class/power_supply is missing 240dbaa44f8e5ad51775c776fc3ce9cd2f19f037 add ConditionACPower= Interestingly, the return condition 'on_ac_power == found_online || !found_offline' was there from the very beginning, and even Yu's latest change doesn't change this, but only extends it to 'on_ac_power == found_online || !found_offline || !found_battery'. This means that any system with no AC power supply will be unconditionally classified as on_ac_power. Let's change the logic: if we have an online AC supply, answer is "yes". If no supplies, but we have a battery, answer is "no". Otherwise, assume "yes", based on the assumption that presense of a battery would at least be always reported, even if an AC power supply might not be. Fixes #24407. It also shouldn't impact previous fixes: assume ac when /sys/class/power_supply is missing, ignore USB-C ports in power source mode, assume system is running on AC power when no battery found. (cherry picked from commit 4a52514b371bf8013e89c421dfc2405a443feef8) (cherry picked from commit 9886011356f9cd3737263b5bf9070181c7859f26)
This commit is contained in:
parent
3ce09d9127
commit
9e62e7facb
@ -641,9 +641,28 @@ static int device_is_power_sink(sd_device *device) {
|
||||
return found_sink || !found_source;
|
||||
}
|
||||
|
||||
static int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) {
|
||||
const char *value;
|
||||
int r;
|
||||
|
||||
r = sd_device_get_sysattr_value(device, sysattr, &value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unsigned v;
|
||||
r = safe_atou(value, &v);
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr);
|
||||
|
||||
if (ret_value)
|
||||
*ret_value = v;
|
||||
/* We return "true" if the value is positive. */
|
||||
return v > 0;
|
||||
}
|
||||
|
||||
int on_ac_power(void) {
|
||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||
bool found_offline = false, found_online = false, found_battery = false;
|
||||
bool found_ac_online = false, found_battery = false;
|
||||
sd_device *d;
|
||||
int r;
|
||||
|
||||
@ -660,22 +679,15 @@ int on_ac_power(void) {
|
||||
return r;
|
||||
|
||||
FOREACH_DEVICE(e, d) {
|
||||
const char *val;
|
||||
unsigned v;
|
||||
|
||||
r = sd_device_get_sysattr_value(d, "type", &val);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to read 'type' sysfs attribute, ignoring device: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We assume every power source is AC, except for batteries. See
|
||||
/* See
|
||||
* https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
|
||||
* for defined power source types. Also see:
|
||||
* https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-power */
|
||||
if (streq(val, "Battery")) {
|
||||
found_battery = true;
|
||||
log_device_debug(d, "The power supply is battery, ignoring device.");
|
||||
|
||||
const char *val;
|
||||
r = sd_device_get_sysattr_value(d, "type", &val);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to read 'type' sysfs attribute, ignoring device: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -691,36 +703,33 @@ int on_ac_power(void) {
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_device_get_sysattr_value(d, "online", &val);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to read 'online' sysfs attribute, ignoring device: %m");
|
||||
bool is_battery = streq(val, "Battery");
|
||||
if (is_battery) {
|
||||
found_battery = true;
|
||||
log_device_debug(d, "The power supply is battery.");
|
||||
continue;
|
||||
}
|
||||
|
||||
r = safe_atou(val, &v);
|
||||
r = device_get_sysattr_unsigned(d, "online", NULL);
|
||||
if (r < 0) {
|
||||
log_device_debug_errno(d, r, "Failed to parse 'online' attribute, ignoring device: %m");
|
||||
log_device_debug_errno(d, r, "Failed to query 'online' sysfs attribute: %m");
|
||||
continue;
|
||||
}
|
||||
} else if (r > 0) /* At least 1 and 2 are defined as different types of 'online' */
|
||||
found_ac_online = true;
|
||||
|
||||
if (v > 0) /* At least 1 and 2 are defined as different types of 'online' */
|
||||
found_online = true;
|
||||
else
|
||||
found_offline = true;
|
||||
|
||||
log_device_debug(d, "The power supply is currently %s.", v > 0 ? "online" : "offline");
|
||||
log_device_debug(d, "The power supply is currently %s.", r > 0 ? "online" : "offline");
|
||||
}
|
||||
|
||||
if (found_online)
|
||||
log_debug("Found at least one online non-battery power supply, system is running on AC power.");
|
||||
else if (!found_offline)
|
||||
log_debug("Found no offline non-battery power supply, assuming system is running on AC power.");
|
||||
else if (!found_battery)
|
||||
log_debug("Found no battery, assuming system is running on AC power.");
|
||||
else
|
||||
log_debug("All non-battery power supplies are offline, assuming system is running with battery.");
|
||||
|
||||
return found_online || !found_offline || !found_battery;
|
||||
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.");
|
||||
return false;
|
||||
} else {
|
||||
log_debug("No power supply reported online and no battery, assuming system is running on AC.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool udev_available(void) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user