*
* Switch from rootfs to another filesystem as the root of the mount tree.
*
- * Licensed under GPL version 2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
*/
-#include "libbb.h"
-#include <sys/vfs.h>
+//usage:#define switch_root_trivial_usage
+//usage: "[-c /dev/console] NEW_ROOT NEW_INIT [ARGS]"
+//usage:#define switch_root_full_usage "\n\n"
+//usage: "Free initramfs and switch to another root fs:\n"
+//usage: "chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,\n"
+//usage: "execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.\n"
+//usage: "\n -c DEV Reopen stdio to DEV after switch"
+
+#include <sys/vfs.h>
+#include <sys/mount.h>
+#include "libbb.h"
// Make up for header deficiencies
#ifndef RAMFS_MAGIC
# define RAMFS_MAGIC ((unsigned)0x858458f6)
#endif
-
#ifndef TMPFS_MAGIC
# define TMPFS_MAGIC ((unsigned)0x01021994)
#endif
-
#ifndef MS_MOVE
# define MS_MOVE 8192
#endif
// Additional sanity checks: we're about to rm -rf /, so be REALLY SURE
// we mean it. I could make this a CONFIG option, but I would get email
// from all the people who WILL destroy their filesystems.
+ if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) {
+ bb_error_msg_and_die("/init is not a regular file");
+ }
statfs("/", &stfs); // this never fails
- if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)
- || ((unsigned)stfs.f_type != RAMFS_MAGIC
- && (unsigned)stfs.f_type != TMPFS_MAGIC)
+ if ((unsigned)stfs.f_type != RAMFS_MAGIC
+ && (unsigned)stfs.f_type != TMPFS_MAGIC
) {
- bb_error_msg_and_die("not rootfs");
+ bb_error_msg_and_die("root filesystem is not ramfs/tmpfs");
}
// Zap everything out of rootdev
}
xchroot(".");
// The chdir is needed to recalculate "." and ".." links
- xchdir("/");
+ /*xchdir("/"); - done in xchroot */
// If a new console specified, redirect stdin/stdout/stderr to it
if (console) {