X Tutup
Skip to content

Commit 3cc3dc7

Browse files
committed
systemd-analyze: option to exit with an error when 'verify' fails
The commit introduces a callback invoked from log_syntax_internal. Use it from systemd-analyze to gather a list of units that contain syntax warnings. A new command line option is added to make use of this. The new option --recursive-errors takes in three possible modes: 1. yes - which is the default. systemd-analyze exits with an error when syntax warnings arise during verification of the specified units or any of their dependencies. 3. no - systemd-analyze exits with an error when syntax warnings arise during verification of only the selected unit. Analyzing and loading any dependencies will be skipped. 4. one - systemd-analyze exits with an error when syntax warnings arise during verification of only the selected units and their direct dependencies. Below are two service unit files that I created for the purposes of testing: 1. First, we run the commands on a unit that does not have dependencies but has a non-existing key-value setting (i.e. foo = bar). > cat <<EOF>testcase.service [Unit] foo = bar [Service] ExecStart = echo hello EOF OUTPUT: maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify testcase.service /home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring. /usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed. /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly. /usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1 maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=yes testcase.service /home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring. /usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed. /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly. /usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1 maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=no testcase.service /home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1 maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=one testcase.service /home/maanya-goenka/systemd/testcase.service:2: Unknown key name 'foo' in section 'Unit', ignoring. /usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed. /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly. /usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1 2. Next, we run the commands on a unit that is syntactically valid but has a non-existing dependency (i.e. foo2.service) > cat <<EOF>foobar.service [Unit] Requires = foo2.service [Service] ExecStart = echo hello EOF OUTPUT: maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify foobar.service /usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed. /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly. /usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether. foobar.service: Failed to create foobar.service/start: Unit foo2.service not found. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1 maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=yes foobar.service /usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed. /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly. /usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether. foobar.service: Failed to create foobar.service/start: Unit foo2.service not found. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1 maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=no foobar.service maanya-goenka@debian:~/systemd (log-error)$ echo $? 0 maanya-goenka@debian:~/systemd (log-error)$ sudo build/systemd-analyze verify --recursive-errors=one foobar.service /usr/lib/systemd/system/plymouth-start.service:15: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed. /usr/lib/systemd/system/dbus.socket:5: ListenStream= references a path below legacy directory /var/run/, updating /var/run/dbus/system_bus_socket → /run/dbus/system_bus_socket; please update the unit file accordingly. /usr/lib/systemd/system/gdm.service:30: Standard output type syslog is obsolete, automatically updating to journal. Please update your unit file, and consider removing the setting altogether. foobar.service: Failed to create foobar.service/start: Unit foo2.service not found. maanya-goenka@debian:~/systemd (log-error)$ echo $? 1
1 parent f14d681 commit 3cc3dc7

File tree

9 files changed

+199
-60
lines changed

9 files changed

+199
-60
lines changed

man/systemd-analyze.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,18 @@ Service b@0.service not loaded, b.socket cannot be started.
744744
generators enabled will generally result in some warnings.</para></listitem>
745745
</varlistentry>
746746

747+
<varlistentry>
748+
<term><option>--recursive-errors=<replaceable>MODE</replaceable></option></term>
749+
750+
<listitem><para>Control verification of units and their dependencies and whether
751+
<command>systemd-analyze verify</command> exits with a non-zero process exit status or not. With
752+
<command>yes</command>, return a non-zero process exit status when warnings arise during verification
753+
of either the specified unit or any of its associated dependencies. This is the default. With
754+
<command>no</command>, return a non-zero process exit status when warnings arise during verification
755+
of only the specified unit. With <command>one</command>, return a non-zero process exit status when
756+
warnings arise during verification of either the specified unit or its immediate dependencies. </para></listitem>
757+
</varlistentry>
758+
747759
<varlistentry>
748760
<term><option>--root=<replaceable>PATH</replaceable></option></term>
749761

