Commit 21d1b2fd authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

mount: don't create a temporary directory for pivot_root()

I found this solution in the LXC code. We can open the old root, call
pivot_root(".", "."), call fchdir to the old root and call umount(".").

Now restore will not fail, if the root is read-only.
In addition it's a bit faster.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent c4a06a2a
...@@ -1464,7 +1464,7 @@ static int clean_mnt_ns(struct mount_info *mntinfo_tree) ...@@ -1464,7 +1464,7 @@ static int clean_mnt_ns(struct mount_info *mntinfo_tree)
static int cr_pivot_root(char *root) static int cr_pivot_root(char *root)
{ {
char put_root[] = "crtools-put-root.XXXXXX"; int old_root;
pr_info("Move the root to %s\n", root ? : "."); pr_info("Move the root to %s\n", root ? : ".");
...@@ -1475,34 +1475,36 @@ static int cr_pivot_root(char *root) ...@@ -1475,34 +1475,36 @@ static int cr_pivot_root(char *root)
} }
} }
if (mkdtemp(put_root) == NULL) { old_root = open("/", O_DIRECTORY | O_RDONLY);
pr_perror("Can't create a temporary directory"); if (old_root < 0) {
pr_perror("Unable to open /");
return -1; return -1;
} }
if (pivot_root(".", put_root)) { if (pivot_root(".", ".")) {
pr_perror("pivot_root(., %s) failed", put_root); close(old_root);
if (rmdir(put_root)) pr_perror("pivot_root(., .) failed");
pr_perror("Can't remove the directory %s", put_root);
return -1; return -1;
} }
if (mount("none", put_root, "none", MS_REC|MS_PRIVATE, NULL)) { if (fchdir(old_root)) {
pr_perror("Can't remount root with MS_PRIVATE"); perror("Unable to change working directory");
return -1; return -1;
} }
close(old_root);
if (mount("none", put_root, "none", MS_REC|MS_PRIVATE, NULL)) { if (mount("none", ".", "none", MS_REC|MS_PRIVATE, NULL)) {
pr_perror("Can't remount root with MS_PRIVATE"); pr_perror("Can't remount root with MS_PRIVATE");
return -1; return -1;
} }
if (umount2(put_root, MNT_DETACH)) { if (umount2(".", MNT_DETACH)) {
pr_perror("Can't umount %s", put_root); pr_perror("Can't umount the old root");
return -1; return -1;
} }
if (rmdir(put_root)) {
pr_perror("Can't remove the directory %s", put_root); if (chdir("/")) {
perror("Unable to change working directory");
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment