1 /* 2 * This is a simple init for shared rootfs guests. This part should be limited 3 * to doing mounts and running stage 2 of the init process. 4 */ 5 #include <sys/mount.h> 6 #include <string.h> 7 #include <unistd.h> 8 #include <stdio.h> 9 #include <errno.h> 10 #include <linux/reboot.h> 11 12 static int run_process(char *filename) 13 { 14 char *new_argv[] = { filename, NULL }; 15 char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0", 16 "HOME=/virt/home", NULL }; 17 18 return execve(filename, new_argv, new_env); 19 } 20 21 static int run_process_sandbox(char *filename) 22 { 23 char *new_argv[] = { filename, "/virt/sandbox.sh", NULL }; 24 char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL }; 25 26 return execve(filename, new_argv, new_env); 27 } 28 29 static void do_mounts(void) 30 { 31 mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L"); 32 mount("", "/sys", "sysfs", 0, NULL); 33 mount("proc", "/proc", "proc", 0, NULL); 34 mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); 35 mkdir("/dev/pts", 0755); 36 mount("devpts", "/dev/pts", "devpts", 0, NULL); 37 } 38 39 int main(int argc, char *argv[]) 40 { 41 pid_t child; 42 int status; 43 44 puts("Mounting..."); 45 46 do_mounts(); 47 48 /* get session leader */ 49 setsid(); 50 51 /* set controlling terminal */ 52 ioctl(0, TIOCSCTTY, 1); 53 54 child = fork(); 55 if (child < 0) { 56 printf("Fatal: fork() failed with %d\n", child); 57 return 0; 58 } else if (child == 0) { 59 if (access("/virt/sandbox.sh", R_OK) == 0) 60 run_process_sandbox("/bin/sh"); 61 else 62 run_process("/bin/sh"); 63 } else { 64 waitpid(child, &status, 0); 65 } 66 67 reboot(LINUX_REBOOT_CMD_RESTART); 68 69 printf("Init failed: %s\n", strerror(errno)); 70 71 return 0; 72 } 73