shell-completion/bash/systemd-analyze

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ _systemd_analyze() {
125125

126126
elif __contains_word "$verb" ${VERBS[VERIFY]}; then
127127
if [[ $cur = -* ]]; then
128-
comps='--help --version --system --user --global --man=no --generators=yes --root --image'
128+
comps='--help --version --system --user --global --man=no --generators=yes --root --image --recursive-errors=no --recursive-errors=yes --recursive-errors=one'
129129
else
130130
comps=$( compgen -A file -- "$cur" )
131131
compopt -o filenames

shell-completion/zsh/_systemd-analyze

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ _arguments \
8989
'--global[Show global user instance config]' \
9090
'--root=[Add support for root argument]:PATH' \
9191
'--image=[Add support for discrete images]:PATH' \
92+
'--recursive-errors=[When verifying a unit, control dependency verification]:MODE' \
9293
'--no-pager[Do not pipe output into a pager]' \
9394
'--man=[Do (not) check for existence of man pages]:boolean:(1 0)' \
9495
'--order[When generating graph for dot, show only order]' \

src/analyze/analyze-verify.c

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,28 @@
1111
#include "manager.h"
1212
#include "pager.h"
1313
#include "path-util.h"
14+
#include "string-table.h"
1415
#include "strv.h"
1516
#include "unit-name.h"
1617
#include "unit-serialize.h"
1718

19+
static void log_syntax_callback(const char *unit, int level, void *userdata) {
20+
Set **s = userdata;
21+
int r;
22+
23+
assert(userdata);
24+
assert(unit);
25+
26+
if (level > LOG_WARNING)
27+
return;
28+
29+
r = set_put_strdup(s, unit);
30+
if (r < 0) {
31+
set_free_free(*s);
32+
*s = POINTER_MAX;
33+
}
34+
}
35+
1836
static int prepare_filename(const char *filename, char **ret) {
1937
int r;
2038
const char *name;
@@ -218,13 +236,22 @@ static int verify_unit(Unit *u, bool check_man, const char *root) {
218236
return r;
219237
}
220238

221-
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root) {
239+
static void set_destroy_ignore_pointer_max(Set** s) {
240+
if (*s == POINTER_MAX)
241+
return;
242+
set_free_free(*s);
243+
}
244+
245+
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root) {
222246
const ManagerTestRunFlags flags =
223247
MANAGER_TEST_RUN_MINIMAL |
224248
MANAGER_TEST_RUN_ENV_GENERATORS |
249+
(recursive_errors == RECURSIVE_ERRORS_NO) * MANAGER_TEST_RUN_IGNORE_DEPENDENCIES |
225250
run_generators * MANAGER_TEST_RUN_GENERATORS;
226251

227252
_cleanup_(manager_freep) Manager *m = NULL;
253+
_cleanup_(set_destroy_ignore_pointer_max) Set *s = NULL;
254+
_unused_ _cleanup_(clear_log_syntax_callback) dummy_t dummy;
228255
Unit *units[strv_length(filenames)];
229256
_cleanup_free_ char *var = NULL;
230257
int r, k, i, count = 0;
@@ -233,6 +260,11 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
233260
if (strv_isempty(filenames))
234261
return 0;
235262

263+
/* Allow systemd-analyze to hook in a callback function so that it can get
264+
* all the required log data from the function itself without having to rely
265+
* on a global set variable for the same */
266+
set_log_syntax_callback(log_syntax_callback, &s);
267+
236268
/* set the path */
237269
r = generate_path(&var, filenames);
238270
if (r < 0)
@@ -283,5 +315,34 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
283315
r = k;
284316
}
285317

286-
return r;
318+
if (s == POINTER_MAX)
319+
return log_oom();
320+
321+
if (set_isempty(s) || r != 0)
322+
return r;
323+
324+
/* If all previous verifications succeeded, then either the recursive parsing of all the
325+
* associated dependencies with RECURSIVE_ERRORS_YES or the parsing of the specified unit file
326+
* with RECURSIVE_ERRORS_NO must have yielded a syntax warning and hence, a non-empty set. */
327+
if (IN_SET(recursive_errors, RECURSIVE_ERRORS_YES, RECURSIVE_ERRORS_NO))
328+
return -ENOTRECOVERABLE;
329+
330+
/* If all previous verifications succeeded, then the non-empty set could have resulted from
331+
* a syntax warning encountered during the recursive parsing of the specified unit file and
332+
* its direct dependencies. Hence, search for any of the filenames in the set and if found,
333+
* return a non-zero process exit status. */
334+
if (recursive_errors == RECURSIVE_ERRORS_ONE)
335+
STRV_FOREACH(filename, filenames)
336+
if (set_contains(s, basename(*filename)))
337+
return -ENOTRECOVERABLE;
338+
339+
return 0;
287340
}
341+
342+
static const char* const recursive_errors_table[_RECURSIVE_ERRORS_MAX] = {
343+
[RECURSIVE_ERRORS_NO] = "no",
344+
[RECURSIVE_ERRORS_YES] = "yes",
345+
[RECURSIVE_ERRORS_ONE] = "one",
346+
};
347+
348+
DEFINE_STRING_TABLE_LOOKUP(recursive_errors, RecursiveErrors);

