summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd-analyze.xml12
-rw-r--r--shell-completion/bash/systemd-analyze2
-rw-r--r--shell-completion/zsh/_systemd-analyze1
-rw-r--r--src/analyze/analyze-verify.c65
-rw-r--r--src/analyze/analyze-verify.h13
-rw-r--r--src/analyze/analyze.c137
-rw-r--r--src/basic/log.c14
-rw-r--r--src/basic/log.h9
-rw-r--r--src/basic/macro.h6
-rw-r--r--src/core/manager.c4
-rw-r--r--src/core/manager.h11
-rw-r--r--src/core/unit.c12
12 files changed, 219 insertions, 67 deletions
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index dc93ac4e72..48976f52bf 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -745,6 +745,18 @@ Service b@0.service not loaded, b.socket cannot be started.
</varlistentry>
<varlistentry>
+ <term><option>--recursive-errors=<replaceable>MODE</replaceable></option></term>
+
+ <listitem><para>Control verification of units and their dependencies and whether
+ <command>systemd-analyze verify</command> exits with a non-zero process exit status or not. With
+ <command>yes</command>, return a non-zero process exit status when warnings arise during verification
+ of either the specified unit or any of its associated dependencies. This is the default. With
+ <command>no</command>, return a non-zero process exit status when warnings arise during verification
+ of only the specified unit. With <command>one</command>, return a non-zero process exit status when
+ warnings arise during verification of either the specified unit or its immediate dependencies. </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--root=<replaceable>PATH</replaceable></option></term>
<listitem><para>With <command>cat-files</command> and <command>verify</command>,
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
index 872518add0..1b9447a125 100644
--- a/shell-completion/bash/systemd-analyze
+++ b/shell-completion/bash/systemd-analyze
@@ -125,7 +125,7 @@ _systemd_analyze() {
elif __contains_word "$verb" ${VERBS[VERIFY]}; then
if [[ $cur = -* ]]; then
- comps='--help --version --system --user --global --man=no --generators=yes --root --image'
+ comps='--help --version --system --user --global --man=no --generators=yes --root --image --recursive-errors=no --recursive-errors=yes --recursive-errors=one'
else
comps=$( compgen -A file -- "$cur" )
compopt -o filenames
diff --git a/shell-completion/zsh/_systemd-analyze b/shell-completion/zsh/_systemd-analyze
index 88a09d84b9..0dd080afb7 100644
--- a/shell-completion/zsh/_systemd-analyze
+++ b/shell-completion/zsh/_systemd-analyze
@@ -89,6 +89,7 @@ _arguments \
'--global[Show global user instance config]' \
'--root=[Add support for root argument]:PATH' \
'--image=[Add support for discrete images]:PATH' \
+ '--recursive-errors=[When verifying a unit, control dependency verification]:MODE' \
'--no-pager[Do not pipe output into a pager]' \
'--man=[Do (not) check for existence of man pages]:boolean:(1 0)' \
'--order[When generating graph for dot, show only order]' \
diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c
index 9ef6868367..cd5377200b 100644
--- a/src/analyze/analyze-verify.c
+++ b/src/analyze/analyze-verify.c
@@ -11,10 +11,28 @@
#include "manager.h"
#include "pager.h"
#include "path-util.h"
+#include "string-table.h"
#include "strv.h"
#include "unit-name.h"
#include "unit-serialize.h"
+static void log_syntax_callback(const char *unit, int level, void *userdata) {
+ Set **s = userdata;
+ int r;
+
+ assert(userdata);
+ assert(unit);
+
+ if (level > LOG_WARNING)
+ return;
+
+ r = set_put_strdup(s, unit);
+ if (r < 0) {
+ set_free_free(*s);
+ *s = POINTER_MAX;
+ }
+}
+
static int prepare_filename(const char *filename, char **ret) {
int r;
const char *name;
@@ -218,13 +236,22 @@ static int verify_unit(Unit *u, bool check_man, const char *root) {
return r;
}
-int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root) {
+static void set_destroy_ignore_pointer_max(Set** s) {
+ if (*s == POINTER_MAX)
+ return;
+ set_free_free(*s);
+}
+
+int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root) {
const ManagerTestRunFlags flags =
MANAGER_TEST_RUN_MINIMAL |
MANAGER_TEST_RUN_ENV_GENERATORS |
+ (recursive_errors == RECURSIVE_ERRORS_NO) * MANAGER_TEST_RUN_IGNORE_DEPENDENCIES |
run_generators * MANAGER_TEST_RUN_GENERATORS;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(set_destroy_ignore_pointer_max) Set *s = NULL;
+ _unused_ _cleanup_(clear_log_syntax_callback) dummy_t dummy;
Unit *units[strv_length(filenames)];
_cleanup_free_ char *var = NULL;
int r, k, i, count = 0;
@@ -233,6 +260,11 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
if (strv_isempty(filenames))
return 0;
+ /* Allow systemd-analyze to hook in a callback function so that it can get
+ * all the required log data from the function itself without having to rely
+ * on a global set variable for the same */
+ set_log_syntax_callback(log_syntax_callback, &s);
+
/* set the path */
r = generate_path(&var, filenames);
if (r < 0)
@@ -283,5 +315,34 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
r = k;
}
- return r;
+ if (s == POINTER_MAX)
+ return log_oom();
+
+ if (set_isempty(s) || r != 0)
+ return r;
+
+ /* If all previous verifications succeeded, then either the recursive parsing of all the
+ * associated dependencies with RECURSIVE_ERRORS_YES or the parsing of the specified unit file
+ * with RECURSIVE_ERRORS_NO must have yielded a syntax warning and hence, a non-empty set. */
+ if (IN_SET(recursive_errors, RECURSIVE_ERRORS_YES, RECURSIVE_ERRORS_NO))
+ return -ENOTRECOVERABLE;
+
+ /* If all previous verifications succeeded, then the non-empty set could have resulted from
+ * a syntax warning encountered during the recursive parsing of the specified unit file and
+ * its direct dependencies. Hence, search for any of the filenames in the set and if found,
+ * return a non-zero process exit status. */
+ if (recursive_errors == RECURSIVE_ERRORS_ONE)
+ STRV_FOREACH(filename, filenames)
+ if (set_contains(s, basename(*filename)))
+ return -ENOTRECOVERABLE;
+
+ return 0;
}
+
+static const char* const recursive_errors_table[_RECURSIVE_ERRORS_MAX] = {
+ [RECURSIVE_ERRORS_NO] = "no",
+ [RECURSIVE_ERRORS_YES] = "yes",
+ [RECURSIVE_ERRORS_ONE] = "one",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(recursive_errors, RecursiveErrors);
diff --git a/src/analyze/analyze-verify.h b/src/analyze/analyze-verify.h
index 6b3d6a5ab5..09d3aea02c 100644
--- a/src/analyze/analyze-verify.h
+++ b/src/analyze/analyze-verify.h
@@ -6,5 +6,16 @@
#include "execute.h"
#include "path-lookup.h"
+typedef enum RecursiveErrors {
+ RECURSIVE_ERRORS_YES, /* Look for errors in all associated units */
+ RECURSIVE_ERRORS_NO, /* Don't look for errors in any but the selected unit */
+ RECURSIVE_ERRORS_ONE, /* Look for errors in the selected unit and its direct dependencies */
+ _RECURSIVE_ERRORS_MAX,
+ _RECURSIVE_ERRORS_INVALID = -EINVAL,
+} RecursiveErrors;
+
int verify_executable(Unit *u, const ExecCommand *exec, const char *root);
-int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root);
+int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root);
+
+const char* recursive_errors_to_string(RecursiveErrors i) _const_;
+RecursiveErrors recursive_errors_from_string(const char *s) _pure_;
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 8d637ff8de..ceb18db740 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -46,6 +46,7 @@
#endif
#include "sort-util.h"
#include "special.h"
+#include "string-table.h"
#include "strv.h"
#include "strxcpyx.h"
#include "terminal-util.h"
@@ -85,6 +86,7 @@ static PagerFlags arg_pager_flags = 0;
static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
static const char *arg_host = NULL;
static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
+static RecursiveErrors arg_recursive_errors = RECURSIVE_ERRORS_YES;
static bool arg_man = true;
static bool arg_generators = false;
static char *arg_root = NULL;
@@ -2145,7 +2147,7 @@ static int do_condition(int argc, char *argv[], void *userdata) {
}
static int do_verify(int argc, char *argv[], void *userdata) {
- return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_root);
+ return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root);
}
static int do_security(int argc, char *argv[], void *userdata) {
@@ -2179,43 +2181,52 @@ static int help(int argc, char *argv[], void *userdata) {
printf("%s [OPTIONS...] COMMAND ...\n\n"
"%sProfile systemd, show unit dependencies, check unit files.%s\n"
"\nCommands:\n"
- " [time] Print time required to boot the machine\n"
- " blame Print list of running units ordered by time to init\n"
- " critical-chain [UNIT...] Print a tree of the time critical chain of units\n"
- " plot Output SVG graphic showing service initialization\n"
- " dot [UNIT...] Output dependency graph in %s format\n"
- " dump Output state serialization of service manager\n"
- " cat-config Show configuration file and drop-ins\n"
- " unit-files List files and symlinks for units\n"
- " unit-paths List load directories for units\n"
- " exit-status [STATUS...] List exit status definitions\n"
- " capability [CAP...] List capability definitions\n"
- " syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
- " condition CONDITION... Evaluate conditions and asserts\n"
- " verify FILE... Check unit files for correctness\n"
- " calendar SPEC... Validate repetitive calendar time events\n"
- " timestamp TIMESTAMP... Validate a timestamp\n"
- " timespan SPAN... Validate a time span\n"
- " security [UNIT...] Analyze security of unit\n"
+ " [time] Print time required to boot the machine\n"
+ " blame Print list of running units ordered by\n"
+ " time to init\n"
+ " critical-chain [UNIT...] Print a tree of the time critical chain\n"
+ " of units\n"
+ " plot Output SVG graphic showing service\n"
+ " initialization\n"
+ " dot [UNIT...] Output dependency graph in %s format\n"
+ " dump Output state serialization of service\n"
+ " manager\n"
+ " cat-config Show configuration file and drop-ins\n"
+ " unit-files List files and symlinks for units\n"
+ " unit-paths List load directories for units\n"
+ " exit-status [STATUS...] List exit status definitions\n"
+ " capability [CAP...] List capability definitions\n"
+ " syscall-filter [NAME...] Print list of syscalls in seccomp\n"
+ " filter\n"
+ " condition CONDITION... Evaluate conditions and asserts\n"
+ " verify FILE... Check unit files for correctness\n"
+ " calendar SPEC... Validate repetitive calendar time\n"
+ " events\n"
+ " timestamp TIMESTAMP... Validate a timestamp\n"
+ " timespan SPAN... Validate a time span\n"
+ " security [UNIT...] Analyze security of unit\n"
"\nOptions:\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --no-pager Do not pipe output into a pager\n"
- " --system Operate on system systemd instance\n"
- " --user Operate on user systemd instance\n"
- " --global Operate on global user configuration\n"
- " -H --host=[USER@]HOST Operate on remote host\n"
- " -M --machine=CONTAINER Operate on local container\n"
- " --order Show only order in the graph\n"
- " --require Show only requirement in the graph\n"
- " --from-pattern=GLOB Show only origins in the graph\n"
- " --to-pattern=GLOB Show only destinations in the graph\n"
- " --fuzz=SECONDS Also print services which finished SECONDS earlier\n"
- " than the latest in the branch\n"
- " --man[=BOOL] Do [not] check for existence of man pages\n"
- " --generators[=BOOL] Do [not] run unit generators (requires privileges)\n"
- " --iterations=N Show the specified number of iterations\n"
- " --base-time=TIMESTAMP Calculate calendar times relative to specified time\n"
+ " -h --help Show this help\n"
+ " --recursive-errors=MODE Control which units are verified\n"
+ " --version Show package version\n"
+ " --no-pager Do not pipe output into a pager\n"
+ " --system Operate on system systemd instance\n"
+ " --user Operate on user systemd instance\n"
+ " --global Operate on global user configuration\n"
+ " -H --host=[USER@]HOST Operate on remote host\n"
+ " -M --machine=CONTAINER Operate on local container\n"
+ " --order Show only order in the graph\n"
+ " --require Show only requirement in the graph\n"
+ " --from-pattern=GLOB Show only origins in the graph\n"
+ " --to-pattern=GLOB Show only destinations in the graph\n"
+ " --fuzz=SECONDS Also print services which finished SECONDS\n"
+ " earlier than the latest in the branch\n"
+ " --man[=BOOL] Do [not] check for existence of man pages\n"
+ " --generators[=BOOL] Do [not] run unit generators\n"
+ " (requires privileges)\n"
+ " --iterations=N Show the specified number of iterations\n"
+ " --base-time=TIMESTAMP Calculate calendar times relative to\n"
+ " specified time\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
@@ -2247,28 +2258,30 @@ static int parse_argv(int argc, char *argv[]) {
ARG_GENERATORS,
ARG_ITERATIONS,
ARG_BASE_TIME,
+ ARG_RECURSIVE_ERRORS,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "order", no_argument, NULL, ARG_ORDER },
- { "require", no_argument, NULL, ARG_REQUIRE },
- { "root", required_argument, NULL, ARG_ROOT },
- { "image", required_argument, NULL, ARG_IMAGE },
- { "system", no_argument, NULL, ARG_SYSTEM },
- { "user", no_argument, NULL, ARG_USER },
- { "global", no_argument, NULL, ARG_GLOBAL },
- { "from-pattern", required_argument, NULL, ARG_DOT_FROM_PATTERN },
- { "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN },
- { "fuzz", required_argument, NULL, ARG_FUZZ },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "man", optional_argument, NULL, ARG_MAN },
- { "generators", optional_argument, NULL, ARG_GENERATORS },
- { "host", required_argument, NULL, 'H' },
- { "machine", required_argument, NULL, 'M' },
- { "iterations", required_argument, NULL, ARG_ITERATIONS },
- { "base-time", required_argument, NULL, ARG_BASE_TIME },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "order", no_argument, NULL, ARG_ORDER },
+ { "require", no_argument, NULL, ARG_REQUIRE },
+ { "root", required_argument, NULL, ARG_ROOT },
+ { "image", required_argument, NULL, ARG_IMAGE },
+ { "recursive-errors", required_argument, NULL, ARG_RECURSIVE_ERRORS },
+ { "system", no_argument, NULL, ARG_SYSTEM },
+ { "user", no_argument, NULL, ARG_USER },
+ { "global", no_argument, NULL, ARG_GLOBAL },
+ { "from-pattern", required_argument, NULL, ARG_DOT_FROM_PATTERN },
+ { "to-pattern", required_argument, NULL, ARG_DOT_TO_PATTERN },
+ { "fuzz", required_argument, NULL, ARG_FUZZ },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "man", optional_argument, NULL, ARG_MAN },
+ { "generators", optional_argument, NULL, ARG_GENERATORS },
+ { "host", required_argument, NULL, 'H' },
+ { "machine", required_argument, NULL, 'M' },
+ { "iterations", required_argument, NULL, ARG_ITERATIONS },
+ { "base-time", required_argument, NULL, ARG_BASE_TIME },
{}
};
@@ -2283,6 +2296,18 @@ static int parse_argv(int argc, char *argv[]) {
case 'h':
return help(0, NULL, NULL);
+ case ARG_RECURSIVE_ERRORS:
+ if (streq(optarg, "help")) {
+ DUMP_STRING_TABLE(recursive_errors, RecursiveErrors, _RECURSIVE_ERRORS_MAX);
+ return 0;
+ }
+ r = recursive_errors_from_string(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Unknown mode passed to --recursive-errors='%s'.", optarg);
+
+ arg_recursive_errors = r;
+ break;
+
case ARG_VERSION:
return version();
diff --git a/src/basic/log.c b/src/basic/log.c
index 7f7e7a2d60..5fd2c5dcb4 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -39,6 +39,9 @@
#define SNDBUF_SIZE (8*1024*1024)
+static log_syntax_callback_t log_syntax_callback = NULL;
+static void *log_syntax_callback_userdata = NULL;
+
static LogTarget log_target = LOG_TARGET_CONSOLE;
static int log_max_level = LOG_INFO;
static int log_facility = LOG_DAEMON;
@@ -1341,6 +1344,14 @@ void log_received_signal(int level, const struct signalfd_siginfo *si) {
signal_to_string(si->ssi_signo));
}
+void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata) {
+ assert(!log_syntax_callback || !cb);
+ assert(!log_syntax_callback_userdata || !userdata);
+
+ log_syntax_callback = cb;
+ log_syntax_callback_userdata = userdata;
+}
+
int log_syntax_internal(
const char *unit,
int level,
@@ -1352,6 +1363,9 @@ int log_syntax_internal(
const char *func,
const char *format, ...) {
+ if (log_syntax_callback)
+ log_syntax_callback(unit, level, log_syntax_callback_userdata);
+
PROTECT_ERRNO;
char buffer[LINE_MAX];
va_list ap;
diff --git a/src/basic/log.h b/src/basic/log.h
index 9a17cd6c3d..b34bdffd1b 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -32,6 +32,15 @@ typedef enum LogTarget{
#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1)
#define ERRNO_VALUE(val) (abs(val) & 255)
+/* The callback function to be invoked when syntax warnings are seen
+ * in the unit files. */
+typedef void (*log_syntax_callback_t)(const char *unit, int level, void *userdata);
+void set_log_syntax_callback(log_syntax_callback_t cb, void *userdata);
+
+static inline void clear_log_syntax_callback(dummy_t *dummy) {
+ set_log_syntax_callback(/* cb= */ NULL, /* userdata= */ NULL);
+}
+
const char *log_target_to_string(LogTarget target) _const_;
LogTarget log_target_from_string(const char *s) _pure_;
void log_set_target(LogTarget target);
diff --git a/src/basic/macro.h b/src/basic/macro.h
index 3e89ba5e4d..645f93096f 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -460,4 +460,10 @@ static inline size_t size_add(size_t x, size_t y) {
return y >= SIZE_MAX - x ? SIZE_MAX : x + y;
}
+typedef struct {
+ int _empty[0];
+} dummy_t;
+
+assert_cc(sizeof(dummy_t) == 0);
+
#include "log.h"
diff --git a/src/core/manager.c b/src/core/manager.c
index e67f320bca..63679268fb 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1541,7 +1541,7 @@ Manager* manager_free(Manager *m) {
static void manager_enumerate_perpetual(Manager *m) {
assert(m);
- if (m->test_run_flags == MANAGER_TEST_RUN_MINIMAL)
+ if (FLAGS_SET(m->test_run_flags, MANAGER_TEST_RUN_MINIMAL))
return;
/* Let's ask every type to load all units from disk/kernel that it might know */
@@ -1559,7 +1559,7 @@ static void manager_enumerate_perpetual(Manager *m) {
static void manager_enumerate(Manager *m) {
assert(m);
- if (m->test_run_flags == MANAGER_TEST_RUN_MINIMAL)
+ if (FLAGS_SET(m->test_run_flags, MANAGER_TEST_RUN_MINIMAL))
return;
/* Let's ask every type to load all units from disk/kernel that it might know */
diff --git a/src/core/manager.h b/src/core/manager.h
index 4ce4368474..1220c9fb16 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -128,11 +128,12 @@ typedef enum WatchdogType {
#include "unit-name.h"
typedef enum ManagerTestRunFlags {
- MANAGER_TEST_NORMAL = 0, /* run normally */
- MANAGER_TEST_RUN_MINIMAL = 1 << 0, /* create basic data structures */
- MANAGER_TEST_RUN_BASIC = 1 << 1, /* interact with the environment */
- MANAGER_TEST_RUN_ENV_GENERATORS = 1 << 2, /* also run env generators */
- MANAGER_TEST_RUN_GENERATORS = 1 << 3, /* also run unit generators */
+ MANAGER_TEST_NORMAL = 0, /* run normally */
+ MANAGER_TEST_RUN_MINIMAL = 1 << 0, /* create basic data structures */
+ MANAGER_TEST_RUN_BASIC = 1 << 1, /* interact with the environment */
+ MANAGER_TEST_RUN_ENV_GENERATORS = 1 << 2, /* also run env generators */
+ MANAGER_TEST_RUN_GENERATORS = 1 << 3, /* also run unit generators */
+ MANAGER_TEST_RUN_IGNORE_DEPENDENCIES = 1 << 4, /* run while ignoring dependencies */
MANAGER_TEST_FULL = MANAGER_TEST_RUN_BASIC | MANAGER_TEST_RUN_ENV_GENERATORS | MANAGER_TEST_RUN_GENERATORS,
} ManagerTestRunFlags;
diff --git a/src/core/unit.c b/src/core/unit.c
index 1b9fb079b4..7c39e4d0f8 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3053,6 +3053,9 @@ int unit_add_dependency(
return 0;
}
+ if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
+ return 0;
+
/* Note that ordering a device unit after a unit is permitted since it allows to start its job
* running timeout at a specific time. */
if (FLAGS_SET(a, UNIT_ATOM_BEFORE) && other->type == UNIT_DEVICE) {
@@ -3176,6 +3179,9 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, boo
if (r < 0)
return r;
+ if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
+ return 0;
+
r = manager_load_unit(u->manager, name, NULL, NULL, &other);
if (r < 0)
return r;
@@ -3195,6 +3201,9 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency
if (r < 0)
return r;
+ if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
+ return 0;
+
r = manager_load_unit(u->manager, name, NULL, NULL, &other);
if (r < 0)
return r;
@@ -3312,6 +3321,9 @@ int unit_set_default_slice(Unit *u) {
assert(u);
+ if (u->manager && FLAGS_SET(u->manager->test_run_flags, MANAGER_TEST_RUN_IGNORE_DEPENDENCIES))
+ return 0;
+
if (UNIT_GET_SLICE(u))
return 0;