diff --git a/man/initrd-battery-check.service.xml b/man/initrd-battery-check.service.xml
new file mode 100644
index 0000000000..582b2269fb
--- /dev/null
+++ b/man/initrd-battery-check.service.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ systemd-battery-check
+ systemd
+
+
+
+ initrd-battery-check.service
+ 8
+
+
+
+ initrd-battery-check.service
+ systemd-battery-check
+ Check battery level whether there's enough charge, and power off if not.
+
+
+
+ initrd-battery-check.service
+
+ /usr/lib/systemd/systemd-battery-check
+ OPTIONS
+
+
+
+
+ Description
+
+
+ initrd-battery-check.service is used to check the battery level during the early
+ boot stage to determine whether there's sufficient battery power to carry on with the booting process.
+
+
+ systemd-battery-check returns success if the device is connected to an AC power
+ source or if the battery charge is greater than 5%. It returns failure otherwise.
+
+
+
+
+ Options
+
+ The following options are understood by systemd-battery-check:
+
+
+
+
+
+
+
+
+ Exit status
+
+
+ On success (running on AC power or battery capacity greater than 5%), 0 is returned, a non-zero failure
+ code otherwise.
+
+
+
+
+ See Also
+
+ systemd1
+
+
+
+
diff --git a/man/rules/meson.build b/man/rules/meson.build
index f924f551eb..e5a36c43d8 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -23,6 +23,7 @@ manpages = [
['hostname', '5', [], ''],
['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
['hwdb', '7', [], 'ENABLE_HWDB'],
+ ['initrd-battery-check.service', '8', ['systemd-battery-check'], ''],
['integritytab', '5', [], 'HAVE_LIBCRYPTSETUP'],
['iocost.conf', '5', [], ''],
['journal-remote.conf', '5', ['journal-remote.conf.d'], 'HAVE_MICROHTTPD'],
@@ -887,7 +888,6 @@ manpages = [
''],
['systemd-ask-password', '1', [], ''],
['systemd-backlight@.service', '8', ['systemd-backlight'], 'ENABLE_BACKLIGHT'],
- ['systemd-battery-check', '1', [], ''],
['systemd-binfmt.service', '8', ['systemd-binfmt'], 'ENABLE_BINFMT'],
['systemd-bless-boot-generator', '8', [], 'ENABLE_BOOTLOADER'],
['systemd-bless-boot.service',
diff --git a/man/systemd-battery-check.xml b/man/systemd-battery-check.xml
deleted file mode 100644
index 58719c795c..0000000000
--- a/man/systemd-battery-check.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
- systemd-battery-check
- systemd
-
-
-
- systemd-battery-check
- 1
-
-
-
- systemd-battery-check
- Checks battery level to see whether there's enough charge.
-
-
-
-
- systemd-battery-check
- OPTIONS
-
-
-
-
- Description
-
- systemd-battery-check is used to check the battery level during the early boot
- stage to determine whether there's sufficient battery power to carry on with the booting process.
- The tool returns success if the device is connected to an AC power source
- or if the battery charge is greater than 5%. It returns failure otherwise.
-
-
-
- Options
-
- The following options are understood:
-
-
-
-
-
-
-
-
- Exit status
-
- On success (running on AC power or battery capacity greater than 5%), 0 is returned, a non-zero failure code otherwise.
-
-
-
- See Also
-
- systemd1
-
-
-
-
diff --git a/src/basic/glyph-util.h b/src/basic/glyph-util.h
index 876a5a91e6..e26ef64c18 100644
--- a/src/basic/glyph-util.h
+++ b/src/basic/glyph-util.h
@@ -50,18 +50,14 @@ typedef enum SpecialGlyph {
_SPECIAL_GLYPH_INVALID = -EINVAL,
} SpecialGlyph;
-const char *special_glyph_full(SpecialGlyph code, bool force_utf) _const_;
-
bool emoji_enabled(void);
+const char *special_glyph_full(SpecialGlyph code, bool force_utf) _const_;
+
static inline const char *special_glyph(SpecialGlyph code) {
return special_glyph_full(code, false);
}
-static inline const char *special_glyph_force_utf(SpecialGlyph code) {
- return special_glyph_full(code, true);
-}
-
static inline const char *special_glyph_check_mark(bool b) {
return b ? special_glyph(SPECIAL_GLYPH_CHECK_MARK) : special_glyph(SPECIAL_GLYPH_CROSS_MARK);
}
diff --git a/src/battery-check/battery-check.c b/src/battery-check/battery-check.c
index 14bb870ca4..ca13251ae0 100644
--- a/src/battery-check/battery-check.c
+++ b/src/battery-check/battery-check.c
@@ -14,47 +14,74 @@
#include "io-util.h"
#include "log.h"
#include "main-func.h"
+#include "pretty-print.h"
#include "socket-util.h"
#include "terminal-util.h"
+#include "time-util.h"
+
+#define BATTERY_LOW_MESSAGE \
+ "Battery level critically low. Please connect your charger or the system will power off in 10 seconds."
+#define BATTERY_RESTORED_MESSAGE \
+ "A.C. power restored, continuing."
+
+static int help(void) {
+ _cleanup_free_ char *link = NULL;
+ int r;
+
+ r = terminal_urlify_man("systemd-battery-check", "8", &link);
+ if (r < 0)
+ return log_oom();
-static void help(void) {
printf("%s\n\n"
- "Checks battery level to see whether there's enough charge.\n\n"
+ "%sCheck battery level to see whether there's enough charge.%s\n\n"
" -h --help Show this help\n"
- " --version Show package version\n",
- program_invocation_short_name);
+ " --version Show package version\n"
+ "\nSee the %s for details.\n",
+ program_invocation_short_name,
+ ansi_highlight(),
+ ansi_normal(),
+ link);
+
+ return 0;
}
-static void battery_check_send_plymouth_message(char *message, const char *mode) {
- assert(message);
- assert(mode);
+static bool ERRNO_IS_NO_PLYMOUTH(int r) {
+ return IN_SET(abs(r), EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(r);
+}
- int r;
+static int plymouth_send_message(const char *mode, const char *message) {
static const union sockaddr_union sa = PLYMOUTH_SOCKET;
- _cleanup_close_ int fd = -EBADF;
_cleanup_free_ char *plymouth_message = NULL;
+ _cleanup_close_ int fd = -EBADF;
+ int c, r;
- int c = asprintf(&plymouth_message,
- "C\x02%c%s%c"
- "M\x02%c%s%c",
- (int) strlen(mode) + 1, mode, '\x00',
- (int) strlen(message) + 1, message, '\x00');
+ assert(mode);
+ assert(message);
+
+ c = asprintf(&plymouth_message,
+ "C\x02%c%s%c"
+ "M\x02%c%s%c",
+ (int) strlen(mode) + 1, mode, '\x00',
+ (int) strlen(message) + 1, message, '\x00');
if (c < 0)
- return (void) log_oom();
+ return log_oom();
/* We set SOCK_NONBLOCK here so that we rather drop the
* message than wait for plymouth */
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0)
- return (void) log_warning_errno(errno, "socket() failed: %m");
+ return log_warning_errno(errno, "socket() failed: %m");
if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
- return (void) log_full_errno(IN_SET(errno, EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(errno) ? LOG_DEBUG : LOG_WARNING, errno, "Connection to plymouth failed: %m");
+ return log_full_errno(ERRNO_IS_NO_PLYMOUTH(errno) ? LOG_DEBUG : LOG_WARNING, errno,
+ "Failed to connect to plymouth: %m");
r = loop_write(fd, plymouth_message, c, /* do_poll = */ false);
if (r < 0)
- return (void) log_full_errno(IN_SET(r, -EAGAIN, -ENOENT) || ERRNO_IS_DISCONNECT(r) ?
-LOG_DEBUG : LOG_WARNING, r, "Failed to write to plymouth, ignoring: %m");
+ return log_full_errno(ERRNO_IS_NO_PLYMOUTH(r) ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to write to plymouth: %m");
+
+ return 0;
}
static int parse_argv(int argc, char * argv[]) {
@@ -79,8 +106,7 @@ static int parse_argv(int argc, char * argv[]) {
switch (c) {
case 'h':
- help();
- return 0;
+ return help();
case ARG_VERSION:
return version();
@@ -100,10 +126,11 @@ static int parse_argv(int argc, char * argv[]) {
}
static int run(int argc, char *argv[]) {
+ _cleanup_free_ char *plymouth_message = NULL;
+ _cleanup_close_ int fd = -EBADF;
int r;
- log_parse_environment();
- log_open();
+ log_setup();
r = parse_argv(argc, argv);
if (r <= 0)
@@ -114,44 +141,40 @@ static int run(int argc, char *argv[]) {
log_warning_errno(r, "Failed to check battery status, ignoring: %m");
return 0;
}
+ if (r == 0)
+ return 0;
+ log_emergency("%s " BATTERY_LOW_MESSAGE, special_glyph(SPECIAL_GLYPH_LOW_BATTERY));
+
+ fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
+ if (fd < 0)
+ log_warning_errno(fd, "Failed to open console, ignoring: %m");
+ else
+ dprintf(fd, ANSI_HIGHLIGHT_RED "%s " BATTERY_LOW_MESSAGE ANSI_NORMAL "\n",
+ special_glyph_full(SPECIAL_GLYPH_LOW_BATTERY, /* force_utf = */ false));
+
+ if (asprintf(&plymouth_message, "%s " BATTERY_LOW_MESSAGE,
+ special_glyph_full(SPECIAL_GLYPH_LOW_BATTERY, /* force_utf = */ true)) < 0)
+ return log_oom();
+
+ (void) plymouth_send_message("shutdown", plymouth_message);
+
+ usleep_safe(10 * USEC_PER_SEC);
+
+ r = battery_is_discharging_and_low();
+ if (r < 0)
+ return log_warning_errno(r, "Failed to check battery status, assuming not charged yet, powering off: %m");
if (r > 0) {
- _cleanup_close_ int fd = -EBADF;
- _cleanup_free_ char *message = NULL, *plymouth_message = NULL, *ac_message = NULL;
-
- if (asprintf(&message, "%s Battery level critically low. Please connect your charger or the system will power off in 10 seconds.", special_glyph(SPECIAL_GLYPH_LOW_BATTERY)) < 0)
- return log_oom();
-
- if (asprintf(&plymouth_message, "%s Battery level critically low. Please connect your charger or the system will power off in 10 seconds.", special_glyph_force_utf(SPECIAL_GLYPH_LOW_BATTERY)) < 0)
- return log_oom();
-
- log_emergency("%s", message);
-
- fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- log_warning_errno(fd, "Failed to open console, ignoring: %m");
- else
- dprintf(fd, ANSI_HIGHLIGHT_RED "%s" ANSI_NORMAL "\n", message);
-
- battery_check_send_plymouth_message(plymouth_message, "shutdown");
- sleep(10);
-
- r = battery_is_discharging_and_low();
- if (r > 0) {
- log_emergency("Battery level critically low, powering off.");
- return r;
- }
- if (r < 0)
- return log_warning_errno(r, "Failed to check battery status, ignoring: %m");
-
- if (asprintf(&ac_message, "A.C. power restored, continuing") < 0)
- return log_oom();
-
- log_info("%s",ac_message);
- dprintf(fd, "%s\n", ac_message);
- battery_check_send_plymouth_message(ac_message, "boot-up");
+ log_emergency("Battery level critically low, powering off.");
+ return r;
}
- return r;
+
+ log_info(BATTERY_RESTORED_MESSAGE);
+ if (fd >= 0)
+ dprintf(fd, BATTERY_RESTORED_MESSAGE "\n");
+ (void) plymouth_send_message("boot-up", BATTERY_RESTORED_MESSAGE);
+
+ return 0;
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
diff --git a/test/units/testsuite-74.battery-check.sh b/test/units/testsuite-74.battery-check.sh
new file mode 100755
index 0000000000..ec5a0c86e6
--- /dev/null
+++ b/test/units/testsuite-74.battery-check.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eux
+set -o pipefail
+
+systemd-battery-check --help
+systemd-battery-check --version
+
+systemd-battery-check || :
diff --git a/units/initrd-battery-check.service.in b/units/initrd-battery-check.service.in
index 4b14049746..052586f3c7 100644
--- a/units/initrd-battery-check.service.in
+++ b/units/initrd-battery-check.service.in
@@ -9,7 +9,7 @@
[Unit]
Description=Check battery level during early boot
-Documentation=man:systemd-battery-check(1)
+Documentation=man:initrd-battery-check.service(8)
DefaultDependencies=no
AssertPathExists=/etc/initrd-release
Before=local-fs-pre.target