src/analyze/analyze-verify.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,16 @@
66
#include "execute.h"
77
#include "path-lookup.h"
88

9+
typedef enum RecursiveErrors {
10+
RECURSIVE_ERRORS_YES, /* Look for errors in all associated units */
11+
RECURSIVE_ERRORS_NO, /* Don't look for errors in any but the selected unit */
12+
RECURSIVE_ERRORS_ONE, /* Look for errors in the selected unit and its direct dependencies */
13+
_RECURSIVE_ERRORS_MAX,
14+
_RECURSIVE_ERRORS_INVALID = -EINVAL,
15+
} RecursiveErrors;
16+
917
int verify_executable(Unit *u, const ExecCommand *exec, const char *root);
10-
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root);
18+
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root);
19+
20+
const char* recursive_errors_to_string(RecursiveErrors i) _const_;
21+
RecursiveErrors recursive_errors_from_string(const char *s) _pure_;

src/analyze/analyze.c

Lines changed: 81 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#endif
4747
#include "sort-util.h"
4848
#include "special.h"
49+
#include "string-table.h"
4950
#include "strv.h"
5051
#include "strxcpyx.h"
5152
#include "terminal-util.h"
@@ -85,6 +86,7 @@ static PagerFlags arg_pager_flags = 0;
8586
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
8687
static const char *arg_host = NULL;
8788
static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
89+
static RecursiveErrors arg_recursive_errors = RECURSIVE_ERRORS_YES;
8890
static bool arg_man = true;
8991
static bool arg_generators = false;
9092
static char *arg_root = NULL;
@@ -2145,7 +2147,7 @@ static int do_condition(int argc, char *argv[], void *userdata) {
21452147
}
21462148

21472149
static int do_verify(int argc, char *argv[], void *userdata) {
2148-
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_root);
2150+
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root);
21492151
}
21502152

