mirror of
https://github.com/clearlinux/systemd-stable.git
synced 2026-09-08 06:31:56 +00:00
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!
This commit is contained in:
+17
-3
@@ -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;
|
||||
|
||||
+50
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user