summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-01-05 08:29:00 +0900
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-01-07 15:59:25 +0100
commitdbfaed242ef889b62598938c622879fdd893a8d6 (patch)
treef039ea5151c95ff2860aef510425d04416ab79ea
parent435bd3077ab807e61f2777626edb540dae1025f5 (diff)
downloadsystemd-dbfaed242ef889b62598938c622879fdd893a8d6.tar.gz
udev-util: re-implement on_ac_power() with sd-device
(cherry picked from commit 01d4ad3bde9efbbc5856846fea328ee9bbcef87e)
-rw-r--r--src/shared/udev-util.c73
1 files changed, 39 insertions, 34 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 <ctype.h>
#include <errno.h>
-#include <fcntl.h>
#include <sys/inotify.h>
#include <unistd.h>
@@ -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;
- unsigned v;
+ r = sd_device_enumerator_allow_uninitialized(e);
+ if (r < 0)
+ return r;
- 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;
+ r = sd_device_enumerator_add_match_subsystem(e, "power_supply", true);
+ if (r < 0)
+ return r;
- return -errno;
- }
+ FOREACH_DEVICE(e, d) {
+ const char *val;
+ unsigned v;
- 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;
}