205 lines
6.5 KiB
Diff
205 lines
6.5 KiB
Diff
|
|
From 53ca847c8d21b1e422745a221d49ddf61679d4dd Mon Sep 17 00:00:00 2001
|
||
|
|
From: lifeng68 <lifeng68@huawei.com>
|
||
|
|
Date: Fri, 27 Nov 2020 16:02:25 +0800
|
||
|
|
Subject: [PATCH] mount: make possible to bind mount /proc and /sys/fs
|
||
|
|
|
||
|
|
1. add check whether have /proc mounts entry, if has, skip the auto
|
||
|
|
mount proc
|
||
|
|
2. mount cgroup before do mount entrys
|
||
|
|
3. pass if the mount on top of /proc and the source of the mount is a proc filesystem
|
||
|
|
|
||
|
|
Signed-off-by: lifeng68 <lifeng68@huawei.com>
|
||
|
|
---
|
||
|
|
src/lxc/conf.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++---
|
||
|
|
src/lxc/path.c | 2 +-
|
||
|
|
2 files changed, 92 insertions(+), 5 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
|
||
|
|
index ce5bab9c5..c3610ae33 100644
|
||
|
|
--- a/src/lxc/conf.c
|
||
|
|
+++ b/src/lxc/conf.c
|
||
|
|
@@ -2581,7 +2581,7 @@ retry:
|
||
|
|
|
||
|
|
/* isulad: checkMountDestination checks to ensure that the mount destination is not over the top of /proc.
|
||
|
|
* dest is required to be an abs path and have any symlinks resolved before calling this function. */
|
||
|
|
-static int check_mount_destination(const char *rootfs, const char *dest)
|
||
|
|
+static int check_mount_destination(const char *rootfs, const char *dest, const char *src)
|
||
|
|
{
|
||
|
|
const char *invalid_destinations[] = {
|
||
|
|
"/proc",
|
||
|
|
@@ -2641,10 +2641,28 @@ static int check_mount_destination(const char *rootfs, const char *dest)
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
relpath = path_relative(fullpath, dest);
|
||
|
|
+ DEBUG("dst path %s get relative path %s with full path %s,src:%s", dest, relpath, fullpath, src);
|
||
|
|
free(fullpath);
|
||
|
|
- if (!relpath)
|
||
|
|
+ if (!relpath) {
|
||
|
|
+ ERROR("Failed to get relpath for %s related to %s", dest, fullpath);
|
||
|
|
return -1;
|
||
|
|
- if (!strcmp(relpath, ".") || strncmp(relpath, "..", 2)) {
|
||
|
|
+ }
|
||
|
|
+ // pass if the mount path is outside of invalid proc
|
||
|
|
+ if (strncmp(relpath, "..", 2) == 0) {
|
||
|
|
+ free(relpath);
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ if (strcmp(relpath, ".") == 0) {
|
||
|
|
+ if (src == NULL) {
|
||
|
|
+ free(relpath);
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+ // pass if the mount on top of /proc and the source of the mount is a proc filesystem
|
||
|
|
+ if (has_fs_type(src, PROC_SUPER_MAGIC)) {
|
||
|
|
+ WARN("src %s is proc allow mount on-top of %s", src, *invalid);
|
||
|
|
+ free(relpath);
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
ERROR("%s cannot be mounted because it is located inside %s", dest, *invalid);
|
||
|
|
free(relpath);
|
||
|
|
return -1;
|
||
|
|
@@ -2706,7 +2724,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent,
|
||
|
|
}
|
||
|
|
dest = rpath;
|
||
|
|
|
||
|
|
- ret = check_mount_destination(rootfs_path, dest);
|
||
|
|
+ ret = check_mount_destination(rootfs_path, dest, mntent->mnt_fsname);
|
||
|
|
if (ret) {
|
||
|
|
ERROR("Mount destination is invalid: '%s'", dest);
|
||
|
|
lxc_write_error_message(rootfs->errfd, "%s:%d: mount destination is invalid: '%s'.",
|
||
|
|
@@ -3119,6 +3137,52 @@ static bool need_setup_dev(const struct lxc_conf *conf, struct lxc_list *mount)
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+static bool have_proc_bind_mount_entry(FILE *file)
|
||
|
|
+{
|
||
|
|
+ bool have_bind_proc = false;
|
||
|
|
+ char buf[PATH_MAX] = { 0 };
|
||
|
|
+ struct mntent mntent;
|
||
|
|
+
|
||
|
|
+ while (getmntent_r(file, &mntent, buf, sizeof(buf))) {
|
||
|
|
+ mntent.mnt_dir = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_dir);
|
||
|
|
+ if(mntent.mnt_dir == NULL) {
|
||
|
|
+ SYSERROR("memory allocation error");
|
||
|
|
+ continue;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ DEBUG("parsed mnt %s, %s, %s", mntent.mnt_fsname, mntent.mnt_dir, mntent.mnt_type);
|
||
|
|
+
|
||
|
|
+ if (strcmp(mntent.mnt_dir, "proc") == 0 && strcmp(mntent.mnt_type, "bind") == 0) {
|
||
|
|
+ have_bind_proc = true;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ free(mntent.mnt_dir);
|
||
|
|
+ mntent.mnt_dir = NULL;
|
||
|
|
+
|
||
|
|
+ if (have_bind_proc)
|
||
|
|
+ return true;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return false;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+// returns true if /proc needs to be set up.
|
||
|
|
+static bool need_setup_proc(const struct lxc_conf *conf, struct lxc_list *mount)
|
||
|
|
+{
|
||
|
|
+ __do_fclose FILE *f = NULL;
|
||
|
|
+
|
||
|
|
+ f = make_anonymous_mount_file(mount, conf->lsm_aa_allow_nesting);
|
||
|
|
+ if (f == NULL)
|
||
|
|
+ return true;
|
||
|
|
+
|
||
|
|
+ if (have_proc_bind_mount_entry(f)) {
|
||
|
|
+ return false;
|
||
|
|
+ } else {
|
||
|
|
+ return true;
|
||
|
|
+ }
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
#endif
|
||
|
|
|
||
|
|
static int parse_cap(const char *cap)
|
||
|
|
@@ -4870,6 +4934,7 @@ int lxc_setup(struct lxc_handler *handler)
|
||
|
|
char *keyring_context = NULL;
|
||
|
|
#ifdef HAVE_ISULAD
|
||
|
|
bool setup_dev = true;
|
||
|
|
+ bool setup_proc = true;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath);
|
||
|
|
@@ -4930,6 +4995,17 @@ int lxc_setup(struct lxc_handler *handler)
|
||
|
|
ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & ~LXC_AUTO_CGROUP_MASK, handler);
|
||
|
|
if (ret < 0)
|
||
|
|
return log_error(-1, "Failed to setup first automatic mounts");
|
||
|
|
+
|
||
|
|
+#ifdef HAVE_ISULAD
|
||
|
|
+ /* Now mount only cgroups, if wanted. Before, /sys could not have been
|
||
|
|
+ * mounted. It is guaranteed to be mounted now either through
|
||
|
|
+ * automatically or via fstab entries.
|
||
|
|
+ */
|
||
|
|
+ ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler);
|
||
|
|
+ if (ret < 0)
|
||
|
|
+ return log_error(-1, "Failed to setup remaining automatic mounts");
|
||
|
|
+#endif
|
||
|
|
+
|
||
|
|
#ifdef HAVE_ISULAD
|
||
|
|
ret = setup_mount(lxc_conf, &lxc_conf->rootfs, lxc_conf->fstab, name, lxcpath, lxc_conf->lsm_se_mount_context);
|
||
|
|
#else
|
||
|
|
@@ -4950,6 +5026,7 @@ int lxc_setup(struct lxc_handler *handler)
|
||
|
|
return log_error(-1, "Failed to setup mount entries");
|
||
|
|
#ifdef HAVE_ISULAD
|
||
|
|
setup_dev = need_setup_dev(lxc_conf, &lxc_conf->mount_list);
|
||
|
|
+ setup_proc = need_setup_proc(lxc_conf, &lxc_conf->mount_list);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -4975,6 +5052,7 @@ int lxc_setup(struct lxc_handler *handler)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+#ifndef HAVE_ISULAD
|
||
|
|
/* Now mount only cgroups, if wanted. Before, /sys could not have been
|
||
|
|
* mounted. It is guaranteed to be mounted now either through
|
||
|
|
* automatically or via fstab entries.
|
||
|
|
@@ -4982,6 +5060,7 @@ int lxc_setup(struct lxc_handler *handler)
|
||
|
|
ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler);
|
||
|
|
if (ret < 0)
|
||
|
|
return log_error(-1, "Failed to setup remaining automatic mounts");
|
||
|
|
+#endif
|
||
|
|
|
||
|
|
ret = run_lxc_hooks(name, "mount", lxc_conf, NULL);
|
||
|
|
if (ret < 0)
|
||
|
|
@@ -5026,9 +5105,17 @@ int lxc_setup(struct lxc_handler *handler)
|
||
|
|
if (ret < 0)
|
||
|
|
return log_error(-1, "Failed to setup \"/dev\" symlinks");
|
||
|
|
|
||
|
|
+#ifdef HAVE_ISULAD
|
||
|
|
+ if (setup_proc) {
|
||
|
|
+ ret = lxc_create_tmp_proc_mount(lxc_conf);
|
||
|
|
+ if (ret < 0)
|
||
|
|
+ return log_error(-1, "Failed to \"/proc\" LSMs");
|
||
|
|
+ }
|
||
|
|
+#else
|
||
|
|
ret = lxc_create_tmp_proc_mount(lxc_conf);
|
||
|
|
if (ret < 0)
|
||
|
|
return log_error(-1, "Failed to \"/proc\" LSMs");
|
||
|
|
+#endif
|
||
|
|
|
||
|
|
#ifdef HAVE_ISULAD
|
||
|
|
/* Ask father to run oci prestart hooks and wait for him to finish. */
|
||
|
|
diff --git a/src/lxc/path.c b/src/lxc/path.c
|
||
|
|
index 65b8aadbf..46256cb26 100644
|
||
|
|
--- a/src/lxc/path.c
|
||
|
|
+++ b/src/lxc/path.c
|
||
|
|
@@ -652,4 +652,4 @@ char *path_relative(const char *basepath, const char *targpath)
|
||
|
|
}
|
||
|
|
|
||
|
|
return safe_strdup(targ + t0);
|
||
|
|
-}
|
||
|
|
+}
|
||
|
|
\ No newline at end of file
|
||
|
|
--
|
||
|
|
2.25.1
|
||
|
|
|