summaryrefslogtreecommitdiffstats
path: root/sys-utils/switch_root.c
diff options
context:
space:
mode:
authorPeter Jones2009-06-19 21:44:32 +0200
committerKarel Zak2009-06-22 21:45:25 +0200
commit2a7ccc65e998fb5b5ad679866730bcdbfc2c1f88 (patch)
tree2666a4ad890ca80a1f9755a42ce982bd01d11141 /sys-utils/switch_root.c
parentswitch_root: fork before cleaning up the filesystem. (diff)
downloadkernel-qcow2-util-linux-2a7ccc65e998fb5b5ad679866730bcdbfc2c1f88.tar.gz
kernel-qcow2-util-linux-2a7ccc65e998fb5b5ad679866730bcdbfc2c1f88.tar.xz
kernel-qcow2-util-linux-2a7ccc65e998fb5b5ad679866730bcdbfc2c1f88.zip
switch_root: do recursiveRemove after our root is moved to avoid races.
This way there's no race between unlinking the /newroot directory and the MS_MOVE/chroot() to get away from it. Signed-off-by: Peter Jones <pjones@redhat.com>
Diffstat (limited to 'sys-utils/switch_root.c')
-rw-r--r--sys-utils/switch_root.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/sys-utils/switch_root.c b/sys-utils/switch_root.c
index 1de3a2e58..b947f5446 100644
--- a/sys-utils/switch_root.c
+++ b/sys-utils/switch_root.c
@@ -135,15 +135,6 @@ static int switchroot(const char *newroot)
}
cfd = open("/", O_RDONLY);
- if (cfd >= 0) {
- pid = fork();
- if (pid <= 0) {
- recursiveRemove(cfd);
- if (pid == 0)
- exit(EXIT_SUCCESS);
- }
- close(cfd);
- }
if (mount(newroot, "/", NULL, MS_MOVE, NULL) < 0) {
warn("failed to mount moving %s to /", newroot);
@@ -154,6 +145,16 @@ static int switchroot(const char *newroot)
warn("failed to change root");
return -1;
}
+
+ if (cfd >= 0) {
+ pid = fork();
+ if (pid <= 0) {
+ recursiveRemove(cfd);
+ if (pid == 0)
+ exit(EXIT_SUCCESS);
+ }
+ close(cfd);
+ }
return 0;
}