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
This commit is contained in:
Lennart Poettering 2018-06-25 16:07:33 +02:00
parent 4b2d80bb0a
commit f876f53789
4 changed files with 140 additions and 0 deletions

View File

@ -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],

View File

@ -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;
}

View File

@ -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/'],

View File

@ -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