21512153
static int do_security(int argc, char *argv[], void *userdata) {
@@ -2179,43 +2181,52 @@ static int help(int argc, char *argv[], void *userdata) {
21792181
printf("%s [OPTIONS...] COMMAND ...\n\n"
21802182
"%sProfile systemd, show unit dependencies, check unit files.%s\n"
21812183
"\nCommands:\n"
2182-
" [time] Print time required to boot the machine\n"
2183-
" blame Print list of running units ordered by time to init\n"
2184-
" critical-chain [UNIT...] Print a tree of the time critical chain of units\n"
2185-
" plot Output SVG graphic showing service initialization\n"
2186-
" dot [UNIT...] Output dependency graph in %s format\n"
2187-
" dump Output state serialization of service manager\n"
2188-
" cat-config Show configuration file and drop-ins\n"
2189-
" unit-files List files and symlinks for units\n"
2190-
" unit-paths List load directories for units\n"
2191-
" exit-status [STATUS...] List exit status definitions\n"
2192-
" capability [CAP...] List capability definitions\n"
2193-
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
2194-
" condition CONDITION... Evaluate conditions and asserts\n"
2195-
" verify FILE... Check unit files for correctness\n"
2196-
" calendar SPEC... Validate repetitive calendar time events\n"
2197-
" timestamp TIMESTAMP... Validate a timestamp\n"
2198-
" timespan SPAN... Validate a time span\n"
2199-
" security [UNIT...] Analyze security of unit\n"
2184+
" [time] Print time required to boot the machine\n"
2185+
" blame Print list of running units ordered by\n"
2186+
" time to init\n"
2187+
" critical-chain [UNIT...] Print a tree of the time critical chain\n"
2188+
" of units\n"
2189+
" plot Output SVG graphic showing service\n"
2190+
" initialization\n"
2191+
" dot [UNIT...] Output dependency graph in %s format\n"
2192+
" dump Output state serialization of service\n"
2193+
" manager\n"
2194+
" cat-config Show configuration file and drop-ins\n"
2195+
" unit-files List files and symlinks for units\n"
2196+
" unit-paths List load directories for units\n"
2197+
" exit-status [STATUS...] List exit status definitions\n"
2198+
" capability [CAP...] List capability definitions\n"
2199+
" syscall-filter [NAME...] Print list of syscalls in seccomp\n"
2200+
" filter\n"
2201+
" condition CONDITION... Evaluate conditions and asserts\n"
2202+
" verify FILE... Check unit files for correctness\n"
2203+
" calendar SPEC... Validate repetitive calendar time\n"
2204+
" events\n"
2205+
" timestamp TIMESTAMP... Validate a timestamp\n"
2206+
" timespan SPAN... Validate a time span\n"
2207+
" security [UNIT...] Analyze security of unit\n"
22002208
"\nOptions:\n"
2201-
" -h --help Show this help\n"
2202-
" --version Show package version\n"
2203-
" --no-pager Do not pipe output into a pager\n"
2204-
" --system Operate on system systemd instance\n"
2205-
" --user Operate on user systemd instance\n"
2206-
" --global Operate on global user configuration\n"
2207-
" -H --host=[USER@]HOST Operate on remote host\n"
2208-
" -M --machine=CONTAINER Operate on local container\n"
2209-
" --order Show only order in the graph\n"
2210-
" --require Show only requirement in the graph\n"
2211-
" --from-pattern=GLOB Show only origins in the graph\n"
2212-
" --to-pattern=GLOB Show only destinations in the graph\n"
2213-
" --fuzz=SECONDS Also print services which finished SECONDS earlier\n"
2214-
" than the latest in the branch\n"
2215-
" --man[=BOOL] Do [not] check for existence of man pages\n"
2216-
" --generators[=BOOL] Do [not] run unit generators (requires privileges)\n"
2217-
" --iterations=N Show the specified number of iterations\n"
2218-
" --base-time=TIMESTAMP Calculate calendar times relative to specified time\n"
2209+
" -h --help Show this help\n"
2210+
" --recursive-errors=MODE Control which units are verified\n"
2211+
" --version Show package version\n"
2212+
" --no-pager Do not pipe output into a pager\n"
2213+
" --system Operate on system systemd instance\n"
2214+
" --user Operate on user systemd instance\n"
2215+
" --global Operate on global user configuration\n"
2216+
" -H --host=[USER@]HOST Operate on remote host\n"
2217+
" -M --machine=CONTAINER Operate on local container\n"
2218+
" --order Show only order in the graph\n"
2219+
" --require Show only requirement in the graph\n"
2220+
" --from-pattern=GLOB Show only origins in the graph\n"
2221+
" --to-pattern=GLOB Show only destinations in the graph\n"
2222+
" --fuzz=SECONDS Also print services which finished SECONDS\n"
2223+
" earlier than the latest in the branch\n"
2224+
" --man[=BOOL] Do [not] check for existence of man pages\n"
2225+
" --generators[=BOOL] Do [not] run unit generators\n"
2226+
" (requires privileges)\n"
2227+
" --iterations=N Show the specified number of iterations\n"
2228+
" --base-time=TIMESTAMP Calculate calendar times relative to\n"
2229+
" specified time\n"
22192230
"\nSee the %s for details.\n",
22202231
program_invocation_short_name,
22212232
ansi_highlight(),
@@ -2247,28 +2258,30 @@ static int parse_argv(int argc, char *argv[]) {
22472258
ARG_GENERATORS,
22482259
ARG_ITERATIONS,
22492260
ARG_BASE_TIME,
2261+
ARG_RECURSIVE_ERRORS,
22502262
};
22512263

22522264
static const struct option options[] = {
2253-
{ "help", no_argument, NULL, 'h' },
2254-
{ "version", no_argument, NULL, ARG_VERSION },
2255-
{ "order", no_argument, NULL, ARG_ORDER },
2256-
{ "require", no_argument, NULL, ARG_REQUIRE },
2257-
{ "root", required_argument, NULL, ARG_ROOT },
2258-
{ "image", required_argument, NULL, ARG_IMAGE },
2259-
{ "system", no_argument, NULL, ARG_SYSTEM },
2260-
{ "user", no_argument, NULL, ARG_USER },
2261-
{ "global", no_argument, NULL, ARG_GLOBAL },
2262-
{ "from-pattern", required_argument, NULL, ARG_DOT_FROM_PATTERN },
2263-
{ "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN },
2264-
{ "fuzz", required_argument, NULL, ARG_FUZZ },
2265-
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
2266-
{ "man", optional_argument, NULL, ARG_MAN },
2267-
{ "generators", optional_argument, NULL, ARG_GENERATORS },
2268-
{ "host", required_argument, NULL, 'H' },
2269-
{ "machine", required_argument, NULL, 'M' },
2270-
{ "iterations", required_argument, NULL, ARG_ITERATIONS },
2271-
{ "base-time", required_argument, NULL, ARG_BASE_TIME },
2265+
{ "help", no_argument, NULL, 'h' },
2266+
{ "version", no_argument, NULL, ARG_VERSION },
2267+
{ "order", no_argument, NULL, ARG_ORDER },
2268+
{ "require", no_argument, NULL, ARG_REQUIRE },
2269+
{ "root", required_argument, NULL, ARG_ROOT },
2270+
{ "image", required_argument, NULL, ARG_IMAGE },
2271+
{ "recursive-errors", required_argument, NULL, ARG_RECURSIVE_ERRORS },
2272+
{ "system", no_argument, NULL, ARG_SYSTEM },
2273+
{ "user", no_argument, NULL, ARG_USER },
2274+
{ "global", no_argument, NULL, ARG_GLOBAL },
2275+
{ "from-pattern", required_argument, NULL, ARG_DOT_FROM_PATTERN },
2276+
{ "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN },
2277+
{ "fuzz", required_argument, NULL, ARG_FUZZ },
2278+
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
2279+
{ "man", optional_argument, NULL, ARG_MAN },
2280+
{ "generators", optional_argument, NULL, ARG_GENERATORS },
2281+
{ "host", required_argument, NULL, 'H' },
2282+
{ "machine", required_argument, NULL, 'M' },
2283+
{ "iterations", required_argument, NULL, ARG_ITERATIONS },
2284+
{ "base-time", required_argument, NULL, ARG_BASE_TIME },
22722285
{}
22732286
};
22742287

@@ -2283,6 +2296,18 @@ static int parse_argv(int argc, char *argv[]) {
22832296
case 'h':
22842297
return help(0, NULL, NULL);
22852298

2299+
case ARG_RECURSIVE_ERRORS:
2300+
if (streq(optarg, "help")) {
2301+
DUMP_STRING_TABLE(recursive_errors, RecursiveErrors, _RECURSIVE_ERRORS_MAX);
2302+
return 0;
2303+
}
2304+
r = recursive_errors_from_string(optarg);
2305+
if (r < 0)
2306+
return log_error_errno(r, "Unknown mode passed to --recursive-errors='%s'.", optarg);
2307+
2308+
arg_recursive_errors = r;
2309+
break;
2310+
22862311
case ARG_VERSION:
22872312
return version();
22882313

0 commit comments

Comments
 (0)
X Tutup