summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-06-25 16:07:33 +0200
committerLennart Poettering <lennart@poettering.net>2018-10-19 22:34:50 +0200
commitf876f53789380cb2c096e3c09401f7273387d1d2 (patch)
tree1a15cb86c3a4b258a7f9120d2fe1883c4b909e51
parentman: update kernel-install(8) documentation (diff)
downloadsystemd-f876f53789380cb2c096e3c09401f7273387d1d2.tar.xz
systemd-f876f53789380cb2c096e3c09401f7273387d1d2.zip
units: add simple boot check unit
This is might be useful in some cases, but it's primarily an example for a boot check service that can be plugged before boot-complete.target. It's disabled by default. All it does is check whether the failed unit count is zero
-rw-r--r--meson.build9
-rw-r--r--src/boot/boot-check-no-failures.c106
-rw-r--r--units/meson.build1
-rw-r--r--units/systemd-boot-check-no-failures.service.in24
4 files changed, 140 insertions, 0 deletions
diff --git a/meson.build b/meson.build
index 059a261813..7960e97893 100644
--- a/meson.build
+++ b/meson.build
@@ -1815,6 +1815,15 @@ if conf.get('ENABLE_EFI') == 1 and conf.get('HAVE_BLKID') == 1
install_dir : systemgeneratordir)
endif
+executable('systemd-boot-check-no-failures',
+ 'src/boot/boot-check-no-failures.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libblkid],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
exe = executable('systemd-socket-activate', 'src/activate/activate.c',
include_directories : includes,
link_with : [libshared],
diff --git a/src/boot/boot-check-no-failures.c b/src/boot/boot-check-no-failures.c
new file mode 100644
index 0000000000..e7884461c6
--- /dev/null
+++ b/src/boot/boot-check-no-failures.c
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sd-bus.h"
+
+#include "alloc-util.h"
+#include "bus-error.h"
+#include "log.h"
+#include "util.h"
+
+static int help(void) {
+
+ printf("%s [COMMAND] [OPTIONS...]\n"
+ "\n"
+ "Verify system operational state.\n\n"
+ " -h --help Show this help\n"
+ " --version Print version\n",
+ program_invocation_short_name);
+
+ return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+ enum {
+ ARG_PATH = 0x100,
+ ARG_VERSION,
+ };
+
+ static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ {}
+ };
+
+ int c;
+
+ assert(argc >= 0);
+ assert(argv);
+
+ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+ switch (c) {
+
+ case 'h':
+ help();
+ return 0;
+
+ case ARG_VERSION:
+ return version();
+
+ case '?':
+ return -EINVAL;
+
+ default:
+ assert_not_reached("Unknown option");
+ }
+
+ return 1;
+}
+
+int main(int argc, char *argv[]) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ uint32_t n;
+ int r;
+
+ log_parse_environment();
+ log_open();
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto finish;
+
+ r = sd_bus_open_system(&bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to connect to system bus: %m");
+ goto finish;
+ }
+
+ r = sd_bus_get_property_trivial(
+ bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "NFailedUnits",
+ &error,
+ 'u',
+ &n);
+ if (r < 0) {
+ log_error_errno(r, "Failed to get failed units counter: %s", bus_error_message(&error, r));
+ goto finish;
+ }
+
+ if (n > 0)
+ log_notice("Health check: %" PRIu32 " units have failed.", n);
+ else
+ log_info("Health check: no failed units.");
+
+ r = n > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+
+finish:
+ return r < 0 ? EXIT_FAILURE : r;
+}
diff --git a/units/meson.build b/units/meson.build
index 26a725b575..d69508467f 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -137,6 +137,7 @@ in_units = [
['systemd-binfmt.service', 'ENABLE_BINFMT',
'sysinit.target.wants/'],
['systemd-bless-boot.service', 'ENABLE_EFI HAVE_BLKID'],
+ ['systemd-boot-check-no-failures.service', ''],
['systemd-coredump@.service', 'ENABLE_COREDUMP'],
['systemd-firstboot.service', 'ENABLE_FIRSTBOOT',
'sysinit.target.wants/'],
diff --git a/units/systemd-boot-check-no-failures.service.in b/units/systemd-boot-check-no-failures.service.in
new file mode 100644
index 0000000000..27e898b85b
--- /dev/null
+++ b/units/systemd-boot-check-no-failures.service.in
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: LGPL-2.1+
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Check if Any System Units Failed
+Documentation=man:systemd-boot-check-no-failures.service(8)
+After=default.target graphical.target multi-user.target
+Before=boot-complete.target
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-boot-check-no-failures
+
+[Install]
+RequiredBy=boot-complete.target