#include #include #include #include #include #include #include #include // FIXME: Make this configurable. #define LUNA_ROOT_PARTITION "/dev/cd0p2" static void mount_devfs() { if (mkdir("/dev", 0755) < 0 && errno != EEXIST && errno != EROFS) exit(255); if (mount("/dev", "devfs", "devfs") < 0) exit(255); } static void open_std_streams() { stdin = fopen("/dev/console", "r"); stdout = fopen("/dev/console", "w"); stderr = fopen("/dev/console", "w"); } static void fail(const char* message) { open_std_streams(); fprintf(stderr, "preinit: fatal error: %s\n", message); exit(255); } static void fail_errno(const char* message) { int err = errno; open_std_streams(); fprintf(stderr, "preinit: fatal error: %s (%s)\n", message, strerror(err)); exit(255); } static void mount_rootfs() { if (mkdir("/osroot", 0755) < 0 && errno != EEXIST) exit(255); if (mount("/osroot", "ext2", LUNA_ROOT_PARTITION) < 0) fail_errno("Cannot mount the root partition"); } int main() { if (getpid() != 1) { fprintf(stderr, "error: preinit must be run as the init process.\n"); return 1; } mount_devfs(); mount_rootfs(); struct stat st; if (stat("/osroot/mnt", &st) < 0 || !S_ISDIR(st.st_mode)) fail("No suitable temporary mountpoint for pivot_root"); // Now that we have mounted the root file system, remove the /dev mount on the current ramfs root. umount("/dev"); long rc = syscall(SYS_pivot_root, "/osroot", "/osroot/mnt"); if (rc < 0) exit(255); chdir("/"); umount("/mnt"); // Now, mount the /dev file system on the new root. mount_devfs(); setenv("PATH", "/sbin:/usr/bin", 1); char* argv[] = { "init", nullptr }; char* envp[] = { nullptr }; execvpe(argv[0], argv, envp); fail_errno("Failed to execute init"); return 255; }