[klibc] [PATCH 8/8] switch_root: Move mount /dev, /proc, /sys to new root

maximilian attems max at stro.at
Wed Jul 13 06:48:33 PDT 2011


Further enhance switch_root() to take care of this.

As a side effect allows to get rid of 2 globals in kinit(8).

Signed-off-by: maximilian attems <max at stro.at>
---
 usr/kinit/kinit.c                      |   30 ++++--------------------------
 usr/kinit/switch_root/switch_root.c    |    1 +
 usr/kinit/switch_root/switch_rootlib.c |   20 ++++++++++++++++++--
 3 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/usr/kinit/kinit.c b/usr/kinit/kinit.c
index 9495d89..96d49c7 100644
--- a/usr/kinit/kinit.c
+++ b/usr/kinit/kinit.c
@@ -16,8 +16,6 @@
 #include "resume.h"
 
 const char *progname = "kinit";
-int mnt_procfs;
-int mnt_sysfs;
 
 #ifdef DEBUG
 void dump_args(int argc, char *argv[])
@@ -225,17 +223,13 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	mnt_procfs = mount_sys_fs("/proc/cmdline", "/proc", "proc") >= 0;
-	if (!mnt_procfs) {
-		ret = 1;
+	ret = mount_sys_fs("/proc/cmdline", "/proc", "proc") >= 0;
+	if (!ret)
 		goto bail;
-	}
 
-	mnt_sysfs = mount_sys_fs("/sys/bus", "/sys", "sysfs") >= 0;
-	if (!mnt_sysfs) {
-		ret = 1;
+	ret = mount_sys_fs("/sys/bus", "/sys", "sysfs") >= 0;
+	if (!ret)
 		goto bail;
-	}
 
 	/* Construct the effective kernel command line.  The
 	   effective kernel command line consists of /arch.cmd, if
@@ -288,16 +282,6 @@ int main(int argc, char *argv[])
 	check_path("/root");
 	do_mounts(cmdc, cmdv);
 
-	if (mnt_procfs) {
-		umount2("/proc", 0);
-		mnt_procfs = 0;
-	}
-
-	if (mnt_sysfs) {
-		umount2("/sys", 0);
-		mnt_sysfs = 0;
-	}
-
 	init_path = find_init("/root", get_arg(cmdc, cmdv, "init="));
 	if (!init_path) {
 		fprintf(stderr, "%s: init not found!\n", progname);
@@ -315,12 +299,6 @@ int main(int argc, char *argv[])
 	goto bail;
 
 bail:
-	if (mnt_procfs)
-		umount2("/proc", 0);
-
-	if (mnt_sysfs)
-		umount2("/sys", 0);
-
 	/*
 	 * If we get here, something bad probably happened, and the kernel
 	 * will most likely panic.  Drain console output so the user can
diff --git a/usr/kinit/switch_root/switch_root.c b/usr/kinit/switch_root/switch_root.c
index 68ef62d..efb9691 100644
--- a/usr/kinit/switch_root/switch_root.c
+++ b/usr/kinit/switch_root/switch_root.c
@@ -32,6 +32,7 @@
  * acting as /init in an initramfs; it does the following:
  *
  * - Delete all files in the initramfs;
+ * - Move mounts /dev, /proc, /sys to /real-root;
  * - Remounts /real-root onto the root filesystem;
  * - Chroots;
  * - Opens /dev/console;
diff --git a/usr/kinit/switch_root/switch_rootlib.c b/usr/kinit/switch_root/switch_rootlib.c
index b34f2b4..7fdbdd2 100644
--- a/usr/kinit/switch_root/switch_rootlib.c
+++ b/usr/kinit/switch_root/switch_rootlib.c
@@ -155,11 +155,27 @@ static int nuke(const char *what)
 const char *switch_root(const char *realroot, const char *console,
 		     const char *init, char **initargs)
 {
+	const char *umounts[] = { "/dev", "/proc", "/sys", NULL };
 	struct stat rst, cst;
 	struct statfs sfs;
-	int confd;
+	int confd, i;
 
-	/* First, change to the new root directory */
+	/* First, mount move sysdir from intramfs to new root  */
+	for (i = 0; umounts[i] != NULL; i++) {
+		char newmount[PATH_MAX];
+
+		snprintf(newmount, sizeof(newmount), "%s%s", realroot,
+				umounts[i]);
+
+		if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) {
+			fprintf(stderr, "failed to mount moving %s to %s",
+				umounts[i], newmount);
+			fprintf(stderr, "forcing unmount of %s", umounts[i]);
+			umount2(umounts[i], MNT_FORCE);
+		}
+	}
+
+	/* Next, change to the new root directory */
 	if (chdir(realroot))
 		return "chdir to new root";
 
-- 
1.7.5.4



More information about the klibc mailing list