From 542fd40b355d670ad5beadb06ee5b4bfe01fa8d8 Mon Sep 17 00:00:00 2001
From: liuhao <liuhao27@huawei.com>
Date: Fri, 26 Apr 2019 07:13:53 +0800
Subject: [PATCH 091/131] lxc: support namespaced kernel params can be changed
 in system container

support namespaced kernel params can be changed in system container

Signed-off-by: yangchenliang <yangchenliang@huawei.com>
---
 src/lxc/conf.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 14d5d807..0f227aa1 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1516,6 +1516,66 @@ error:
 	return false;
 }
 
+static bool remount_readwrite(const char *path)
+{
+	int ret, i;
+
+	if (!path)
+		return true;
+
+	for (i = 0; i < 5; i++) {
+		ret = mount("", path, "", MS_REMOUNT, "");
+		if (ret < 0 && errno != ENOENT) {
+			if (errno == EINVAL) {
+				// Probably not a mountpoint, use bind-mount
+				ret = mount(path, path, "", MS_BIND, "");
+				if (ret < 0)
+					goto on_error;
+				ret = mount(path, path, "", MS_BIND | MS_REMOUNT | MS_REC | \
+					    MS_NOEXEC | MS_NOSUID | MS_NODEV, "");
+				if (ret < 0)
+					goto on_error;
+			} else if (errno == EBUSY) {
+				DEBUG("Try to mount \"%s\" to readonly after 100ms.", path);
+				usleep(100 * 1000);
+				continue;
+			} else {
+				goto on_error;
+			}
+		}
+		return true;
+	}
+
+on_error:
+	SYSERROR("Unable to mount \"%s\" to readwrite", path);
+	return false;
+}
+
+static int remount_proc_sys_mount_entries(struct lxc_list *mount_list)
+{
+	char buf[4096];
+	FILE *file;
+	struct mntent mntent;
+
+	file = make_anonymous_mount_file(mount_list);
+	if (!file)
+		return -1;
+
+	while (getmntent_r(file, &mntent, buf, sizeof(buf))) {
+		if (strstr(mntent.mnt_dir, "proc/sys") == NULL) {
+			continue;
+		}
+
+		if (!remount_readwrite((const char*)mntent.mnt_dir)) {
+			fclose(file);
+			return -1;
+		}
+	}
+
+	fclose(file);
+	return 0;
+}
+
 // remount_readonly will bind over the top of an existing path and ensure that it is read-only.
 static bool remount_readonly(const char *path)
 {
@@ -2699,6 +2759,13 @@ static int mount_file_entries(const struct lxc_conf *conf,
 	int ret = -1;
 
 	while (getmntent_r(file, &mntent, buf, sizeof(buf))) {
+		//isulad, system contaienr, skip "proc/sys/xxx" path
+		if (conf->systemd != NULL && strcmp(conf->systemd, "true") == 0) {
+			if (strstr(mntent.mnt_dir, "proc/sys") != NULL) {
+				continue;
+			}
+		}
+
 		/* Note: Workaround for volume file path with space*/
 		mntent.mnt_fsname = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_fsname);
 		if(!mntent.mnt_fsname) {
@@ -4254,6 +4321,16 @@ int lxc_setup(struct lxc_handler *handler)
 		}
 	}
 
+	//isulad: system container, remount /proc/sys/xxx by mount_list
+	if (lxc_conf->systemd != NULL && strcmp(lxc_conf->systemd, "true") == 0) {
+		if (!lxc_list_empty(&lxc_conf->mount_list)) {
+			if (remount_proc_sys_mount_entries(&lxc_conf->mount_list)) {
+				ERROR("failed to remount /proc/sys");
+				goto on_error;
+			}
+		}
+	}
+
 	if (!lxc_list_empty(&lxc_conf->keepcaps)) {
 		if (!lxc_list_empty(&lxc_conf->caps)) {
 			ERROR("Container requests lxc.cap.drop and "
-- 
2.23.0

