]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - sys-utils/switch_root.c
Make the ways of using output stream consistent in usage()
[thirdparty/util-linux.git] / sys-utils / switch_root.c
index 3195c789892423fddd4b861b319ce8395e2c6c3c..ab8c2a141c4795ab984255b3abbebd970c888d66 100644 (file)
@@ -128,7 +128,12 @@ static int switchroot(const char *newroot)
        const char *umounts[] = { "/dev", "/proc", "/sys", "/run", NULL };
        int i;
        int cfd = -1;
-       struct stat newroot_stat, sb;
+       struct stat newroot_stat, oldroot_stat, sb;
+
+       if (stat("/", &oldroot_stat) != 0) {
+               warn(_("stat of %s failed"), "/");
+               return -1;
+       }
 
        if (stat(newroot, &newroot_stat) != 0) {
                warn(_("stat of %s failed"), newroot);
@@ -140,6 +145,11 @@ static int switchroot(const char *newroot)
 
                snprintf(newmount, sizeof(newmount), "%s%s", newroot, umounts[i]);
 
+               if ((stat(umounts[i], &sb) == 0) && sb.st_dev == oldroot_stat.st_dev) {
+                       /* mount point to move seems to be a normal directory or stat failed */
+                       continue;
+               }
+
                if ((stat(newmount, &sb) != 0) || (sb.st_dev != newroot_stat.st_dev)) {
                        /* mount point seems to be mounted already or stat failed */
                        umount2(umounts[i], MNT_DETACH);
@@ -220,8 +230,8 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_("Switch to another filesystem as the root of the mount tree.\n"), output);
 
        fputs(USAGE_OPTIONS, output);
-       printf(USAGE_HELP_OPTIONS(16));
-       printf(USAGE_MAN_TAIL("switch_root(8)"));
+       fprintf(output, USAGE_HELP_OPTIONS(16));
+       fprintf(output, USAGE_MAN_TAIL("switch_root(8)"));
 
        exit(EXIT_SUCCESS);
 }
@@ -270,4 +280,3 @@ int main(int argc, char *argv[])
        execv(init, initargs);
        errexec(init);
 }
-