summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-04-17 15:54:10 +0200
committerGitHub <noreply@github.com>2018-04-17 15:54:10 +0200
commit2cb36f7c1e4672df2b47bffab3b7d65216915992 (patch)
treeb4f0fa07c1cd3ffe34d7624efe27ad98eaa2da82
parent79a4beb39f16ae47213e42145bda2ea64bee9987 (diff)
parent7e4a49b42b2f4fb3a621dc89a4a76e330a9aebe9 (diff)
downloadsystemd-2cb36f7c1e4672df2b47bffab3b7d65216915992.tar.gz
systemd-2cb36f7c1e4672df2b47bffab3b7d65216915992.tar.bz2
systemd-2cb36f7c1e4672df2b47bffab3b7d65216915992.zip
Merge pull request #8575 from keszybz/non-absolute-paths
Do not require absolute paths in ExecStart and friends
-rw-r--r--man/systemd-path.xml7
-rw-r--r--man/systemd.service.xml40
-rw-r--r--src/analyze/analyze-verify.c11
-rw-r--r--src/basic/path-util.h6
-rw-r--r--src/core/load-fragment.c46
-rw-r--r--src/core/main.c27
-rw-r--r--src/core/manager.c29
-rw-r--r--src/core/manager.h1
-rw-r--r--src/libsystemd/sd-path/sd-path.c14
-rw-r--r--src/path/path.c1
-rw-r--r--src/systemd/sd-path.h1
-rw-r--r--src/test/meson.build3
-rw-r--r--src/test/test-cgroup-mask.c15
-rw-r--r--src/test/test-engine.c14
-rw-r--r--src/test/test-execute.c7
-rw-r--r--src/test/test-path.c14
-rw-r--r--src/test/test-sched-prio.c15
-rw-r--r--test/meson.build1
-rw-r--r--test/test-execute/exec-basic.service13
-rw-r--r--test/test-execute/exec-bindpaths.service8
-rw-r--r--test/test-execute/exec-dynamicuser-statedir-migrate-step1.service16
-rw-r--r--test/test-execute/exec-dynamicuser-statedir-migrate-step2.service32
-rw-r--r--test/test-execute/exec-dynamicuser-statedir.service18
-rw-r--r--test/test-execute/exec-restrictnamespaces-mnt-blacklist.service2
-rw-r--r--test/test-execute/exec-restrictnamespaces-mnt.service2
-rw-r--r--test/test-execute/exec-restrictnamespaces-no.service2
-rw-r--r--test/test-execute/exec-restrictnamespaces-yes.service2
-rw-r--r--test/test-execute/exec-specifier.service38
-rw-r--r--test/test-execute/exec-specifier@.service38
-rw-r--r--test/test-execute/exec-temporaryfilesystem-rw.service16
30 files changed, 261 insertions, 178 deletions
diff --git a/man/systemd-path.xml b/man/systemd-path.xml
index 882d0d1a2a..2e52e5b874 100644
--- a/man/systemd-path.xml
+++ b/man/systemd-path.xml
@@ -39,7 +39,9 @@
<refsynopsisdiv>
<cmdsynopsis>
- <command>systemd-path <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt" rep="repeat">NAME</arg></command>
+ <command>systemd-path</command>
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
+ <arg choice="opt" rep="repeat">NAME</arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -68,8 +70,7 @@
<varlistentry>
<term><option>--suffix=</option></term>
- <listitem><para>The printed paths are suffixed by the
- specified string.</para></listitem>
+ <listitem><para>Printed paths are suffixed by the specified string.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 1e309904fa..6fe0b1e153 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -288,8 +288,9 @@
<varname>ExecStop=</varname> line set. (Services lacking both <varname>ExecStart=</varname> and
<varname>ExecStop=</varname> are not valid.)</para>
- <para>For each of the specified commands, the first argument must be an absolute path to an
- executable. Optionally, this filename may be prefixed with a number of special characters:</para>
+ <para>For each of the specified commands, the first argument must be either an absolute path to an executable
+ or a simple file name without any slashes. Optionally, this filename may be prefixed with a number of special
+ characters:</para>
<table>
<title>Special executable prefixes</title>
@@ -991,11 +992,9 @@
<literal>&amp;</literal>, and <emphasis>other elements of shell
syntax are not supported</emphasis>.</para>
- <para>The command to execute must be an absolute path name. It may
- contain spaces, but control characters are not allowed.</para>
+ <para>The command to execute may contain spaces, but control characters are not allowed.</para>
- <para>The command line accepts <literal>%</literal> specifiers as
- described in
+ <para>The command line accepts <literal>%</literal> specifiers as described in
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<para>Basic environment variable substitution is supported. Use
@@ -1009,10 +1008,21 @@
For this type of expansion, quotes are respected when splitting
into words, and afterwards removed.</para>
+ <para>If the command is not a full (absolute) path, it will be resolved to a full path using a
+ fixed search path determinted at compilation time. Searched directories include
+ <filename>/usr/local/bin/</filename>, <filename>/usr/bin/</filename>, <filename>/bin/</filename>
+ on systems using split <filename>/usr/bin/</filename> and <filename>/bin/</filename>
+ directories, and their <filename>sbin/</filename> counterparts on systems using split
+ <filename>bin/</filename> and <filename>sbin/</filename>. It is thus safe to use just the
+ executable name in case of executables located in any of the "standard" directories, and an
+ absolute path must be used in other cases. Using an absolute path is recommended to avoid
+ ambiguity. Hint: this search path may be queried using
+ <command>systemd-path search-binaries-default</command>.</para>
+
<para>Example:</para>
<programlisting>Environment="ONE=one" 'TWO=two two'
-ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
+ExecStart=echo $ONE $TWO ${TWO}</programlisting>
<para>This will execute <command>/bin/echo</command> with four
arguments: <literal>one</literal>, <literal>two</literal>,
@@ -1022,7 +1032,7 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
<programlisting>Environment=ONE='one' "TWO='two two' too" THREE=
ExecStart=/bin/echo ${ONE} ${TWO} ${THREE}
ExecStart=/bin/echo $ONE $TWO $THREE</programlisting>
- <para>This results in <filename>echo</filename> being
+ <para>This results in <filename>/bin/echo</filename> being
called twice, the first time with arguments
<literal>'one'</literal>,
<literal>'two two' too</literal>, <literal></literal>,
@@ -1048,27 +1058,27 @@ ExecStart=/bin/echo $ONE $TWO $THREE</programlisting>
<para>Note that shell command lines are not directly supported. If
shell command lines are to be used, they need to be passed
explicitly to a shell implementation of some kind. Example:</para>
- <programlisting>ExecStart=/bin/sh -c 'dmesg | tac'</programlisting>
+ <programlisting>ExecStart=sh -c 'dmesg | tac'</programlisting>
<para>Example:</para>
- <programlisting>ExecStart=/bin/echo one ; /bin/echo "two two"</programlisting>
+ <programlisting>ExecStart=echo one ; echo "two two"</programlisting>
- <para>This will execute <command>/bin/echo</command> two times,
+ <para>This will execute <command>echo</command> two times,
each time with one argument: <literal>one</literal> and
<literal>two two</literal>, respectively. Because two commands are
specified, <varname>Type=oneshot</varname> must be used.</para>
<para>Example:</para>
- <programlisting>ExecStart=/bin/echo / &gt;/dev/null &amp; \; \
-/bin/ls</programlisting>
+ <programlisting>ExecStart=echo / &gt;/dev/null &amp; \; \
+ls</programlisting>
- <para>This will execute <command>/bin/echo</command>
+ <para>This will execute <command>echo</command>
with five arguments: <literal>/</literal>,
<literal>&gt;/dev/null</literal>,
<literal>&amp;</literal>, <literal>;</literal>, and
- <literal>/bin/ls</literal>.</para>
+ <literal>ls</literal>.</para>
<table>
<title>C escapes supported in command lines and environment variables</title>
diff --git a/src/analyze/analyze-verify.c b/src/analyze/analyze-verify.c
index fdaf90c7fc..90c10f575a 100644
--- a/src/analyze/analyze-verify.c
+++ b/src/analyze/analyze-verify.c
@@ -231,7 +231,6 @@ static int verify_unit(Unit *u, bool check_man) {
}
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators) {
- _cleanup_(sd_bus_error_free) sd_bus_error err = SD_BUS_ERROR_NULL;
_cleanup_free_ char *var = NULL;
Manager *m = NULL;
FILE *serial = NULL;
@@ -284,12 +283,10 @@ int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run
continue;
}
- k = manager_load_unit(m, NULL, prepared, &err, &units[count]);
- if (k < 0) {
- log_error_errno(k, "Failed to load %s: %m", *filename);
- if (r == 0)
- r = k;
- } else
+ k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]);
+ if (k < 0 && r == 0)
+ r = k;
+ else
count++;
}
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 898eeb4395..9946853b41 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -17,17 +17,23 @@
#if HAVE_SPLIT_BIN
# define PATH_SBIN_BIN(x) x "sbin:" x "bin"
+# define PATH0_SBIN_BIN(x) x "sbin\0" x "bin"
#else
+# define PATH0_SBIN_BIN(x) x "bin"
# define PATH_SBIN_BIN(x) x "bin"
#endif
#define DEFAULT_PATH_NORMAL PATH_SBIN_BIN("/usr/local/") ":" PATH_SBIN_BIN("/usr/")
+#define DEFAULT_PATH0_NORMAL PATH0_SBIN_BIN("/usr/local/") "\0" PATH0_SBIN_BIN("/usr/")
#define DEFAULT_PATH_SPLIT_USR DEFAULT_PATH_NORMAL ":" PATH_SBIN_BIN("/")
+#define DEFAULT_PATH0_SPLIT_USR DEFAULT_PATH0_NORMAL "\0" PATH0_SBIN_BIN("/")
#if HAVE_SPLIT_USR
# define DEFAULT_PATH DEFAULT_PATH_SPLIT_USR
+# define DEFAULT_PATH_NULSTR DEFAULT_PATH0_SPLIT_USR
#else
# define DEFAULT_PATH DEFAULT_PATH_NORMAL
+# define DEFAULT_PATH_NULSTR DEFAULT_PATH0_NORMAL
#endif
bool is_path(const char *p) _pure_;
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index c3ff27b518..767355adf6 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -639,23 +639,51 @@ int config_parse_exec(
}
if (!string_is_safe(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
- "Executable path contains special characters%s: %s",
- ignore ? ", ignoring" : "", rvalue);
- return ignore ? 0 : -ENOEXEC;
- }
- if (!path_is_absolute(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0,
- "Executable path is not absolute%s: %s",
- ignore ? ", ignoring" : "", rvalue);
+ "Executable name contains special characters%s: %s",
+ ignore ? ", ignoring" : "", path);
return ignore ? 0 : -ENOEXEC;
}
if (endswith(path, "/")) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Executable path specifies a directory%s: %s",
- ignore ? ", ignoring" : "", rvalue);
+ ignore ? ", ignoring" : "", path);
return ignore ? 0 : -ENOEXEC;
}
+ if (!path_is_absolute(path)) {
+ const char *prefix;
+ bool found = false;
+
+ if (!filename_is_valid(path)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Neither a valid executable name nor an absolute path%s: %s",
+ ignore ? ", ignoring" : "", path);
+ return ignore ? 0 : -ENOEXEC;
+ }
+
+ /* Resolve a single-component name to a full path */
+ NULSTR_FOREACH(prefix, DEFAULT_PATH_NULSTR) {
+ _cleanup_free_ char *fullpath = NULL;
+
+ fullpath = strjoin(prefix, "/", path);
+ if (!fullpath)
+ return log_oom();
+
+ if (access(fullpath, F_OK) >= 0) {
+ free_and_replace(path, fullpath);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable \"%s\" not found in path \"%s\"%s",
+ path, DEFAULT_PATH, ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
+ }
+ }
+
if (!separate_argv0) {
char *w = NULL;
diff --git a/src/core/main.c b/src/core/main.c
index 701cbab99b..201882ca95 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1890,28 +1890,15 @@ static int do_queue_default_job(
log_debug("Activating default unit: %s", arg_default_unit);
- r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
- if (r < 0)
- log_error("Failed to load default target: %s", bus_error_message(&error, r));
- else if (IN_SET(target->load_state, UNIT_ERROR, UNIT_NOT_FOUND))
- log_error_errno(target->load_error, "Failed to load default target: %m");
- else if (target->load_state == UNIT_MASKED)
- log_error("Default target masked.");
-
- if (!target || target->load_state != UNIT_LOADED) {
- log_info("Trying to load rescue target...");
+ r = manager_load_startable_unit_or_warn(m, arg_default_unit, NULL, &target);
+ if (r < 0) {
+ log_info("Falling back to rescue target: " SPECIAL_RESCUE_TARGET);
- r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
+ r = manager_load_startable_unit_or_warn(m, SPECIAL_RESCUE_TARGET, NULL, &target);
if (r < 0) {
- *ret_error_message = "Failed to load rescue target";
- return log_emergency_errno(r, "Failed to load rescue target: %s", bus_error_message(&error, r));
- } else if (IN_SET(target->load_state, UNIT_ERROR, UNIT_NOT_FOUND)) {
- *ret_error_message = "Failed to load rescue target";
- return log_emergency_errno(target->load_error, "Failed to load rescue target: %m");
- } else if (target->load_state == UNIT_MASKED) {
- *ret_error_message = "Rescue target masked";
- log_emergency("Rescue target masked.");
- return -ERFKILL;
+ *ret_error_message = r == -ERFKILL ? "Rescue target masked"
+ : "Failed to load rescue target";
+ return r;
}
}
diff --git a/src/core/manager.c b/src/core/manager.c
index 74e36a7521..a42fccd8e4 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1810,7 +1810,36 @@ int manager_load_unit(
manager_dispatch_load_queue(m);
*_ret = unit_follow_merge(*_ret);
+ return 0;
+}
+
+int manager_load_startable_unit_or_warn(
+ Manager *m,
+ const char *name,
+ const char *path,
+ Unit **ret) {
+
+ /* Load a unit, make sure it loaded fully and is not masked. */
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ Unit *unit;
+ int r;
+
+ r = manager_load_unit(m, name, path, &error, &unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to load %s %s: %s",
+ name ? "unit" : "file", name ?: path,
+ bus_error_message(&error, r));
+ else if (IN_SET(unit->load_state, UNIT_ERROR, UNIT_NOT_FOUND))
+ return log_error_errno(unit->load_error, "Failed to load %s %s: %m",
+ name ? "unit" : "file", name ?: path);
+ else if (unit->load_state == UNIT_MASKED) {
+ log_error("%s %s is masked.",
+ name ? "Unit" : "File", name ?: path);
+ return -ERFKILL;
+ }
+ *ret = unit;
return 0;
}
diff --git a/src/core/manager.h b/src/core/manager.h
index 6047c02532..cab89d8192 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -383,6 +383,7 @@ int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
int manager_load_unit_prepare(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
+int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret);
int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u);
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret);
diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c
index d8867bc439..c75a39613b 100644
--- a/src/libsystemd/sd-path/sd-path.c
+++ b/src/libsystemd/sd-path/sd-path.c
@@ -335,6 +335,7 @@ _public_ int sd_path_home(uint64_t type, const char *suffix, char **path) {
if (IN_SET(type,
SD_PATH_SEARCH_BINARIES,
+ SD_PATH_SEARCH_BINARIES_DEFAULT,
SD_PATH_SEARCH_LIBRARY_PRIVATE,
SD_PATH_SEARCH_LIBRARY_ARCH,
SD_PATH_SEARCH_SHARED,
@@ -553,7 +554,17 @@ static int get_search(uint64_t type, char ***list) {
false,
"/etc",
NULL);
- }
+
+ case SD_PATH_SEARCH_BINARIES_DEFAULT: {
+ char **t;
+
+ t = strv_split_nulstr(DEFAULT_PATH_NULSTR);
+ if (!t)
+ return -ENOMEM;
+
+ *list = t;
+ return 0;
+ }}
return -EOPNOTSUPP;
}
@@ -566,6 +577,7 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) {
if (!IN_SET(type,
SD_PATH_SEARCH_BINARIES,
+ SD_PATH_SEARCH_BINARIES_DEFAULT,
SD_PATH_SEARCH_LIBRARY_PRIVATE,
SD_PATH_SEARCH_LIBRARY_ARCH,
SD_PATH_SEARCH_SHARED,
diff --git a/src/path/path.c b/src/path/path.c
index 16a12875a8..5275845750 100644
--- a/src/path/path.c
+++ b/src/path/path.c
@@ -54,6 +54,7 @@ static const char* const path_table[_SD_PATH_MAX] = {
[SD_PATH_USER_TEMPLATES] = "user-templates",
[SD_PATH_USER_DESKTOP] = "user-desktop",
[SD_PATH_SEARCH_BINARIES] = "search-binaries",
+ [SD_PATH_SEARCH_BINARIES_DEFAULT] = "search-binaries-default",
[SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
[SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
[SD_PATH_SEARCH_SHARED] = "search-shared",
diff --git a/src/systemd/sd-path.h b/src/systemd/sd-path.h
index 2dfc8967b4..19f48b73eb 100644
--- a/src/systemd/sd-path.h
+++ b/src/systemd/sd-path.h
@@ -74,6 +74,7 @@ enum {
/* Search paths */
SD_PATH_SEARCH_BINARIES,
+ SD_PATH_SEARCH_BINARIES_DEFAULT,
SD_PATH_SEARCH_LIBRARY_PRIVATE,
SD_PATH_SEARCH_LIBRARY_ARCH,
SD_PATH_SEARCH_SHARED,
diff --git a/src/test/meson.build b/src/test/meson.build
index c138481df8..61bb23ef7e 100644
--- a/src/test/meson.build
+++ b/src/test/meson.build
@@ -553,7 +553,8 @@ tests += [
libseccomp,
libselinux,
libmount,
- libblkid]],
+ libblkid],
+ '', 'timeout=360'],
[['src/test/test-siphash24.c'],
[],
diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c
index 1e59bb02bb..90e2cc8edb 100644
--- a/src/test/test-cgroup-mask.c
+++ b/src/test/test-cgroup-mask.c
@@ -53,16 +53,11 @@ static int test_cgroup_mask(void) {
assert_se(manager_startup(m, serial, fdset) >= 0);
/* Load units and verify hierarchy. */
- assert_se(manager_load_unit(m, "parent.slice", NULL, NULL, &parent) >= 0);
- assert_se(manager_load_unit(m, "son.service", NULL, NULL, &son) >= 0);
- assert_se(manager_load_unit(m, "daughter.service", NULL, NULL, &daughter) >= 0);
- assert_se(manager_load_unit(m, "grandchild.service", NULL, NULL, &grandchild) >= 0);
- assert_se(manager_load_unit(m, "parent-deep.slice", NULL, NULL, &parent_deep) >= 0);
- assert_se(parent->load_state == UNIT_LOADED);
- assert_se(son->load_state == UNIT_LOADED);
- assert_se(daughter->load_state == UNIT_LOADED);
- assert_se(grandchild->load_state == UNIT_LOADED);
- assert_se(parent_deep->load_state == UNIT_LOADED);
+ assert_se(manager_load_startable_unit_or_warn(m, "parent.slice", NULL, &parent) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "son.service", NULL, &son) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "daughter.service", NULL, &daughter) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "grandchild.service", NULL, &grandchild) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "parent-deep.slice", NULL, &parent_deep) >= 0);
assert_se(UNIT_DEREF(son->slice) == parent);
assert_se(UNIT_DEREF(daughter->slice) == parent);
assert_se(UNIT_DEREF(parent_deep->slice) == parent);
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index 1c12a8644d..6d3b0a1627 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -47,9 +47,9 @@ int main(int argc, char *argv[]) {
assert_se(manager_startup(m, serial, fdset) >= 0);
printf("Load1:\n");
- assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0);
- assert_se(manager_load_unit(m, "b.service", NULL, NULL, &b) >= 0);
- assert_se(manager_load_unit(m, "c.service", NULL, NULL, &c) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "a.service", NULL, &a) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "b.service", NULL, &b) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "c.service", NULL, &c) >= 0);
manager_dump_units(m, stdout, "\t");
printf("Test1: (Trivial)\n");
@@ -61,8 +61,8 @@ int main(int argc, char *argv[]) {
printf("Load2:\n");
manager_clear_jobs(m);
- assert_se(manager_load_unit(m, "d.service", NULL, NULL, &d) >= 0);
- assert_se(manager_load_unit(m, "e.service", NULL, NULL, &e) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "d.service", NULL, &d) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "e.service", NULL, &e) >= 0);
manager_dump_units(m, stdout, "\t");
printf("Test2: (Cyclic Order, Unfixable)\n");
@@ -78,7 +78,7 @@ int main(int argc, char *argv[]) {
manager_dump_jobs(m, stdout, "\t");
printf("Load3:\n");
- assert_se(manager_load_unit(m, "g.service", NULL, NULL, &g) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "g.service", NULL, &g) >= 0);
manager_dump_units(m, stdout, "\t");
printf("Test5: (Colliding transaction, fail)\n");
@@ -100,7 +100,7 @@ int main(int argc, char *argv[]) {
manager_dump_jobs(m, stdout, "\t");
printf("Load4:\n");
- assert_se(manager_load_unit(m, "h.service", NULL, NULL, &h) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "h.service", NULL, &h) >= 0);
manager_dump_units(m, stdout, "\t");
printf("Test10: (Unmergeable job type of auxiliary job, fail)\n");
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
index 0bb2b85918..59d996c11b 100644
--- a/src/test/test-execute.c
+++ b/src/test/test-execute.c
@@ -132,7 +132,7 @@ static void test(Manager *m, const char *unit_name, int status_expected, int cod
assert_se(unit_name);
- assert_se(manager_load_unit(m, unit_name, NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
check(m, unit, status_expected, code_expected);
}
@@ -536,6 +536,10 @@ static void test_exec_capabilityboundingset(Manager *m) {
test(m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED);
}
+static void test_exec_basic(Manager *m) {
+ test(m, "exec-basic.service", 0, CLD_EXITED);
+}
+
static void test_exec_ambientcapabilities(Manager *m) {
int r;
@@ -635,6 +639,7 @@ static int run_tests(UnitFileScope scope, const test_function_t *tests) {
int main(int argc, char *argv[]) {
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
static const test_function_t user_tests[] = {
+ test_exec_basic,
test_exec_ambientcapabilities,
test_exec_bindpaths,
test_exec_capabilityboundingset,
diff --git a/src/test/test-path.c b/src/test/test-path.c
index 1fd1a75990..3d990407b3 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -121,7 +121,7 @@ static void test_path_exists(Manager *m) {
assert_se(m);
- assert_se(manager_load_unit(m, "path-exists.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-exists.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
assert_se(touch(test_path) >= 0);
@@ -134,7 +134,7 @@ static void test_path_existsglob(Manager *m) {
Unit *unit = NULL;
assert_se(m);
- assert_se(manager_load_unit(m, "path-existsglob.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-existsglob.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
assert_se(touch(test_path) >= 0);
@@ -151,7 +151,7 @@ static void test_path_changed(Manager *m) {
assert_se(touch(test_path) >= 0);
- assert_se(manager_load_unit(m, "path-changed.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-changed.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
f = fopen(test_path, "w");
@@ -170,7 +170,7 @@ static void test_path_modified(Manager *m) {
assert_se(touch(test_path) >= 0);
- assert_se(manager_load_unit(m, "path-modified.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-modified.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
f = fopen(test_path, "w");
@@ -186,7 +186,7 @@ static void test_path_unit(Manager *m) {
assert_se(m);
- assert_se(manager_load_unit(m, "path-unit.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-unit.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
assert_se(touch(test_path) >= 0);
@@ -202,7 +202,7 @@ static void test_path_directorynotempty(Manager *m) {
assert_se(access(test_path, F_OK) < 0);
- assert_se(manager_load_unit(m, "path-directorynotempty.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-directorynotempty.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
/* MakeDirectory default to no */
@@ -223,7 +223,7 @@ static void test_path_makedirectory_directorymode(Manager *m) {
assert_se(access(test_path, F_OK) < 0);
- assert_se(manager_load_unit(m, "path-makedirectory.path", NULL, NULL, &unit) >= 0);
+ assert_se(manager_load_startable_unit_or_warn(m, "path-makedirectory.path", NULL, &unit) >= 0);
assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
/* Check if the directory has been created */
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index cede70b053..7d8fc445ec 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -40,8 +40,7 @@ int main(int argc, char *argv[]) {
assert_se(manager_startup(m, serial, fdset) >= 0);
/* load idle ok */
- assert_se(manager_load_unit(m, "sched_idle_ok.service", NULL, NULL, &idle_ok) >= 0);
- assert_se(idle_ok->load_state == UNIT_LOADED);
+ assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_ok.service", NULL, &idle_ok) >= 0);
ser = SERVICE(idle_ok);
assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER);
assert_se(ser->exec_context.cpu_sched_priority == 0);
@@ -49,8 +48,7 @@ int main(int argc, char *argv[]) {
/*
* load idle bad. This should print a warning but we have no way to look at it.
*/
- assert_se(manager_load_unit(m, "sched_idle_bad.service", NULL, NULL, &idle_bad) >= 0);
- assert_se(idle_bad->load_state == UNIT_LOADED);
+ assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_bad.service", NULL, &idle_bad) >= 0);
ser = SERVICE(idle_ok);
assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER);
assert_se(ser->exec_context.cpu_sched_priority == 0);
@@ -59,8 +57,7 @@ int main(int argc, char *argv[]) {
* load rr ok.
* Test that the default priority is moving from 0 to 1.
*/
- assert_se(manager_load_unit(m, "sched_rr_ok.service", NULL, NULL, &rr_ok) >= 0);
- assert_se(rr_ok->load_state == UNIT_LOADED);
+ assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_ok.service", NULL, &rr_ok) >= 0);
ser = SERVICE(rr_ok);
assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR);
assert_se(ser->exec_context.cpu_sched_priority == 1);
@@ -69,8 +66,7 @@ int main(int argc, char *argv[]) {
* load rr bad.
* Test that the value of 0 and 100 is ignored.
*/
- assert_se(manager_load_unit(m, "sched_rr_bad.service", NULL, NULL, &rr_bad) >= 0);
- assert_se(rr_bad->load_state == UNIT_LOADED);
+ assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_bad.service", NULL, &rr_bad) >= 0);
ser = SERVICE(rr_bad);
assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR);
assert_se(ser->exec_context.cpu_sched_priority == 1);
@@ -79,8 +75,7 @@ int main(int argc, char *argv[]) {
* load rr change.
* Test that anything between 1 and 99 can be set.
*/
- assert_se(manager_load_unit(m, "sched_rr_change.service", NULL, NULL, &rr_sched) >= 0);
- assert_se(rr_sched->load_state == UNIT_LOADED);
+ assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_change.service", NULL, &rr_sched) >= 0);
ser = SERVICE(rr_sched);
assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR);
assert_se(ser->exec_context.cpu_sched_priority == 99);
diff --git a/test/meson.build b/test/meson.build
index c112e09577..c65e7e4538 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -32,6 +32,7 @@ test_data_files = '''
sockets.target
son.service
sysinit.target
+ test-execute/exec-basic.service
test-execute/exec-ambientcapabilities-merge-nfsnobody.service
test-execute/exec-ambientcapabilities-merge-nobody.service
test-execute/exec-ambientcapabilities-merge.service
diff --git a/test/test-execute/exec-basic.service b/test/test-execute/exec-basic.service
new file mode 100644
index 0000000000..456f06951a
--- /dev/null
+++ b/test/test-execute/exec-basic.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Test for basic execution
+
+[Service]
+ExecStart=touch /tmp/a ; /bin/touch /tmp/b ; touch /tmp/c
+ExecStart=test -f /tmp/a
+ExecStart=!test -f /tmp/b
+ExecStart=!!test -f /tmp/c
+ExecStart=+test -f /tmp/c
+ExecStartPost=rm /tmp/a /tmp/b /tmp/c
+
+PrivateTmp=true
+Type=oneshot
diff --git a/test/test-execute/exec-bindpaths.service b/test/test-execute/exec-bindpaths.service
index 7bd8fa7402..edab18bb0f 100644
--- a/test/test-execute/exec-bindpaths.service
+++ b/test/test-execute/exec-bindpaths.service
@@ -4,14 +4,14 @@ Description=Test for BindPaths= and BindReadOnlyPaths=
[Service]
Type=oneshot
# Create a file in /tmp/test-exec-bindpaths
-ExecStart=/bin/sh -c 'touch /tmp/test-exec-bindpaths/thisisasimpletest'
+ExecStart=touch /tmp/test-exec-bindpaths/thisisasimpletest
# Then, the file can be access through /tmp
-ExecStart=/bin/sh -c 'test -f /tmp/thisisasimpletest'
+ExecStart=test -f /tmp/thisisasimpletest
# Also, through /tmp/test-exec-bindreadonlypaths
-ExecStart=/bin/sh -c 'test -f /tmp/test-exec-bindreadonlypaths/thisisasimpletest'
+ExecStart=test -f /tmp/test-exec-bindreadonlypaths/thisisasimpletest
# The file cannot modify through /tmp/test-exec-bindreadonlypaths
ExecStart=/bin/sh -x -c '! touch /tmp/test-exec-bindreadonlypaths/thisisasimpletest'
# Cleanup
-ExecStart=/bin/sh -c 'rm /tmp/thisisasimpletest'
+ExecStart=rm /tmp/thisisasimpletest
BindPaths=/tmp:/tmp/test-exec-bindpaths
BindReadOnlyPaths=/tmp:/tmp/test-exec-bindreadonlypaths
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
index 83bdfb311a..72e6d7686f 100644
--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
@@ -2,14 +2,14 @@
Description=Test DynamicUser= migrate StateDirectory= (preparation)
[Service]
-ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'test ! -L /var/lib/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test ! -L /var/lib/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate/yay'
-ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay'
+ExecStart=test -w /var/lib/test-dynamicuser-migrate
+ExecStart=test -w /var/lib/test-dynamicuser-migrate2/hoge
+ExecStart=test ! -L /var/lib/test-dynamicuser-migrate
+ExecStart=test ! -L /var/lib/test-dynamicuser-migrate2/hoge
+ExecStart=test -d /var/lib/test-dynamicuser-migrate
+ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge
+ExecStart=touch /var/lib/test-dynamicuser-migrate/yay
+ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay
Type=oneshot
DynamicUser=no
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
index 8154922a2f..5a61228c9f 100644
--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
@@ -2,22 +2,22 @@
Description=Test DynamicUser= migrate StateDirectory= (preparation)
[Service]
-ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test -w /var/lib/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'test -L /var/lib/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test -L /var/lib/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test -d /var/lib/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'test -f /var/lib/test-dynamicuser-migrate/yay'
-ExecStart=/bin/sh -c 'test -f /var/lib/test-dynamicuser-migrate2/hoge/yayyay'
-ExecStart=/bin/sh -c 'test -d /var/lib/private/test-dynamicuser-migrate'
-ExecStart=/bin/sh -c 'test -d /var/lib/private/test-dynamicuser-migrate2/hoge'
-ExecStart=/bin/sh -c 'test -f /var/lib/private/test-dynamicuser-migrate/yay'
-ExecStart=/bin/sh -c 'test -f /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay'
-ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate/yay'
-ExecStart=/bin/sh -c 'touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay'
-ExecStart=/bin/sh -c 'touch /var/lib/private/test-dynamicuser-migrate/yay'
-ExecStart=/bin/sh -c 'touch /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay'
+ExecStart=test -w /var/lib/test-dynamicuser-migrate
+ExecStart=test -w /var/lib/test-dynamicuser-migrate2/hoge
+ExecStart=test -L /var/lib/test-dynamicuser-migrate
+ExecStart=test -L /var/lib/test-dynamicuser-migrate2/hoge
+ExecStart=test -d /var/lib/test-dynamicuser-migrate
+ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge
+ExecStart=test -f /var/lib/test-dynamicuser-migrate/yay
+ExecStart=test -f /var/lib/test-dynamicuser-migrate2/hoge/yayyay
+ExecStart=test -d /var/lib/private/test-dynamicuser-migrate
+ExecStart=test -d /var/lib/private/test-dynamicuser-migrate2/hoge
+ExecStart=test -f /var/lib/private/test-dynamicuser-migrate/yay
+ExecStart=test -f /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay
+ExecStart=touch /var/lib/test-dynamicuser-migrate/yay
+ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay
+ExecStart=touch /var/lib/private/test-dynamicuser-migrate/yay
+ExecStart=touch /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay
Type=oneshot
DynamicUser=yes
diff --git a/test/test-execute/exec-dynamicuser-statedir.service b/test/test-execute/exec-dynamicuser-statedir.service
index 5ea6d9da42..f459f3c1eb 100644
--- a/test/test-execute/exec-dynamicuser-statedir.service
+++ b/test/test-execute/exec-dynamicuser-statedir.service
@@ -2,17 +2,17 @@
Description=Test DynamicUser= with StateDirectory=
[Service]
-ExecStart=/bin/sh -c 'test -w /var/lib/waldo'
-ExecStart=/bin/sh -c 'test -w /var/lib/quux/pief'
-ExecStart=/bin/sh -c 'touch /var/lib/waldo/yay'
-ExecStart=/bin/sh -c 'touch /var/lib/quux/pief/yayyay'
-ExecStart=/bin/sh -c 'test -f /var/lib/waldo/yay'
-ExecStart=/bin/sh -c 'test -f /var/lib/quux/pief/yayyay'
-ExecStart=/bin/sh -c 'test -f /var/lib/private/waldo/yay'
-ExecStart=/bin/sh -c 'test -f /var/lib/private/quux/pief/yayyay'
+ExecStart=test -w /var/lib/waldo
+ExecStart=test -w /var/lib/quux/pief
+ExecStart=touch /var/lib/waldo/yay
+ExecStart=touch /var/lib/quux/pief/yayyay
+ExecStart=test -f /var/lib/waldo/yay
+ExecStart=test -f /var/lib/quux/pief/yayyay
+ExecStart=test -f /var/lib/private/waldo/yay
+ExecStart=test -f /var/lib/private/quux/pief/yayyay
# Make sure that /var/lib/private/waldo is really the only writable directory besides the obvious candidates
-ExecStart=/bin/sh -x -c 'test $$(find / -type d -writable 2> /dev/null | egrep -v -e \'^(/var/tmp$$|/tmp$$|/proc/|/dev/mqueue$$|/dev/shm$$|/sys/fs/bpf$$)\' | sort -u | tr -d '\\\\n') = /var/lib/private/quux/pief/var/lib/private/waldo'
+ExecStart=sh -x -c 'test $$(find / \( -path /var/tmp -o -path /tmp -o -path /proc -o -path /dev/mqueue -o -path /dev/shm -o -path /sys/fs/bpf \) -prune -o -type d -writable -print 2>/dev/null | sort -u | tr -d '\\\\n') = /var/lib/private/quux/pief/var/lib/private/waldo'
Type=oneshot
DynamicUser=yes
diff --git a/test/test-execute/exec-restrictnamespaces-mnt-blacklist.service b/test/test-execute/exec-restrictnamespaces-mnt-blacklist.service
index ab909cbd94..7756a2575e 100644
--- a/test/test-execute/exec-restrictnamespaces-mnt-blacklist.service
+++ b/test/test-execute/exec-restrictnamespaces-mnt-blacklist.service
@@ -3,5 +3,5 @@ Description=Test RestrictNamespaces=~mnt
[Service]
RestrictNamespaces=~mnt
-ExecStart=/bin/sh -x -c 'unshare -m'
+ExecStart=unshare -m
Type=oneshot
diff --git a/test/test-execute/exec-restrictnamespaces-mnt.service b/test/test-execute/exec-restrictnamespaces-mnt.service
index 1aeed72717..2c5b942601 100644
--- a/test/test-execute/exec-restrictnamespaces-mnt.service
+++ b/test/test-execute/exec-restrictnamespaces-mnt.service
@@ -3,5 +3,5 @@ Description=Test RestrictNamespaces=mnt
[Service]
RestrictNamespaces=mnt
-ExecStart=/bin/sh -x -c 'unshare -m'
+ExecStart=unshare -m
Type=oneshot
diff --git a/test/test-execute/exec-restrictnamespaces-no.service b/test/test-execute/exec-restrictnamespaces-no.service
index 33500302d2..5ffe081e45 100644
--- a/test/test-execute/exec-restrictnamespaces-no.service
+++ b/test/test-execute/exec-restrictnamespaces-no.service
@@ -3,5 +3,5 @@ Description=Test RestrictNamespaces=no
[Service]
RestrictNamespaces=no
-ExecStart=/bin/sh -x -c 'unshare -m -u -i -n -p -f'
+ExecStart=unshare -m -u -i -n -p -f
Type=oneshot
diff --git a/test/test-execute/exec-restrictnamespaces-yes.service b/test/test-execute/exec-restrictnamespaces-yes.service
index 3fe70e2bea..8e077ed3a0 100644
--- a/test/test-execute/exec-restrictnamespaces-yes.service
+++ b/test/test-execute/exec-restrictnamespaces-yes.service
@@ -3,5 +3,5 @@ Description=Test RestrictNamespaces=yes
[Service]
RestrictNamespaces=yes
-ExecStart=/bin/sh -x -c 'unshare -m'
+ExecStart=unshare -m
Type=oneshot
diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service
index 37852390ac..65a64bc95e 100644
--- a/test/test-execute/exec-specifier.service
+++ b/test/test-execute/exec-specifier.service
@@ -3,22 +3,22 @@ Description=Test for specifiers
[Service]
Type=oneshot
-ExecStart=/usr/bin/test %n = exec-specifier.service
-ExecStart=/usr/bin/test %N = exec-specifier
-ExecStart=/usr/bin/test %p = exec-specifier
-ExecStart=/usr/bin/test %P = exec/specifier
-ExecStart=/usr/bin/test %i = ""
-ExecStart=/usr/bin/test %I = ""
-ExecStart=/usr/bin/test %f = /exec/specifier
-ExecStart=/usr/bin/test %t = /run
-ExecStart=/usr/bin/test %S = /var/lib
-ExecStart=/usr/bin/test %C = /var/cache
-ExecStart=/usr/bin/test %L = /var/log
-ExecStart=/bin/sh -c 'test %u = $$(id -un 0)'
-ExecStart=/usr/bin/test %U = 0
-ExecStart=/bin/sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)
-ExecStart=/bin/sh -c 'test %s = $$(getent passwd 0 | cut -d: -f 7)
-ExecStart=/bin/sh -c 'test %m = $$(cat /etc/machine-id)'
-ExecStart=/bin/sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
-ExecStart=/bin/sh -c 'test %H = $$(hostname)'
-ExecStart=/bin/sh -c 'test %v = $$(uname -r)'
+ExecStart=test %n = exec-specifier.service
+ExecStart=test %N = exec-specifier
+ExecStart=test %p = exec-specifier
+ExecStart=test %P = exec/specifier
+ExecStart=test %i = ""
+ExecStart=test %I = ""
+ExecStart=test %f = /exec/specifier
+ExecStart=test %t = /run
+ExecStart=test %S = /var/lib
+ExecStart=test %C = /var/cache
+ExecStart=test %L = /var/log
+ExecStart=sh -c 'test %u = $$(id -un 0)'
+ExecStart=test %U = 0
+ExecStart=sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)'
+ExecStart=sh -c 'test %s = $$(getent passwd 0 | cut -d: -f 7)'
+ExecStart=sh -c 'test %m = $$(cat /etc/machine-id)'
+ExecStart=sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
+ExecStart=sh -c 'test %H = $$(hostname)'
+ExecStart=sh -c 'test %v = $$(uname -r)'
diff --git a/test/test-execute/exec-specifier@.service b/test/test-execute/exec-specifier@.service
index 0015dffca6..f8d7dce680 100644
--- a/test/test-execute/exec-specifier@.service
+++ b/test/test-execute/exec-specifier@.service
@@ -3,22 +3,22 @@ Description=Test for specifiers (template unit)
[Service]
Type=oneshot
-ExecStart=/usr/bin/test %n = exec-specifier@foo-bar.service
-ExecStart=/usr/bin/test %N = exec-specifier@foo-bar
-ExecStart=/usr/bin/test %p = exec-specifier
-ExecStart=/usr/bin/test %P = exec/specifier
-ExecStart=/usr/bin/test %i = foo-bar
-ExecStart=/usr/bin/test %I = foo/bar
-ExecStart=/usr/bin/test %f = /foo/bar
-ExecStart=/usr/bin/test %t = /run
-ExecStart=/usr/bin/test %S = /var/lib
-ExecStart=/usr/bin/test %C = /var/cache
-ExecStart=/usr/bin/test %L = /var/log
-ExecStart=/bin/sh -c 'test %u = $$(id -un 0)'
-ExecStart=/usr/bin/test %U = 0
-ExecStart=/bin/sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)
-ExecStart=/bin/sh -c 'test %s = $$(getent passwd 0 | cut -d: -f 7)
-ExecStart=/bin/sh -c 'test %m = $$(cat /etc/machine-id)'
-ExecStart=/bin/sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
-ExecStart=/bin/sh -c 'test %H = $$(hostname)'
-ExecStart=/bin/sh -c 'test %v = $$(uname -r)'
+ExecStart=test %n = exec-specifier@foo-bar.service
+ExecStart=test %N = exec-specifier@foo-bar
+ExecStart=test %p = exec-specifier
+ExecStart=test %P = exec/specifier
+ExecStart=test %i = foo-bar
+ExecStart=test %I = foo/bar
+ExecStart=test %f = /foo/bar
+ExecStart=test %t = /run
+ExecStart=test %S = /var/lib
+ExecStart=test %C = /var/cache
+ExecStart=test %L = /var/log
+ExecStart=sh -c 'test %u = $$(id -un 0)'
+ExecStart=test %U = 0
+ExecStart=sh -c 'test %h = $$(getent passwd 0 | cut -d: -f 6)'
+ExecStart=sh -c 'test %s = $$(getent passwd 0 | cut -d: -f 7)'
+ExecStart=sh -c 'test %m = $$(cat /etc/machine-id)'
+ExecStart=sh -c 'test %b = $$(cat /proc/sys/kernel/random/boot_id | sed -e 's/-//g')'
+ExecStart=sh -c 'test %H = $$(hostname)'
+ExecStart=sh -c 'test %v = $$(uname -r)'
diff --git a/test/test-execute/exec-temporaryfilesystem-rw.service b/test/test-execute/exec-temporaryfilesystem-rw.service
index fc02ceab1c..379ad066fb 100644
--- a/test/test-execute/exec-temporaryfilesystem-rw.service
+++ b/test/test-execute/exec-temporaryfilesystem-rw.service
@@ -5,28 +5,28 @@ Description=Test for TemporaryFileSystem
Type=oneshot
# Check directories exist
-ExecStart=/bin/sh -c 'test -d /var/test-exec-temporaryfilesystem/rw && test -d /var/test-exec-temporaryfilesystem/ro'
+ExecStart=test -d /var/test-exec-temporaryfilesystem/rw -a -d /var/test-exec-temporaryfilesystem/ro
# Check TemporaryFileSystem= are empty
-ExecStart=/bin/sh -c 'for i in $$(ls -A /var); do test $$i = test-exec-temporaryfilesystem || false; done'
+ExecStart=sh -c 'for i in $$(ls -A /var); do test $$i = test-exec-temporaryfilesystem || false; done'
# Create a file in /var
-ExecStart=/bin/sh -c 'touch /var/hoge'
+ExecStart=touch /var/hoge
# Create a file in /var/test-exec-temporaryfilesystem/rw
-ExecStart=/bin/sh -c 'touch /var/test-exec-temporaryfilesystem/rw/thisisasimpletest-temporaryfilesystem'
+ExecStart=touch /var/test-exec-temporaryfilesystem/rw/thisisasimpletest-temporaryfilesystem
# Then, the file can be access through /tmp
-ExecStart=/bin/sh -c 'test -f /tmp/thisisasimpletest-temporaryfilesystem'
+ExecStart=test -f /tmp/thisisasimpletest-temporaryfilesystem
# Also, through /var/test-exec-temporaryfilesystem/ro
-ExecStart=/bin/sh -c 'test -f /var/test-exec-temporaryfilesystem/ro/thisisasimpletest-temporaryfilesystem'
+ExecStart=test -f /var/test-exec-temporaryfilesystem/ro/thisisasimpletest-temporaryfilesystem
# The file cannot modify through /var/test-exec-temporaryfilesystem/ro
-ExecStart=/bin/sh -c '! touch /var/test-exec-temporaryfilesystem/ro/thisisasimpletest-temporaryfilesystem'
+ExecStart=sh -c '! touch /var/test-exec-temporaryfilesystem/ro/thisisasimpletest-temporaryfilesystem'
# Cleanup
-ExecStart=/bin/sh -c 'rm /tmp/thisisasimpletest-temporaryfilesystem'
+ExecStart=rm /tmp/thisisasimpletest-temporaryfilesystem
TemporaryFileSystem=/var
BindPaths=/tmp:/var/test-exec-temporaryfilesystem/rw