From 68d3c92b40e049a257bf86dbb29fb274a5f1125e Mon Sep 17 00:00:00 2001
From: LiFeng <lifeng68@huawei.com>
Date: Sat, 18 Apr 2020 18:13:16 +0800
Subject: [PATCH] setupdev: add judge whether have mount /dev entry

reason: If user specify the Destination "/dev".
        1.Should not populate devices
        2.Should not setup devpts

Signed-off-by: LiFeng <lifeng68@huawei.com>
---
 src/lxc/conf.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 59 insertions(+), 3 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 4d8fa2a..e8568d8 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1942,6 +1942,9 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
 	if (ret < 0 && errno != EEXIST)
 		return log_error_errno(-errno, errno, "Failed to create console");
 
+#ifdef HAVE_ISULAD
+	if (console->slave > 0) {
+#endif
 	ret = fchmod(console->slave, S_IXUSR | S_IXGRP);
 	if (ret < 0)
 		return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name);
@@ -1949,7 +1952,9 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs,
 	ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path);
 	if (ret < 0)
 		return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, path);
-
+#ifdef HAVE_ISULAD
+	}
+#endif
 	DEBUG("Mounted pts device \"%s\" onto \"%s\"", console->name, path);
 	return 0;
 }
@@ -2913,6 +2918,51 @@ static int setup_mount_entries(const struct lxc_conf *conf,
 	return mount_file_entries(conf, rootfs, f, lxc_name, lxc_path);
 }
 
+#ifdef HAVE_ISULAD
+static bool have_dev_bind_mount_entry(FILE *file)
+{
+	bool have_bind_dev = false;
+	char buf[PATH_MAX];
+	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) {
+			SYSERROR("memory allocation error");
+			continue;
+		}
+
+		if (strcmp(mntent.mnt_dir, "dev") == 0 && strcmp(mntent.mnt_type, "bind") == 0) {
+			have_bind_dev = true;
+		}
+
+		free(mntent.mnt_dir);
+		mntent.mnt_dir = NULL;
+
+		if (have_bind_dev)
+			return true;
+	}
+
+	return false;
+}
+
+// returns true if /dev needs to be set up.
+static bool need_setup_dev(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)
+		return true;
+
+	if (have_dev_bind_mount_entry(f)) {
+		return false;
+	} else {
+		return true;
+	}
+}
+#endif
+
 static int parse_cap(const char *cap)
 {
 	size_t i;
@@ -4655,6 +4705,9 @@ int lxc_setup(struct lxc_handler *handler)
 	const char *lxcpath = handler->lxcpath, *name = handler->name;
 	struct lxc_conf *lxc_conf = handler->conf;
 	char *keyring_context = NULL;
+#ifdef HAVE_ISULAD
+	bool setup_dev = true;
+#endif
 
 	ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath);
 #ifdef HAVE_ISULAD
@@ -4723,6 +4776,9 @@ int lxc_setup(struct lxc_handler *handler)
 					  &lxc_conf->mount_list, name, lxcpath);
 		if (ret < 0)
 			return log_error(-1, "Failed to setup mount entries");
+#ifdef HAVE_ISULAD
+		setup_dev = need_setup_dev(lxc_conf, &lxc_conf->mount_list);
+#endif
 	}
 
 	if (lxc_conf->is_execute) {
@@ -4771,7 +4827,7 @@ int lxc_setup(struct lxc_handler *handler)
 
 #ifdef HAVE_ISULAD
 	/* isulad: setup devices which will be populated in the container. */
-	if (!lxc_list_empty(&lxc_conf->populate_devs)) {
+	if (!lxc_list_empty(&lxc_conf->populate_devs) && setup_dev) {
 		if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs) != 0) {
 			return log_error(-1, "Failed to setup devices in the container");
 		}
@@ -4813,7 +4869,7 @@ int lxc_setup(struct lxc_handler *handler)
 	if (setup_rootfs_mountopts(&lxc_conf->rootfs)) {
 			return log_error(-1, "failed to set rootfs for '%s'", name);
 	}
-	if (lxc_conf->rootfs.path) {
+	if (lxc_conf->rootfs.path != NULL && setup_dev) {
 		ret = lxc_setup_devpts(lxc_conf);
 		if (ret < 0) {
 			return log_error(-1, "Failed to setup new devpts instance for '%s'", name);
-- 
1.8.3.1

