]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
switch_root: handle /run and do not mount over existing mounts
authorHarald Hoyer <harald@redhat.com>
Thu, 20 Oct 2011 08:05:20 +0000 (10:05 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 20 Oct 2011 08:12:28 +0000 (10:12 +0200)
Handle /run just like /dev, /sys and /proc

Do not mount move, if there is already something mounted on the
destination folder.

Signed-off-by: Harald Hoyer <harald@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/switch_root.c

index 2dfed71a065ca86f4ce5dce015248e9fb7c8f8f7..f86b8c697a887de3d88ef6d25daf2984a48a7b9c 100644 (file)
@@ -111,16 +111,28 @@ done:
 static int switchroot(const char *newroot)
 {
        /*  Don't try to unmount the old "/", there's no way to do it. */
-       const char *umounts[] = { "/dev", "/proc", "/sys", NULL };
+       const char *umounts[] = { "/dev", "/proc", "/sys", "/run", NULL };
        int i;
        int cfd;
        pid_t pid;
+       struct stat newroot_stat, sb;
+
+       if (stat(newroot, &newroot_stat) != 0) {
+               warn("failed to stat directory %s", newroot);
+               return -1;
+       }
 
        for (i = 0; umounts[i] != NULL; i++) {
                char newmount[PATH_MAX];
 
                snprintf(newmount, sizeof(newmount), "%s%s", newroot, umounts[i]);
 
+               if ((stat(newmount, &sb) != 0) || (sb.st_dev != newroot_stat.st_dev)) {
+                       /* mount point seems to be mounted already or stat failed */
+                       umount(umounts[i]);
+                       continue;
+               }
+
                if (mount(umounts[i], newmount, NULL, MS_MOVE, NULL) < 0) {
                        warn("failed to mount moving %s to %s",
                                umounts[i], newmount);