[systemd-devel] [PATCH v2 1/2] nspawn: only mount the cgroup root if it's not already mounted
This allows the user to set the cgroups manually before calling nspawn. --- src/nspawn/nspawn.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 8c91726..f292c63 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1031,15 +1031,16 @@ static int mount_all(const char *dest) { } MountPoint; static const MountPoint mount_table[] = { -{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, -{ "/proc/sys", "/proc/sys", NULL,NULL,MS_BIND, true }, /* Bind mount first */ -{ NULL,"/proc/sys", NULL,NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */ -{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, -{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true }, -{ "devpts","/dev/pts", "devpts","newinstance,ptmxmode=0666,mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, true }, -{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, -{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, -{ "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_STRICTATIME, true }, +{ "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, +{ "/proc/sys", "/proc/sys", NULL,NULL, MS_BIND,true }, /* Bind mount first */ +{ NULL,"/proc/sys", NULL,NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true }, /* Then, make it r/o */ +{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true }, +{ "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, true }, +{ "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true }, +{ "devpts","/dev/pts", "devpts","newinstance,ptmxmode=0666,mode=620,gid=" STRINGIFY(TTY_GID), MS_NOSUID|MS_NOEXEC, true }, +{ "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, +{ "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true }, +{ "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_STRICTATIME, true }, #ifdef HAVE_SELINUX { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false }, /* Bind mount first */ { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false }, /* Then, make it r/o */ @@ -1324,9 +1325,6 @@ static int mount_cgroup(const char *dest) { if (r < 0) return log_error_errno(r, "Failed to determine our own cgroup path: %m"); -cgroup_root = strjoina(dest, "/sys/fs/cgroup"); -if (mount("tmpfs", cgroup_root, "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, "mode=755") < 0) -return log_error_errno(errno, "Failed to mount tmpfs to /sys/fs/cgroup: %m"); for (;;) { _cleanup_free_ char *controller = NULL, *origin = NULL, *combined = NULL; @@ -1386,6 +1384,7 @@ static int mount_cgroup(const char *dest) { if (mount(NULL, systemd_root, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, NULL) < 0) return log_error_errno(errno, "Failed to mount cgroup root read-only: %m"); +cgroup_root = strjoina(dest, "/sys/fs/cgroup"); if (mount(NULL, cgroup_root, NULL, MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755") < 0) return log_error_errno(errno, "Failed to remount %s read-only: %m", cgroup_root); -- 2.4.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 0/2] Allow setting the cgroup hierarchy manually before calling nspawn
These two commits allow nspawn to play nicely with a cgroup hierarchy manually set beforehand. Iago López Galeiras (2): nspawn: only mount the cgroup root if it's not already mounted nspawn: skip symlink to a combined cgroup hierarchy if it already exists src/nspawn/nspawn.c | 33 +++-- src/shared/util.c | 23 +++ src/shared/util.h | 1 + 3 files changed, 43 insertions(+), 14 deletions(-) -- 2.4.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 2/2] nspawn: skip symlink to a combined cgroup hierarchy if it already exists
If a symlink to a combined cgroup hierarchy already exists and points to the right path, skip it. This avoids an error when the cgroups are set manually before calling nspawn. --- src/nspawn/nspawn.c | 10 -- src/shared/util.c | 23 +++ src/shared/util.h | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index f292c63..e9e703f 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1365,8 +1365,14 @@ static int mount_cgroup(const char *dest) { if (r < 0) return r; -if (symlink(combined, target) < 0) -return log_error_errno(errno, "Failed to create symlink for combined hierarchy: %m"); +r = symlink_idempotent(combined, target); +if (r < 0) { +if (r == -EINVAL) { +log_error("Invalid existing symlink for combined hierarchy"); +return r; +} else +return log_error_errno(r, "Failed to create symlink for combined hierarchy: %m"); +} } } diff --git a/src/shared/util.c b/src/shared/util.c index 466dce4..22e00a6 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -2765,6 +2765,29 @@ int symlink_atomic(const char *from, const char *to) { return 0; } +int symlink_idempotent(const char *from, const char *to) { +_cleanup_free_ char *p = NULL; +int r; + +assert(from); +assert(to); + +if (symlink(from, to) < 0) { +if (errno == EEXIST) { +r = readlink_malloc(to, &p); +if (r < 0) +return r; + +if (!streq(p, from)) { +return -EINVAL; +} +} else +return -errno; +} + +return 0; +} + int mknod_atomic(const char *path, mode_t mode, dev_t dev) { _cleanup_free_ char *t = NULL; int r; diff --git a/src/shared/util.h b/src/shared/util.h index 4a67d5c..8565fd6 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -404,6 +404,7 @@ bool machine_name_is_valid(const char *s) _pure_; char* strshorten(char *s, size_t l); +int symlink_idempotent(const char *from, const char *to); int symlink_atomic(const char *from, const char *to); int mknod_atomic(const char *path, mode_t mode, dev_t dev); -- 2.4.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/2] nspawn: skip symlink to a combined cgroup hierarchy if it already exists
If a symlink to a combined cgroup hierarchy already exists and points to the right path, skip it. This avoids an error when the cgroups are set manually before calling nspawn. --- src/nspawn/nspawn.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index c67cab2..cc0b84f 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1113,7 +1113,7 @@ static int mount_cgroup(const char *dest) { } else if (r < 0) return log_error_errno(r, "Failed to read link %s: %m", origin); else { -_cleanup_free_ char *target = NULL; +_cleanup_free_ char *target = NULL, *p = NULL; target = strjoin(dest, "/sys/fs/cgroup/", controller, NULL); if (!target) @@ -1130,8 +1130,18 @@ static int mount_cgroup(const char *dest) { if (r < 0) return r; -if (symlink(combined, target) < 0) +if (symlink(combined, target) < 0) { +if (errno == EEXIST) { +r = readlink_malloc(target, &p); +if (r < 0) +return log_error_errno(r, "Failed to read link %s: %m", target); +else if (!streq(p, combined)) { +log_error("Invalid existing symlink for combined hierarchy"); +return -EINVAL; +} +} else return log_error_errno(errno, "Failed to create symlink for combined hierarchy: %m"); +} } } -- 2.4.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 1/2] nspawn: only mount the cgroup root if it's not already mounted
This allows the user to set the cgroups manually before calling nspawn. --- src/nspawn/nspawn.c | 20 ++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 2f7dd53..c67cab2 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1053,6 +1053,21 @@ static int mount_cgroup_hierarchy(const char *dest, const char *controller, cons return 1; } +static int mount_cgroup_tmpfs(const char *cgroup_root) { +int r; + +r = path_is_mount_point(cgroup_root, false); +if (r < 0 && r != -ENOENT) +return log_error_errno(r, "Failed to determine if %s is mounted already: %m", cgroup_root); +if (r > 0) +return 0; + +if (mount("tmpfs", cgroup_root, "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, "mode=755") < 0) +return log_error_errno(errno, "Failed to mount tmpfs to /sys/fs/cgroup: %m"); + +return 1; +} + static int mount_cgroup(const char *dest) { _cleanup_set_free_free_ Set *controllers = NULL; _cleanup_free_ char *own_cgroup_path = NULL; @@ -1072,8 +1087,9 @@ static int mount_cgroup(const char *dest) { return log_error_errno(r, "Failed to determine our own cgroup path: %m"); cgroup_root = strjoina(dest, "/sys/fs/cgroup"); -if (mount("tmpfs", cgroup_root, "tmpfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, "mode=755") < 0) -return log_error_errno(errno, "Failed to mount tmpfs to /sys/fs/cgroup: %m"); +r = mount_cgroup_tmpfs(cgroup_root); +if (r < 0) +return r; for (;;) { _cleanup_free_ char *controller = NULL, *origin = NULL, *combined = NULL; -- 2.4.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 0/2] Allow setting the cgroup hierarchy manually before calling nspawn
These two commits allow nspawn to play nicely with a cgroup hierarchy manually set beforehand. Iago López Galeiras (2): nspawn: only mount the cgroup root if it's not already mounted nspawn: skip symlink to a combined cgroup hierarchy if it already exists src/nspawn/nspawn.c | 34 ++ 1 file changed, 30 insertions(+), 4 deletions(-) -- 2.4.0 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH] change filesystemtype from "bind" to NULL in mount syscalls
Try to keep syscalls as minimal as possible. --- src/core/namespace.c | 2 +- src/nspawn/nspawn.c | 16 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/namespace.c b/src/core/namespace.c index f8a2bbc..718da23 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -293,7 +293,7 @@ static int mount_kdbus(BindMount *m) { goto fail; } -r = mount(m->path, busnode, "bind", MS_BIND, NULL); +r = mount(m->path, busnode, NULL, MS_BIND, NULL); if (r < 0) { log_error_errno(errno, "bind mount of %s failed: %m", m->path); r = -errno; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 300b6df..685dafa 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1007,7 +1007,7 @@ static int mount_binds(const char *dest, char **l, bool ro) { return log_error_errno(r, "Failed to create mount point %s: %m", where); } -if (mount(*x, where, "bind", MS_BIND, NULL) < 0) +if (mount(*x, where, NULL, MS_BIND, NULL) < 0) return log_error_errno(errno, "mount(%s) failed: %m", where); if (ro) { @@ -1323,7 +1323,7 @@ static int setup_volatile(const char *directory) { goto fail; } -if (mount(f, t, "bind", MS_BIND|MS_REC, NULL) < 0) { +if (mount(f, t, NULL, MS_BIND|MS_REC, NULL) < 0) { log_error_errno(errno, "Failed to create /usr bind mount: %m"); r = -errno; goto fail; @@ -1394,10 +1394,10 @@ static int setup_boot_id(const char *dest) { if (r < 0) return log_error_errno(r, "Failed to write boot id: %m"); -if (mount(from, to, "bind", MS_BIND, NULL) < 0) { +if (mount(from, to, NULL, MS_BIND, NULL) < 0) { log_error_errno(errno, "Failed to bind mount boot id: %m"); r = -errno; -} else if (mount(from, to, "bind", MS_BIND|MS_REMOUNT|MS_RDONLY, NULL)) +} else if (mount(from, to, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL)) log_warning_errno(errno, "Failed to make boot id read-only: %m"); unlink(from); @@ -1508,7 +1508,7 @@ static int setup_dev_console(const char *dest, const char *console) { if (mknod(to, (st.st_mode & ~0) | 0600, st.st_rdev) < 0) return log_error_errno(errno, "mknod() for /dev/console failed: %m"); -if (mount(console, to, "bind", MS_BIND, NULL) < 0) +if (mount(console, to, NULL, MS_BIND, NULL) < 0) return log_error_errno(errno, "Bind mount for /dev/console failed: %m"); return 0; @@ -1551,7 +1551,7 @@ static int setup_kmsg(const char *dest, int kmsg_socket) { if (r < 0) return log_error_errno(r, "Failed to correct access mode for /dev/kmsg: %m"); -if (mount(from, to, "bind", MS_BIND, NULL) < 0) +if (mount(from, to, NULL, MS_BIND, NULL) < 0) return log_error_errno(errno, "Bind mount for /proc/kmsg failed: %m"); fd = open(from, O_RDWR|O_NDELAY|O_CLOEXEC); @@ -1926,7 +1926,7 @@ static int setup_journal(const char *directory) { return r; } -if (mount(p, q, "bind", MS_BIND, NULL) < 0) +if (mount(p, q, NULL, MS_BIND, NULL) < 0) return log_error_errno(errno, "Failed to bind mount journal from host into guest: %m"); return 0; @@ -4034,7 +4034,7 @@ int main(int argc, char *argv[]) { _exit(EXIT_FAILURE); /* Turn directory into bind mount */ -if (mount(arg_directory, arg_directory, "bind", MS_BIND|MS_REC, NULL) < 0) { +if (mount(arg_directory, arg_directory, NULL, MS_BIND|MS_REC, NULL) < 0) { log_error_errno(errno, "Failed to make bind mount: %m"); _exit(EXIT_FAILURE); } -- 2.3.4 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] Appc support in systemd-importd
Hi, We're looking into adding appc[1] support in systemd-importd. An appc image (ACI) is just a tar with a "rootfs" directory and a json "manifest". We would have to implement image discovery and simply extract the rootfs. Some questions: * I see that the dkr implementation ignores the information in the docker manifest (resource restrictions, binary to exec...). Is that by design or just not implemented yet? Should we do the same with appc (*only* extract the rootfs)? * Alban liked the idea of saving the manifest so we can extract the whole ACI and modify nspawn to detect a container is an ACI and set /var/lib/machines/appc-image.aci/rootfs as the container's root. The benefit of keeping the manifest would be knowing which binary to start. Is that acceptable? [1]: https://github.com/appc/spec/blob/master/SPEC.md Cheers, Iago -- Iago López Galeiras, Endocode AG ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 1/2] test: support empty environment variables in unit files
--- src/test/test-unit-file.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index 03b3e25..f31a1bb 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -222,6 +222,9 @@ static void test_config_parse_exec(void) { "MODULE_0=coretemp\n" \ "MODULE_1=f71882fg" +#define env_file_5 \ +"a=\n" \ +"b=" static void test_load_env_file_1(void) { _cleanup_strv_free_ char **data = NULL; @@ -300,6 +303,24 @@ static void test_load_env_file_4(void) { unlink(name); } +static void test_load_env_file_5(void) { +_cleanup_strv_free_ char **data = NULL; +int r; + +char name[] = "/tmp/test-load-env-file.XX"; +_cleanup_close_ int fd; + +fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); +assert_se(fd >= 0); +assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5)); + +r = load_env_file(NULL, name, NULL, &data); +assert_se(r == 0); +assert_se(streq(data[0], "a=")); +assert_se(streq(data[1], "b=")); +assert_se(data[2] == NULL); +unlink(name); +} static void test_install_printf(void) { charname[] = "name.service", @@ -387,6 +408,7 @@ int main(int argc, char *argv[]) { test_load_env_file_2(); test_load_env_file_3(); test_load_env_file_4(); +test_load_env_file_5(); TEST_REQ_RUNNING_SYSTEMD(test_install_printf()); return r; -- 2.1.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 0/2] Empty environment variables in unit files work
Clarified commit message (thanks Koen Kooi) Iago López Galeiras (2): test: support empty environment variables in unit files update TODO TODO | 2 -- src/test/test-unit-file.c | 22 ++ 2 files changed, 22 insertions(+), 2 deletions(-) -- 2.1.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH v2 2/2] update TODO
Empty environment variables in Environment= and EnvironmentFile= options work. --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index d4138fe..3e8d04c 100644 --- a/TODO +++ b/TODO @@ -191,8 +191,6 @@ Features: * generator that automatically discovers btrfs subvolumes, identifies their purpose based on some xattr on them. -* support setting empty environment variables with Environment= and EnvironmentFile= - * timer units: actually add extra delays to timer units with high AccuracySec values, don't start them already when we are awake... * a way for container managers to turn off getty starting via $container_headless= or so... -- 2.1.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 1/2] test: empty environment variables in unit files
--- src/test/test-unit-file.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index 03b3e25..f31a1bb 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -222,6 +222,9 @@ static void test_config_parse_exec(void) { "MODULE_0=coretemp\n" \ "MODULE_1=f71882fg" +#define env_file_5 \ +"a=\n" \ +"b=" static void test_load_env_file_1(void) { _cleanup_strv_free_ char **data = NULL; @@ -300,6 +303,24 @@ static void test_load_env_file_4(void) { unlink(name); } +static void test_load_env_file_5(void) { +_cleanup_strv_free_ char **data = NULL; +int r; + +char name[] = "/tmp/test-load-env-file.XX"; +_cleanup_close_ int fd; + +fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); +assert_se(fd >= 0); +assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5)); + +r = load_env_file(NULL, name, NULL, &data); +assert_se(r == 0); +assert_se(streq(data[0], "a=")); +assert_se(streq(data[1], "b=")); +assert_se(data[2] == NULL); +unlink(name); +} static void test_install_printf(void) { charname[] = "name.service", @@ -387,6 +408,7 @@ int main(int argc, char *argv[]) { test_load_env_file_2(); test_load_env_file_3(); test_load_env_file_4(); +test_load_env_file_5(); TEST_REQ_RUNNING_SYSTEMD(test_install_printf()); return r; -- 2.1.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 2/2] update TODO
Empty environment variables in Environment= and EnvironmentFile= options work. --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index d4138fe..3e8d04c 100644 --- a/TODO +++ b/TODO @@ -191,8 +191,6 @@ Features: * generator that automatically discovers btrfs subvolumes, identifies their purpose based on some xattr on them. -* support setting empty environment variables with Environment= and EnvironmentFile= - * timer units: actually add extra delays to timer units with high AccuracySec values, don't start them already when we are awake... * a way for container managers to turn off getty starting via $container_headless= or so... -- 2.1.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
[systemd-devel] [PATCH 0/2] Empty environment variables in unit files work
with this file: [Unit] Description=Test empty variables [Service] Environment=TEST= TEST2= ExecStart=/bin/bash -c "env" [Install] WantedBy=default.target I get this output: Nov 19 16:59:07 arch-tree systemd[1]: Starting Test empty variables... Nov 19 16:59:07 arch-tree systemd[1]: Started Test empty variables. Nov 19 16:59:07 arch-tree bash[131]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin Nov 19 16:59:07 arch-tree bash[131]: PWD=/ Nov 19 16:59:07 arch-tree bash[131]: TEST= Nov 19 16:59:07 arch-tree bash[131]: SHLVL=1 Nov 19 16:59:07 arch-tree bash[131]: TEST2= Nov 19 16:59:07 arch-tree bash[131]: _=/usr/sbin/env Iago López Galeiras (2): test: empty environment variables in unit files update TODO TODO | 2 -- src/test/test-unit-file.c | 22 ++ 2 files changed, 22 insertions(+), 2 deletions(-) -- 2.1.3 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel