diff options
author | Shawn Landden <shawn@churchofgit.com> | 2013-12-05 06:20:08 -0800 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-12-06 00:38:13 -0500 |
commit | 2ed4e5e0b89cd1cf128803a62c0a27dd78e1c12e (patch) | |
tree | 719ddbe299074bd0ea6e7845283545b8f7496d3e | |
parent | 85ca9433abc00d8cc641fceafe9e87dfcd92af4a (diff) |
nspawn: fix buggy mount_binds, now works for bind-mounted files
-rw-r--r-- | src/nspawn/nspawn.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index dd7337bc91..eef0e9a281 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -418,39 +418,46 @@ static int mount_binds(const char *dest, char **l, unsigned long flags) { char **x, **y; STRV_FOREACH_PAIR(x, y, l) { - _cleanup_free_ char *where = NULL; + char *where; struct stat source_st, dest_st; + int r; if (stat(*x, &source_st) < 0) { log_error("failed to stat %s: %m", *x); return -errno; } - where = strjoin(dest, "/", *y, NULL); - if (!where) - return log_oom(); - - if (stat(where, &dest_st) == 0) { + where = strappenda(dest, *y); + r = stat(where, &dest_st); + if (r == 0) { if ((source_st.st_mode & S_IFMT) != (dest_st.st_mode & S_IFMT)) { log_error("The file types of %s and %s do not match. Refusing bind mount", *x, where); return -EINVAL; } - } else { - /* Create the mount point, but be conservative -- refuse to create block - * and char devices. */ - if (S_ISDIR(source_st.st_mode)) - mkdir_p_label(where, 0755); - else if (S_ISFIFO(source_st.st_mode)) - mkfifo(where, 0644); - else if (S_ISSOCK(source_st.st_mode)) - mknod(where, 0644 | S_IFSOCK, 0); - else if (S_ISREG(source_st.st_mode)) - touch(where); - else { - log_error("Refusing to create mountpoint for file: %s", *x); - return -ENOTSUP; + } else if (errno == ENOENT) { + r = mkdir_parents_label(where, 0755); + if (r < 0) { + log_error("Failed to bind mount %s: %s", *x, strerror(-r)); + return r; } + } else { + log_error("Failed to bind mount %s: %s", *x, strerror(errno)); + return -errno; + } + /* Create the mount point, but be conservative -- refuse to create block + * and char devices. */ + if (S_ISDIR(source_st.st_mode)) + mkdir_label(where, 0755); + else if (S_ISFIFO(source_st.st_mode)) + mkfifo(where, 0644); + else if (S_ISSOCK(source_st.st_mode)) + mknod(where, 0644 | S_IFSOCK, 0); + else if (S_ISREG(source_st.st_mode)) + touch(where); + else { + log_error("Refusing to create mountpoint for file: %s", *x); + return -ENOTSUP; } if (mount(*x, where, "bind", MS_BIND, NULL) < 0) { |