#include #include #include #include #include #include #include #include int run(const char *path, ...) { va_list ap; char **argv; int argvMax, argvIdx; pid_t pid; int pidstat; pid = fork(); if (pid == ((pid_t) -1)) { return(-1); } if (pid != 0) { waitpid(pid, &pidstat, 0); return(pidstat); } argvMax = 32; argv = malloc(sizeof(*argv) * argvMax); va_start(ap, path); for (argvIdx = 0; argvIdx < argvMax; argvIdx++) { argv[argvIdx] = va_arg(ap, char *); if (argv[argvIdx] == NULL) { break; } } va_end(ap); execv(path, argv); exit(EXIT_FAILURE); } int main(int argc, char **argv) { int mount_ret; /* * Load kernel modules (drivers) */ mkdir("/sys", 0755); mount("sysfs", "/sys", "sysfs", 0, NULL); run("/bin/init-modules", "init-modules", NULL); umount("/sys"); rmdir("/sys"); /* * Mount root filesystem */ mkdir("/dev", 0755); mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); mkdir("/new-root", 0755); mount_ret = mount("/dev/vda2", "/new-root", "ext4", 0, NULL); if (mount_ret != 0) { mount_ret = mount("/dev/sda2", "/new-root", "ext4", 0, NULL); } if (mount_ret != 0) { mount_ret = mount("/dev/hda2", "/new-root", "ext4", 0, NULL); } umount("/dev"); rmdir("/dev"); if (mount_ret == 0) { mkdir("/new-root/initramfs", 0755); mkdir("/new-root/bin", 0755); mkdir("/new-root/lib", 0755); symlink("../initramfs/bin/appfsd", "/new-root/bin/appfsd"); symlink("../initramfs/bin/init", "/new-root/bin/init"); symlink("../initramfs/bin/init-modules", "/new-root/bin/init-modules"); symlink("../initramfs/bin/init-networking", "/new-root/bin/init-networking"); symlink("../initramfs/bin/appfs-cache", "/new-root/bin/appfs-cache"); symlink("../initramfs/bin/tclkit", "/new-root/bin/tclkit"); symlink("../initramfs/lib/modules", "/new-root/lib/modules"); chdir("/new-root"); mount("/", "/new-root/initramfs", "bind", MS_BIND, NULL); chroot("/new-root"); chdir("/"); } /* * Mount needed filesystems */ mkdir("/dev", 0755); mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); mkdir("/tmp", 0755); mount("tmpfs", "/tmp", "tmpfs", 0, NULL); mkdir("/proc", 0755); mount("proc", "/proc", "proc", 0, NULL); mkdir("/sys", 0755); mount("sysfs", "/sys", "sysfs", 0, NULL); /* * Setup networking */ run("/bin/init-networking", "init-networking", NULL); mkdir("/etc", 0755); mkdir("/bin", 0755); mkdir("/lib", 0755); mkdir("/opt", 0755); mkdir("/opt/appfs", 0755); mkdir("/var", 0755); mkdir("/var/cache", 0755); mkdir("/var/cache/appfs", 0755); run("/bin/appfsd", "appfsd", "/var/cache/appfs", "/opt/appfs", NULL); symlink(".", "/usr"); symlink("lib", "/lib64"); symlink("/proc/self/mounts", "/etc/mtab"); symlink("/opt/appfs/core.appfs.rkeene.org/bash/platform/latest/bin/bash", "/bin/bash"); symlink("/opt/appfs/core.appfs.rkeene.org/coreutils/platform/latest/bin/env", "/bin/env"); symlink("/bin/bash", "/bin/sh"); setenv("PATH", "/bin:/opt/appfs/core.appfs.rkeene.org/coreutils/platform/latest/bin", 1); run("/bin/appfs-cache", "appfs-cache", "install", "-lib", "core.appfs.rkeene.org", "glibc", NULL); run("/bin/appfs-cache", "appfs-cache", "install", "core.appfs.rkeene.org", "coreutils", NULL); run("/bin/appfs-cache", "appfs-cache", "install", "core.appfs.rkeene.org", "procps-ng", NULL); setenv("PATH", "/bin", 1); run("/bin/sh", "sh", NULL); sync(); return(0); }