From dbfaed242ef889b62598938c622879fdd893a8d6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 5 Jan 2022 08:29:00 +0900 Subject: [PATCH] udev-util: re-implement on_ac_power() with sd-device (cherry picked from commit 01d4ad3bde9efbbc5856846fea328ee9bbcef87e) --- src/shared/udev-util.c | 75 ++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 73ca886fb3..800493afe9 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -10,12 +9,10 @@ #include "device-nodes.h" #include "device-private.h" #include "device-util.h" -#include "dirent-util.h" #include "env-file.h" #include "errno-util.h" #include "escape.h" #include "fd-util.h" -#include "fileio.h" #include "log.h" #include "macro.h" #include "parse-util.h" @@ -584,60 +581,68 @@ int udev_queue_init(void) { } int on_ac_power(void) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; bool found_offline = false, found_online = false; - _cleanup_closedir_ DIR *d = NULL; + sd_device *d; int r; - d = opendir("/sys/class/power_supply"); - if (!d) - return errno == ENOENT ? true : -errno; + r = sd_device_enumerator_new(&e); + if (r < 0) + return r; - FOREACH_DIRENT(de, d, return -errno) { - _cleanup_close_ int device_fd = -1; - _cleanup_free_ char *contents = NULL; + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_subsystem(e, "power_supply", true); + if (r < 0) + return r; + + FOREACH_DEVICE(e, d) { + const char *val; unsigned v; - device_fd = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC); - if (device_fd < 0) { - if (IN_SET(errno, ENOENT, ENOTDIR)) - continue; - - return -errno; - } - - r = read_virtual_file_at(device_fd, "type", SIZE_MAX, &contents, NULL); - if (r == -ENOENT) + 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: %m"); continue; - if (r < 0) - return r; - - delete_trailing_chars(contents, NEWLINE); + } /* We assume every power source is AC, except for batteries. 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(contents, "Battery")) + if (streq(val, "Battery")) { + log_device_debug(d, "The power supply is battery, ignoring."); continue; + } - contents = mfree(contents); - - r = read_virtual_file_at(device_fd, "online", SIZE_MAX, &contents, NULL); - if (r == -ENOENT) + 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: %m"); continue; - if (r < 0) - return r; + } - delete_trailing_chars(contents, NEWLINE); + r = safe_atou(val, &v); + if (r < 0) { + log_device_debug_errno(d, r, "Failed to parse 'online' attribute, ignoring: %m"); + continue; + } - r = safe_atou(contents, &v); - if (r < 0) - return r; 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"); } + 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 + log_debug("All non-battery power supplies are offline, assuming system is running with battery."); + return found_online || !found_offline; }