[systemd-commits] 7 commits - TODO man/systemd-nspawn.xml src/core src/journal src/machine src/nspawn src/shared src/systemctl src/sysusers src/test
Lennart Poettering
lennart at kemper.freedesktop.org
Fri Dec 12 08:30:37 PST 2014
TODO | 3 +-
man/systemd-nspawn.xml | 45 ++++++++++++++++++++----------
src/core/ima-setup.c | 2 -
src/journal/coredump.c | 2 -
src/machine/machine-dbus.c | 2 -
src/nspawn/nspawn.c | 67 +++++++++++++++++++++++++++++++++++++--------
src/shared/copy.c | 14 ++++-----
src/shared/copy.h | 4 +-
src/shared/util.c | 52 +++++++++++++++++++++++++++++++++-
src/shared/util.h | 1
src/systemctl/systemctl.c | 4 +-
src/sysusers/sysusers.c | 2 -
src/test/test-copy.c | 4 +-
13 files changed, 156 insertions(+), 46 deletions(-)
New commits:
commit 98cd2651988619bf606f0b27825440c4638a7e0b
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 17:30:02 2014 +0100
update TODO
diff --git a/TODO b/TODO
index 89dbd13..19459b3 100644
--- a/TODO
+++ b/TODO
@@ -35,6 +35,8 @@ External:
Features:
+* when a start job for a device unit is queued, when systemd runs in a container, make it fail immediately instead of wait for all eternity
+
* port libmount hookup to use API's own inotify interface, as soon as that is table in libmount
* bash completion for busctl, to make it truly useful
@@ -558,7 +560,6 @@ Features:
* nspawn:
- bind mount read-only the cgroup tree higher than nspawn
- refuses to boot containers without /etc/machine-id (OK?), and with empty /etc/machine-id (not OK).
- - support taking a btrfs snapshot at startup and dropping it afterwards
- introduce machines.target to order after all nspawn instances
- systemd-nspawn at .service should fail if some nspawn arg is invalid, with Type=notify
- PID 1 doesn't apply nspawns devices cgroup policy
commit 667993e88eb7519c6674fe9a9e985619817465e0
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 17:29:12 2014 +0100
man: fedora 21 has been release, suggest 21 as fedora version in example yum command line
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index d7d60e5..fdb0c29 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -780,7 +780,7 @@
<example>
<title>Boot a minimal Fedora distribution in a container</title>
- <programlisting># yum -y --releasever=19 --nogpg --installroot=/srv/mycontainer --disablerepo='*' --enablerepo=fedora install systemd passwd yum fedora-release vim-minimal
+ <programlisting># yum -y --releasever=21 --nogpg --installroot=/srv/mycontainer --disablerepo='*' --enablerepo=fedora install systemd passwd yum fedora-release vim-minimal
# systemd-nspawn -bD /srv/mycontainer</programlisting>
<para>This installs a minimal Fedora distribution into
commit b9ba4dabbab8a58a044ec42655e11e65bd3ecc47
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 17:26:31 2014 +0100
nspawn: when booting in ephemeral mode, append random token to machine name
Also, when booting up an ephemeral container of / use the system
hostname as default machine name.
This way specifiyng -M is unnecessary when booting up an ephemeral
container, while allowing any number of ephemeral containers to run from
the same tree.
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index b66c34d..d7d60e5 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -231,8 +231,10 @@
its root directory (as configured with
<option>--directory=</option>), that
is removed immediately when the
- container terminates. May not be
- specified together with
+ container terminates. This option is
+ only supported if the root file system
+ is <literal>btrfs</literal>. May not
+ be specified together with
<option>--image=</option> or
<option>--template=</option>.</para></listitem>
</varlistentry>
@@ -303,13 +305,22 @@
<listitem><para>Sets the machine name
for this container. This name may be
- used to identify this container on the
- host, and is used to initialize the
- container's hostname (which the
- container can choose to override,
- however). If not specified, the last
- component of the root directory of the
- container is used.</para></listitem>
+ used to identify this container during
+ its runtime (for example in tools like
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ and similar), and is used to
+ initialize the container's hostname
+ (which the container can choose to
+ override, however). If not specified,
+ the last component of the root
+ directory path of the container is
+ used, possibly suffixed with a random
+ identifier in case
+ <option>--ephemeral</option> mode is
+ selected. If the root directory
+ selected is the host's root directory
+ the host's hostname is used as default
+ instead.</para></listitem>
</varlistentry>
<varlistentry>
@@ -814,13 +825,16 @@
</example>
<example>
- <title>Boot into a <literal>btrfs</literal> snapshot of the host system</title>
+ <title>Boot into an ephemeral <literal>btrfs</literal> snapshot of the host system</title>
- <programlisting># btrfs subvolume snapshot / /.tmp
-# systemd-nspawn --private-network -D /.tmp -b</programlisting>
+ <programlisting># systemd-nspawn -D / -xb</programlisting>
<para>This runs a copy of the host system in a
- <literal>btrfs</literal> snapshot.</para>
+ <literal>btrfs</literal> snapshot which is
+ removed immediately when the container
+ exits. All file system changes made during
+ runtime will be lost on shutdown,
+ hence.</para>
</example>
<example>
@@ -847,7 +861,8 @@
<citerefentry project='die-net'><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='archlinux'><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 651a451..9ca53cd 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2875,7 +2875,11 @@ static int determine_names(void) {
}
if (!arg_machine) {
- arg_machine = strdup(basename(arg_image ?: arg_directory));
+ if (arg_directory && path_equal(arg_directory, "/"))
+ arg_machine = gethostname_malloc();
+ else
+ arg_machine = strdup(basename(arg_image ?: arg_directory));
+
if (!arg_machine)
return log_oom();
@@ -2884,6 +2888,21 @@ static int determine_names(void) {
log_error("Failed to determine machine name automatically, please use -M.");
return -EINVAL;
}
+
+ if (arg_ephemeral) {
+ char *b;
+
+ /* Add a random suffix when this is an
+ * ephemeral machine, so that we can run many
+ * instances at once without manually having
+ * to specify -M each time. */
+
+ if (asprintf(&b, "%s-%016" PRIx64, arg_machine, random_u64()) < 0)
+ return log_oom();
+
+ free(arg_machine);
+ arg_machine = b;
+ }
}
return 0;
commit c4e34a612c81266773cf8358cb38a43d2e43474e
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 16:59:15 2014 +0100
nspawn: allow spawning ephemeral nspawn containers based on the root file system of the OS
This works now:
# systemd-nspawn -xb -D / -M foobar
Which boots up an ephemeral container, based on the host's root file
system. Or in other words: you can now run the very same host OS you
booted your system with also in a container, on top of it, without
having it interfere. Great for testing whether the init system you are
hacking on still boots without reboot the system!
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f6f20ab..651a451 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2942,8 +2942,8 @@ int main(int argc, char *argv[]) {
if (arg_directory) {
assert(!arg_image);
- if (path_equal(arg_directory, "/")) {
- log_error("Spawning container on root directory not supported.");
+ if (path_equal(arg_directory, "/") && !arg_ephemeral) {
+ log_error("Spawning container on root directory is not supported. Consider using --ephemeral.");
r = -EINVAL;
goto finish;
}
@@ -2964,7 +2964,21 @@ int main(int argc, char *argv[]) {
} else if (arg_ephemeral) {
char *np;
- r = tempfn_random(arg_directory, &np);
+ /* If the specified path is a mount point we
+ * generate the new snapshot immediately
+ * inside it under a random name. However if
+ * the specified is not a mount point we
+ * create the new snapshot in the parent
+ * directory, just next to it. */
+ r = path_is_mount_point(arg_directory, false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to determine whether directory %s is mount point: %m", arg_directory);
+ goto finish;
+ }
+ if (r > 0)
+ r = tempfn_random_child(arg_directory, &np);
+ else
+ r = tempfn_random(arg_directory, &np);
if (r < 0) {
log_error_errno(r, "Failed to generate name for snapshot: %m");
goto finish;
diff --git a/src/shared/util.c b/src/shared/util.c
index 254b563..ee95a4b 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6977,6 +6977,14 @@ int tempfn_xxxxxx(const char *p, char **ret) {
assert(p);
assert(ret);
+ /*
+ * Turns this:
+ * /foo/bar/waldo
+ *
+ * Into this:
+ * /foo/bar/.waldoXXXXXX
+ */
+
fn = basename(p);
if (!filename_is_valid(fn))
return -EINVAL;
@@ -6987,7 +6995,7 @@ int tempfn_xxxxxx(const char *p, char **ret) {
strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), "."), fn), "XXXXXX");
- *ret = t;
+ *ret = path_kill_slashes(t);
return 0;
}
@@ -7000,6 +7008,14 @@ int tempfn_random(const char *p, char **ret) {
assert(p);
assert(ret);
+ /*
+ * Turns this:
+ * /foo/bar/waldo
+ *
+ * Into this:
+ * /foo/bar/.waldobaa2a261115984a9
+ */
+
fn = basename(p);
if (!filename_is_valid(fn))
return -EINVAL;
@@ -7018,7 +7034,39 @@ int tempfn_random(const char *p, char **ret) {
*x = 0;
- *ret = t;
+ *ret = path_kill_slashes(t);
+ return 0;
+}
+
+int tempfn_random_child(const char *p, char **ret) {
+ char *t, *x;
+ uint64_t u;
+ unsigned i;
+
+ assert(p);
+ assert(ret);
+
+ /* Turns this:
+ * /foo/bar/waldo
+ * Into this:
+ * /foo/bar/waldo/.3c2b6219aa75d7d0
+ */
+
+ t = new(char, strlen(p) + 2 + 16 + 1);
+ if (!t)
+ return -ENOMEM;
+
+ x = stpcpy(stpcpy(t, p), "/.");
+
+ u = random_u64();
+ for (i = 0; i < 16; i++) {
+ *(x++) = hexchar(u & 0xF);
+ u >>= 4;
+ }
+
+ *x = 0;
+
+ *ret = path_kill_slashes(t);
return 0;
}
diff --git a/src/shared/util.h b/src/shared/util.h
index 9a878ca..a8ccf20 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1018,6 +1018,7 @@ int fflush_and_check(FILE *f);
int tempfn_xxxxxx(const char *p, char **ret);
int tempfn_random(const char *p, char **ret);
+int tempfn_random_child(const char *p, char **ret);
bool is_localhost(const char *hostname);
commit df9a75e480ecbfe230589a7c1e8e0bb790ee0595
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 16:58:57 2014 +0100
nspawn: don't link journals in ephemeral mode
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 8082166..f6f20ab 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -687,6 +687,11 @@ static int parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
+ if (arg_ephemeral && !IN_SET(arg_link_journal, LINK_NO, LINK_AUTO)) {
+ log_error("--ephemeral and --link-journal= may not be combined.");
+ return -EINVAL;
+ }
+
if (arg_volatile != VOLATILE_NO && arg_read_only) {
log_error("Cannot combine --read-only with --volatile. Note that --volatile already implies a read-only base hierarchy.");
return -EINVAL;
@@ -1317,6 +1322,10 @@ static int setup_journal(const char *directory) {
char *id;
int r;
+ /* Don't link journals in ephemeral mode */
+ if (arg_ephemeral)
+ return 0;
+
p = strappend(directory, "/etc/machine-id");
if (!p)
return log_oom();
@@ -1345,8 +1354,7 @@ static int setup_journal(const char *directory) {
"Host and machine ids are equal (%s): refusing to link journals", id);
if (arg_link_journal == LINK_AUTO)
return 0;
- return
- -EEXIST;
+ return -EEXIST;
}
if (arg_link_journal == LINK_NO)
commit 53e438e3016e6b8304834d784fd0bbfeeb17cb77
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 16:58:30 2014 +0100
nspawn: properly unset arg_link_journal_try, when --link-journal= is specified
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1bfc99d..8082166 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -477,15 +477,19 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_LINK_JOURNAL:
- if (streq(optarg, "auto"))
+ if (streq(optarg, "auto")) {
arg_link_journal = LINK_AUTO;
- else if (streq(optarg, "no"))
+ arg_link_journal_try = false;
+ } else if (streq(optarg, "no")) {
arg_link_journal = LINK_NO;
- else if (streq(optarg, "guest"))
+ arg_link_journal_try = false;
+ } else if (streq(optarg, "guest")) {
arg_link_journal = LINK_GUEST;
- else if (streq(optarg, "host"))
+ arg_link_journal_try = false;
+ } else if (streq(optarg, "host")) {
arg_link_journal = LINK_HOST;
- else if (streq(optarg, "try-guest")) {
+ arg_link_journal_try = false;
+ } else if (streq(optarg, "try-guest")) {
arg_link_journal = LINK_GUEST;
arg_link_journal_try = true;
} else if (streq(optarg, "try-host")) {
commit 7430ec6ac08f2c0416d9f806964c46b30f3862b2
Author: Lennart Poettering <lennart at poettering.net>
Date: Fri Dec 12 16:24:33 2014 +0100
copy: use btrfs reflinking only whe we know we copy full files
diff --git a/src/core/ima-setup.c b/src/core/ima-setup.c
index 8e4fed1..0e0d16a 100644
--- a/src/core/ima-setup.c
+++ b/src/core/ima-setup.c
@@ -66,7 +66,7 @@ int ima_setup(void) {
return 0;
}
- r = copy_bytes(policyfd, imafd, -1);
+ r = copy_bytes(policyfd, imafd, (off_t) -1, false);
if (r < 0)
log_error_errno(r, "Failed to load the IMA custom policy file "IMA_POLICY_PATH": %m");
else
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 8678ec6..a37e5eb 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -316,7 +316,7 @@ static int save_external_coredump(
if (fd < 0)
return log_error_errno(errno, "Failed to create coredump file %s: %m", tmp);
- r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max);
+ r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max, false);
if (r == -EFBIG) {
log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", info[INFO_PID], info[INFO_COMM]);
goto fail;
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 72ae6c6..f6fd9cf 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -344,7 +344,7 @@ int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void
_exit(EXIT_FAILURE);
}
- r = copy_bytes(fd, pair[1], (off_t) -1);
+ r = copy_bytes(fd, pair[1], (off_t) -1, false);
if (r < 0)
_exit(EXIT_FAILURE);
diff --git a/src/shared/copy.c b/src/shared/copy.c
index 233dbbc..b4a85c7 100644
--- a/src/shared/copy.c
+++ b/src/shared/copy.c
@@ -25,7 +25,7 @@
#include "btrfs-util.h"
#include "copy.h"
-int copy_bytes(int fdf, int fdt, off_t max_bytes) {
+int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
bool try_sendfile = true;
int r;
@@ -33,10 +33,10 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes) {
assert(fdt >= 0);
/* Try btrfs reflinks first. */
- if (max_bytes == (off_t) -1) {
+ if (try_reflink && max_bytes == (off_t) -1) {
r = btrfs_reflink(fdf, fdt);
if (r >= 0)
- return 0;
+ return r;
}
for (;;) {
@@ -131,7 +131,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
if (fdt < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (off_t) -1);
+ r = copy_bytes(fdf, fdt, (off_t) -1, true);
if (r < 0) {
unlinkat(dt, to, 0);
return r;
@@ -318,7 +318,7 @@ int copy_tree_fd(int dirfd, const char *to, bool merge) {
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
}
-int copy_file_fd(const char *from, int fdt) {
+int copy_file_fd(const char *from, int fdt, bool try_reflink) {
_cleanup_close_ int fdf = -1;
assert(from);
@@ -328,7 +328,7 @@ int copy_file_fd(const char *from, int fdt) {
if (fdf < 0)
return -errno;
- return copy_bytes(fdf, fdt, (off_t) -1);
+ return copy_bytes(fdf, fdt, (off_t) -1, try_reflink);
}
int copy_file(const char *from, const char *to, int flags, mode_t mode) {
@@ -341,7 +341,7 @@ int copy_file(const char *from, const char *to, int flags, mode_t mode) {
if (fdt < 0)
return -errno;
- r = copy_file_fd(from, fdt);
+ r = copy_file_fd(from, fdt, true);
if (r < 0) {
close(fdt);
unlink(to);
diff --git a/src/shared/copy.h b/src/shared/copy.h
index 15faf54..201fe69 100644
--- a/src/shared/copy.h
+++ b/src/shared/copy.h
@@ -24,8 +24,8 @@
#include <stdbool.h>
#include <sys/types.h>
-int copy_file_fd(const char *from, int to);
+int copy_file_fd(const char *from, int to, bool try_reflink);
int copy_file(const char *from, const char *to, int flags, mode_t mode);
int copy_tree(const char *from, const char *to, bool merge);
int copy_tree_fd(int dirfd, const char *to, bool merge);
-int copy_bytes(int fdf, int fdt, off_t max_bytes);
+int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 5ed430c..a75e9de 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -4641,7 +4641,7 @@ static int cat(sd_bus *bus, char **args) {
ansi_highlight_off());
fflush(stdout);
- r = copy_file_fd(fragment_path, STDOUT_FILENO);
+ r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
if (r < 0) {
log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
continue;
@@ -4656,7 +4656,7 @@ static int cat(sd_bus *bus, char **args) {
ansi_highlight_off());
fflush(stdout);
- r = copy_file_fd(*path, STDOUT_FILENO);
+ r = copy_file_fd(*path, STDOUT_FILENO, false);
if (r < 0) {
log_warning_errno(r, "Failed to cat %s: %m", *path);
continue;
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 647eb57..0baa2c3 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -215,7 +215,7 @@ static int make_backup(const char *target, const char *x) {
if (r < 0)
return r;
- r = copy_bytes(src, fileno(dst), (off_t) -1);
+ r = copy_bytes(src, fileno(dst), (off_t) -1, true);
if (r < 0)
goto fail;
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index d2cad08..d70a0be 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -67,8 +67,8 @@ static void test_copy_file_fd(void) {
assert_se(out_fd >= 0);
assert_se(write_string_file(in_fn, text) == 0);
- assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd) < 0);
- assert_se(copy_file_fd(in_fn, out_fd) >= 0);
+ assert_se(copy_file_fd("/a/file/which/does/not/exist/i/guess", out_fd, true) < 0);
+ assert_se(copy_file_fd(in_fn, out_fd, true) >= 0);
assert_se(lseek(out_fd, SEEK_SET, 0) == 0);
assert_se(read(out_fd, buf, sizeof(buf)) == sizeof(text) - 1);
More information about the systemd-commits
mailing list