[Toybox] [PATCH] Fix switch_root implementation.
Alistair Strachan
alistair.strachan at imgtec.com
Tue May 5 15:15:38 PDT 2015
Add the MS_MOVE of cwd to / and chroot into it. We don't need to
chdir after the chroot because xchroot already does this for us.
The switch_root toy was also blocking any case where NEW_ROOT/init
did not exist, even though NEW_INIT was a required parameter and
did not have to be '/init'. Change it to handle any NEW_INIT
passed as either a relative or absolute path.
With this change, the switch_root toy actually works from initramfs.
---
toys/other/switch_root.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/toys/other/switch_root.c b/toys/other/switch_root.c
index 0861c70..224fdb1 100644
--- a/toys/other/switch_root.c
+++ b/toys/other/switch_root.c
@@ -43,7 +43,7 @@ static int del_node(struct dirtree *node)
void switch_root_main(void)
{
- char *newroot = *toys.optargs, **cmdline = toys.optargs+1;
+ char *newroot = *toys.optargs, **cmdline = toys.optargs+1, *rel_cmdline;
struct stat st1, st2;
struct statfs stfs;
int console = console; // gcc's "may be used" warnings are broken.
@@ -68,7 +68,10 @@ void switch_root_main(void)
TT.rootdev=st2.st_dev;
// init program must exist and be an executable file
- if (stat("init", &st1) || !S_ISREG(st1.st_mode) || !(st1.st_mode&0100)) {
+ rel_cmdline = *cmdline[0] == '/' ? *cmdline+1 : *cmdline;
+ if (stat(rel_cmdline, &st1) || !S_ISREG(st1.st_mode) ||
+ !(st1.st_mode&0100))
+ {
error_msg("bad init");
goto panic;
}
@@ -81,6 +84,13 @@ void switch_root_main(void)
// Ok, enough safety checks: wipe root partition.
dirtree_read("/", del_node);
+ // Move the newroot to the old root and enter it
+ if (mount(".", "/", NULL, MS_MOVE, NULL)) {
+ error_msg("mount(.., MS_MOVE, ..) failed");
+ goto panic;
+ }
+ xchroot(".");
+
if (TT.console) {
int i;
for (i=0; i<3; i++) if (console != i) dup2(console, i);
--
2.1.4
More information about the Toybox
mailing list