1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <getopt.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 #include "sd-bus.h"
9
10 #include "alloc-util.h"
11 #include "bus-error.h"
12 #include "log.h"
13 #include "main-func.h"
14 #include "pretty-print.h"
15 #include "terminal-util.h"
16 #include "util.h"
17
help(void)18 static int help(void) {
19 _cleanup_free_ char *link = NULL;
20 int r;
21
22 r = terminal_urlify_man("systemd-boot-check-no-failures.service", "8", &link);
23 if (r < 0)
24 return log_oom();
25
26 printf("%s [OPTIONS...]\n"
27 "\n%sVerify system operational state.%s\n\n"
28 " -h --help Show this help\n"
29 " --version Print version\n"
30 "\nSee the %s for details.\n",
31 program_invocation_short_name,
32 ansi_highlight(),
33 ansi_normal(),
34 link);
35
36 return 0;
37 }
38
parse_argv(int argc,char * argv[])39 static int parse_argv(int argc, char *argv[]) {
40 enum {
41 ARG_PATH = 0x100,
42 ARG_VERSION,
43 };
44
45 static const struct option options[] = {
46 { "help", no_argument, NULL, 'h' },
47 { "version", no_argument, NULL, ARG_VERSION },
48 {}
49 };
50
51 int c;
52
53 assert(argc >= 0);
54 assert(argv);
55
56 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
57 switch (c) {
58
59 case 'h':
60 help();
61 return 0;
62
63 case ARG_VERSION:
64 return version();
65
66 case '?':
67 return -EINVAL;
68
69 default:
70 assert_not_reached();
71 }
72
73 return 1;
74 }
75
run(int argc,char * argv[])76 static int run(int argc, char *argv[]) {
77 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
78 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
79 uint32_t n;
80 int r;
81
82 log_parse_environment();
83 log_open();
84
85 r = parse_argv(argc, argv);
86 if (r <= 0)
87 return r;
88
89 r = sd_bus_open_system(&bus);
90 if (r < 0)
91 return log_error_errno(r, "Failed to connect to system bus: %m");
92
93 r = sd_bus_get_property_trivial(
94 bus,
95 "org.freedesktop.systemd1",
96 "/org/freedesktop/systemd1",
97 "org.freedesktop.systemd1.Manager",
98 "NFailedUnits",
99 &error,
100 'u',
101 &n);
102 if (r < 0)
103 return log_error_errno(r, "Failed to get failed units counter: %s", bus_error_message(&error, r));
104
105 if (n > 0)
106 log_notice("Health check: %" PRIu32 " units have failed.", n);
107 else
108 log_info("Health check: no failed units.");
109
110 return n > 0;
111 }
112
113 DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
114