summaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-06-05 11:49:35 +0200
committerLennart Poettering <lennart@poettering.net>2023-06-05 12:18:21 +0200
commitaf4e8e86ec91389a04df2b1b8621c0ad5c84917b (patch)
tree14fe71addd6fa8acaeadd9ec0954922551b12ab9 /src/shared
parentadd support for KSM (diff)
downloadsystemd-af4e8e86ec91389a04df2b1b8621c0ad5c84917b.tar.xz
systemd-af4e8e86ec91389a04df2b1b8621c0ad5c84917b.zip
battery-util: split out code that checks AC power state into its own .c/.h pair
No code change, just some splitting out of the relevant code from udev-util.[ch]. This makes sense on its own, but is also prepartion to move the code that checks for low battery state into battery-util.[ch], too.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/battery-util.c178
-rw-r--r--src/shared/battery-util.h4
-rw-r--r--src/shared/condition.c2
-rw-r--r--src/shared/meson.build1
-rw-r--r--src/shared/sleep-config.c4
-rw-r--r--src/shared/udev-util.c170
-rw-r--r--src/shared/udev-util.h2
7 files changed, 186 insertions, 175 deletions
diff --git a/src/shared/battery-util.c b/src/shared/battery-util.c
new file mode 100644
index 0000000000..aa93b531a0
--- /dev/null
+++ b/src/shared/battery-util.c
@@ -0,0 +1,178 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-device.h"
+
+#include "device-private.h"
+#include "device-util.h"
+#include "string-util.h"
+#include "battery-util.h"
+
+static int device_is_power_sink(sd_device *device) {
+ _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
+ bool found_source = false, found_sink = false;
+ sd_device *parent, *d;
+ int r;
+
+ assert(device);
+
+ /* USB-C power supply device has two power roles: source or sink. See,
+ * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-typec */
+
+ r = sd_device_enumerator_new(&e);
+ if (r < 0)
+ return r;
+
+ r = sd_device_enumerator_allow_uninitialized(e);
+ if (r < 0)
+ return r;
+
+ r = sd_device_enumerator_add_match_subsystem(e, "typec", true);
+ if (r < 0)
+ return r;
+
+ r = sd_device_get_parent(device, &parent);
+ if (r < 0)
+ return r;
+
+ r = sd_device_enumerator_add_match_parent(e, parent);
+ if (r < 0)
+ return r;
+
+ FOREACH_DEVICE(e, d) {
+ const char *val;
+
+ r = sd_device_get_sysattr_value(d, "power_role", &val);
+ if (r < 0) {
+ if (r != -ENOENT)
+ log_device_debug_errno(d, r, "Failed to read 'power_role' sysfs attribute, ignoring: %m");
+ continue;
+ }
+
+ if (strstr(val, "[source]")) {
+ found_source = true;
+ log_device_debug(d, "The USB type-C port is in power source mode.");
+ } else if (strstr(val, "[sink]")) {
+ found_sink = true;
+ log_device_debug(d, "The USB type-C port is in power sink mode.");
+ }
+ }
+
+ if (found_sink)
+ log_device_debug(device, "The USB type-C device has at least one port in power sink mode.");
+ else if (!found_source)
+ log_device_debug(device, "The USB type-C device has no port in power source mode, assuming the device is in power sink mode.");
+ else
+ log_device_debug(device, "All USB type-C ports are in power source mode.");
+
+ 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_discharging_battery = false;
+ sd_device *d;
+ int r;
+
+ r = sd_device_enumerator_new(&e);
+ if (r < 0)
+ return r;
+
+ 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) {
+ /* See
+ * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
+ * for defined power source types. Also see:
+ * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-power */
+
+ 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;
+ }
+
+ /* Ignore USB-C power supply in source mode. See issue #21988. */
+ if (streq(val, "USB")) {
+ r = device_is_power_sink(d);
+ if (r <= 0) {
+ if (r < 0)
+ log_device_debug_errno(d, r, "Failed to determine the current power role, ignoring device: %m");
+ else
+ log_device_debug(d, "USB power supply is in source mode, ignoring device.");
+ continue;
+ }
+ }
+
+ if (streq(val, "Battery")) {
+ if (battery_is_discharging(d)) {
+ found_discharging_battery = true;
+ log_device_debug(d, "The power supply is a battery and currently discharging.");
+ }
+ continue;
+ }
+
+ r = device_get_sysattr_unsigned(d, "online", NULL);
+ if (r < 0) {
+ log_device_debug_errno(d, r, "Failed to query 'online' sysfs attribute, ignoring device: %m");
+ continue;
+ } else if (r > 0) /* At least 1 and 2 are defined as different types of 'online' */
+ found_ac_online = true;
+
+ log_device_debug(d, "The power supply is currently %s.", r > 0 ? "online" : "offline");
+ }
+
+ 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_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 discharging battery found, assuming system is running on AC.");
+ return true;
+ }
+}
diff --git a/src/shared/battery-util.h b/src/shared/battery-util.h
new file mode 100644
index 0000000000..4089fff0c4
--- /dev/null
+++ b/src/shared/battery-util.h
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+int on_ac_power(void);
diff --git a/src/shared/condition.c b/src/shared/condition.c
index fce3fc2afb..9eb49d0eb5 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -18,6 +18,7 @@
#include "apparmor-util.h"
#include "architecture.h"
#include "audit-util.h"
+#include "battery-util.h"
#include "blockdev-util.h"
#include "cap-list.h"
#include "cgroup-util.h"
@@ -56,7 +57,6 @@
#include "string-util.h"
#include "tomoyo-util.h"
#include "tpm2-util.h"
-#include "udev-util.h"
#include "uid-alloc-range.h"
#include "user-util.h"
#include "virt.h"
diff --git a/src/shared/meson.build b/src/shared/meson.build
index 31241bc08d..b34d218c1e 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -6,6 +6,7 @@ shared_sources = files(
'ask-password-api.c',
'barrier.c',
'base-filesystem.c',
+ 'battery-util.c',
'binfmt-util.c',
'bitmap.c',
'blockdev-util.c',
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
index d388c89192..51aebf2f0d 100644
--- a/src/shared/sleep-config.c
+++ b/src/shared/sleep-config.c
@@ -18,6 +18,7 @@
#include "sd-device.h"
#include "alloc-util.h"
+#include "battery-util.h"
#include "blockdev-util.h"
#include "btrfs-util.h"
#include "conf-parser.h"
@@ -34,15 +35,14 @@
#include "log.h"
#include "macro.h"
#include "path-util.h"
-#include "sleep-config.h"
#include "siphash24.h"
+#include "sleep-config.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
-#include "udev-util.h"
#define BATTERY_LOW_CAPACITY_LEVEL 5
#define DISCHARGE_RATE_FILEPATH "/var/lib/systemd/sleep/battery_discharge_percentage_rate_per_hour"
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c
index 646eaf9135..088eb0fe9a 100644
--- a/src/shared/udev-util.c
+++ b/src/shared/udev-util.c
@@ -591,176 +591,6 @@ int udev_queue_init(void) {
return TAKE_FD(fd);
}
-static int device_is_power_sink(sd_device *device) {
- _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
- bool found_source = false, found_sink = false;
- sd_device *parent, *d;
- int r;
-
- assert(device);
-
- /* USB-C power supply device has two power roles: source or sink. See,
- * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-typec */
-
- r = sd_device_enumerator_new(&e);
- if (r < 0)
- return r;
-
- r = sd_device_enumerator_allow_uninitialized(e);
- if (r < 0)
- return r;
-
- r = sd_device_enumerator_add_match_subsystem(e, "typec", true);
- if (r < 0)
- return r;
-
- r = sd_device_get_parent(device, &parent);
- if (r < 0)
- return r;
-
- r = sd_device_enumerator_add_match_parent(e, parent);
- if (r < 0)
- return r;
-
- FOREACH_DEVICE(e, d) {
- const char *val;
-
- r = sd_device_get_sysattr_value(d, "power_role", &val);
- if (r < 0) {
- if (r != -ENOENT)
- log_device_debug_errno(d, r, "Failed to read 'power_role' sysfs attribute, ignoring: %m");
- continue;
- }
-
- if (strstr(val, "[source]")) {
- found_source = true;
- log_device_debug(d, "The USB type-C port is in power source mode.");
- } else if (strstr(val, "[sink]")) {
- found_sink = true;
- log_device_debug(d, "The USB type-C port is in power sink mode.");
- }
- }
-
- if (found_sink)
- log_device_debug(device, "The USB type-C device has at least one port in power sink mode.");
- else if (!found_source)
- log_device_debug(device, "The USB type-C device has no port in power source mode, assuming the device is in power sink mode.");
- else
- log_device_debug(device, "All USB type-C ports are in power source mode.");
-
- 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_discharging_battery = false;
- sd_device *d;
- int r;
-
- r = sd_device_enumerator_new(&e);
- if (r < 0)
- return r;
-
- 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) {
- /* See
- * https://github.com/torvalds/linux/blob/4eef766b7d4d88f0b984781bc1bcb574a6eafdc7/include/linux/power_supply.h#L176
- * for defined power source types. Also see:
- * https://docs.kernel.org/admin-guide/abi-testing.html#abi-file-testing-sysfs-class-power */
-
- 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;
- }
-
- /* Ignore USB-C power supply in source mode. See issue #21988. */
- if (streq(val, "USB")) {
- r = device_is_power_sink(d);
- if (r <= 0) {
- if (r < 0)
- log_device_debug_errno(d, r, "Failed to determine the current power role, ignoring device: %m");
- else
- log_device_debug(d, "USB power supply is in source mode, ignoring device.");
- continue;
- }
- }
-
- if (streq(val, "Battery")) {
- if (battery_is_discharging(d)) {
- found_discharging_battery = true;
- log_device_debug(d, "The power supply is a battery and currently discharging.");
- }
- continue;
- }
-
- r = device_get_sysattr_unsigned(d, "online", NULL);
- if (r < 0) {
- log_device_debug_errno(d, r, "Failed to query 'online' sysfs attribute, ignoring device: %m");
- continue;
- } else if (r > 0) /* At least 1 and 2 are defined as different types of 'online' */
- found_ac_online = true;
-
- log_device_debug(d, "The power supply is currently %s.", r > 0 ? "online" : "offline");
- }
-
- 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_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 discharging battery found, assuming system is running on AC.");
- return true;
- }
-}
-
bool udev_available(void) {
static int cache = -1;
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index c3c3dbe842..175fa0b6f0 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -55,8 +55,6 @@ bool devpath_conflict(const char *a, const char *b);
int udev_queue_is_empty(void);
int udev_queue_init(void);
-int on_ac_power(void);
-
bool udev_available(void);
#if HAVE_SYS_SDT_H