From f876f53789380cb2c096e3c09401f7273387d1d2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Jun 2018 16:07:33 +0200 Subject: [PATCH] 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 --- meson.build | 9 ++ src/boot/boot-check-no-failures.c | 106 ++++++++++++++++++++++++ units/meson.build | 1 + units/systemd-boot-check-no-failures.service.in | 24 ++++++ 4 files changed, 140 insertions(+) create mode 100644 src/boot/boot-check-no-failures.c create mode 100644 units/systemd-boot-check-no-failures.service.in diff --git a/meson.build b/meson.build index 059a261..7960e97 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 0000000..e788446 --- /dev/null +++ b/src/boot/boot-check-no-failures.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include +#include +#include + +#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 26a725b..d695084 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 0000000..27e898b --- /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 -- 2.7.4