Commit 183ebf0a by Serge Hallyn Committed by GitHub

Merge pull request #1725 from brauner/2017-08-01/handle_pre_mounted_dev

conf: NOTICE() on mounts on container's /dev
parents ebc52433 307eba8a
...@@ -4,11 +4,3 @@ lxc.cgroup.devices.allow = ...@@ -4,11 +4,3 @@ lxc.cgroup.devices.allow =
# We can't move bind-mounts, so don't use /dev/lxc/ # We can't move bind-mounts, so don't use /dev/lxc/
lxc.tty.dir = lxc.tty.dir =
# Extra bind-mounts for userns
lxc.mount.entry = /dev/full dev/full none bind,create=file 0 0
lxc.mount.entry = /dev/null dev/null none bind,create=file 0 0
lxc.mount.entry = /dev/random dev/random none bind,create=file 0 0
lxc.mount.entry = /dev/tty dev/tty none bind,create=file 0 0
lxc.mount.entry = /dev/urandom dev/urandom none bind,create=file 0 0
lxc.mount.entry = /dev/zero dev/zero none bind,create=file 0 0
...@@ -263,7 +263,7 @@ static void exec_criu(struct criu_opts *opts) ...@@ -263,7 +263,7 @@ static void exec_criu(struct criu_opts *opts)
for (i = 0; i < cgroup_num_hierarchies(); i++) { for (i = 0; i < cgroup_num_hierarchies(); i++) {
char **controllers = NULL, *fullname; char **controllers = NULL, *fullname;
char *path; char *path, *tmp;
if (!cgroup_get_hierarchies(i, &controllers)) { if (!cgroup_get_hierarchies(i, &controllers)) {
ERROR("failed to get hierarchy %d", i); ERROR("failed to get hierarchy %d", i);
...@@ -296,11 +296,15 @@ static void exec_criu(struct criu_opts *opts) ...@@ -296,11 +296,15 @@ static void exec_criu(struct criu_opts *opts)
} }
} }
if (!lxc_deslashify(&path)) { tmp = lxc_deslashify(path);
ERROR("failed to deslashify %s", path); if (!tmp) {
ERROR("Failed to remove extraneous slashes from \"%s\"",
path);
free(path); free(path);
goto err; goto err;
} }
free(path);
path = tmp;
fullname = lxc_string_join(",", (const char **) controllers, false); fullname = lxc_string_join(",", (const char **) controllers, false);
if (!fullname) { if (!fullname) {
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include <sys/prctl.h> #include <sys/prctl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/vfs.h>
#include <sys/wait.h> #include <sys/wait.h>
#include "log.h" #include "log.h"
...@@ -183,22 +182,24 @@ static int _recursive_rmdir(char *dirname, dev_t pdev, ...@@ -183,22 +182,24 @@ static int _recursive_rmdir(char *dirname, dev_t pdev,
return failed ? -1 : 0; return failed ? -1 : 0;
} }
/* we have two different magic values for overlayfs, yay */ /* We have two different magic values for overlayfs, yay. */
#ifndef OVERLAYFS_SUPER_MAGIC
#define OVERLAYFS_SUPER_MAGIC 0x794c764f #define OVERLAYFS_SUPER_MAGIC 0x794c764f
#endif
#ifndef OVERLAY_SUPER_MAGIC
#define OVERLAY_SUPER_MAGIC 0x794c7630 #define OVERLAY_SUPER_MAGIC 0x794c7630
/* #endif
* In overlayfs, st_dev is unreliable. so on overlayfs we don't do
* the lxc_rmdir_onedev() /* In overlayfs, st_dev is unreliable. So on overlayfs we don't do the
* lxc_rmdir_onedev()
*/ */
static bool is_native_overlayfs(const char *path) static bool is_native_overlayfs(const char *path)
{ {
struct statfs sb; if (has_fs_type(path, OVERLAY_SUPER_MAGIC) ||
has_fs_type(path, OVERLAYFS_SUPER_MAGIC))
if (statfs(path, &sb) < 0)
return false;
if (sb.f_type == OVERLAYFS_SUPER_MAGIC ||
sb.f_type == OVERLAY_SUPER_MAGIC)
return true; return true;
return false; return false;
} }
...@@ -728,47 +729,46 @@ char **lxc_normalize_path(const char *path) ...@@ -728,47 +729,46 @@ char **lxc_normalize_path(const char *path)
return components; return components;
} }
bool lxc_deslashify(char **path) char *lxc_deslashify(const char *path)
{ {
bool ret = false; char *dup, *p;
char *p;
char **parts = NULL; char **parts = NULL;
size_t n, len; size_t n, len;
parts = lxc_normalize_path(*path); dup = strdup(path);
if (!parts) if (!dup)
return false; return NULL;
parts = lxc_normalize_path(dup);
if (!parts) {
free(dup);
return NULL;
}
/* We'll end up here if path == "///" or path == "". */ /* We'll end up here if path == "///" or path == "". */
if (!*parts) { if (!*parts) {
len = strlen(*path); len = strlen(dup);
if (!len) { if (!len) {
ret = true; lxc_free_array((void **)parts, free);
goto out; return dup;
} }
n = strcspn(*path, "/"); n = strcspn(dup, "/");
if (n == len) { if (n == len) {
free(dup);
lxc_free_array((void **)parts, free);
p = strdup("/"); p = strdup("/");
if (!p) if (!p)
goto out; return NULL;
free(*path);
*path = p; return p;
ret = true;
goto out;
} }
} }
p = lxc_string_join("/", (const char **)parts, **path == '/'); p = lxc_string_join("/", (const char **)parts, *dup == '/');
if (!p) free(dup);
goto out;
free(*path);
*path = p;
ret = true;
out:
lxc_free_array((void **)parts, free); lxc_free_array((void **)parts, free);
return ret; return p;
} }
char *lxc_append_paths(const char *first, const char *second) char *lxc_append_paths(const char *first, const char *second)
...@@ -2384,3 +2384,25 @@ void *must_realloc(void *orig, size_t sz) ...@@ -2384,3 +2384,25 @@ void *must_realloc(void *orig, size_t sz)
return ret; return ret;
} }
bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val)
{
return (fs->f_type == (fs_type_magic)magic_val);
}
bool has_fs_type(const char *path, fs_type_magic magic_val)
{
bool has_type;
int ret;
struct statfs sb;
ret = statfs(path, &sb);
if (ret < 0)
return false;
has_type = is_fs_type(&sb, magic_val);
if (!has_type && magic_val == RAMFS_MAGIC)
WARN("When the ramfs it a tmpfs statfs() might report tmpfs");
return has_type;
}
...@@ -34,8 +34,10 @@ ...@@ -34,8 +34,10 @@
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include <linux/loop.h> #include <linux/loop.h>
#include <linux/magic.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/vfs.h>
#include "initutils.h" #include "initutils.h"
...@@ -273,7 +275,7 @@ extern char *lxc_string_join(const char *sep, const char **parts, bool use_as_pr ...@@ -273,7 +275,7 @@ extern char *lxc_string_join(const char *sep, const char **parts, bool use_as_pr
*/ */
extern char **lxc_normalize_path(const char *path); extern char **lxc_normalize_path(const char *path);
/* remove multiple slashes from the path, e.g. ///foo//bar -> /foo/bar */ /* remove multiple slashes from the path, e.g. ///foo//bar -> /foo/bar */
extern bool lxc_deslashify(char **path); extern char *lxc_deslashify(const char *path);
extern char *lxc_append_paths(const char *first, const char *second); extern char *lxc_append_paths(const char *first, const char *second);
/* Note: the following two functions use strtok(), so they will never /* Note: the following two functions use strtok(), so they will never
* consider an empty element, even if two delimiters are next to * consider an empty element, even if two delimiters are next to
...@@ -386,4 +388,9 @@ char *must_copy_string(const char *entry); ...@@ -386,4 +388,9 @@ char *must_copy_string(const char *entry);
/* Re-alllocate a pointer, do not fail */ /* Re-alllocate a pointer, do not fail */
void *must_realloc(void *orig, size_t sz); void *must_realloc(void *orig, size_t sz);
/* __typeof__ should be safe to use with all compilers. */
typedef __typeof__(((struct statfs *)NULL)->f_type) fs_type_magic;
bool has_fs_type(const char *path, fs_type_magic magic_val);
bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val);
#endif /* __LXC_UTILS_H */ #endif /* __LXC_UTILS_H */
...@@ -41,33 +41,37 @@ ...@@ -41,33 +41,37 @@
void test_lxc_deslashify(void) void test_lxc_deslashify(void)
{ {
char *s = strdup("/A///B//C/D/E/"); char *s = "/A///B//C/D/E/";
if (!s) char *t;
t = lxc_deslashify(s);
if (!t)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
lxc_test_assert_abort(lxc_deslashify(&s)); lxc_test_assert_abort(strcmp(t, "/A/B/C/D/E") == 0);
lxc_test_assert_abort(strcmp(s, "/A/B/C/D/E") == 0); free(t);
free(s);
s = strdup("/A"); s = "/A";
if (!s)
t = lxc_deslashify(s);
if (!t)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
lxc_test_assert_abort(lxc_deslashify(&s)); lxc_test_assert_abort(strcmp(t, "/A") == 0);
lxc_test_assert_abort(strcmp(s, "/A") == 0); free(t);
free(s);
s = strdup(""); s = "";
if (!s) t = lxc_deslashify(s);
if (!t)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
lxc_test_assert_abort(lxc_deslashify(&s)); lxc_test_assert_abort(strcmp(t, "") == 0);
lxc_test_assert_abort(strcmp(s, "") == 0); free(t);
free(s);
s = "//";
s = strdup("//"); t = lxc_deslashify(s);
if (!s) if (!t)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
lxc_test_assert_abort(lxc_deslashify(&s)); lxc_test_assert_abort(strcmp(t, "/") == 0);
lxc_test_assert_abort(strcmp(s, "/") == 0); free(t);
free(s);
} }
/* /proc/int_as_str/ns/mnt\0 = (5 + 21 + 7 + 1) */ /* /proc/int_as_str/ns/mnt\0 = (5 + 21 + 7 + 1) */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment