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 <sys/stat.h> 11 #include <sys/wait.h> 12 #include <sys/reboot.h> 13 14 static int run_process(char *filename) 15 { 16 char *new_argv[] = { filename, NULL }; 17 char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0", 18 "HOME=/virt/home", NULL }; 19 20 return execve(filename, new_argv, new_env); 21 } 22 23 static int run_process_sandbox(char *filename) 24 { 25 char *new_argv[] = { filename, "/virt/sandbox.sh", NULL }; 26 char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL }; 27 28 return execve(filename, new_argv, new_env); 29 } 30 31 static void do_mounts(void) 32 { 33 mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L"); 34 mount("", "/sys", "sysfs", 0, NULL); 35 mount("proc", "/proc", "proc", 0, NULL); 36 mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); 37 mkdir("/dev/pts", 0755); 38 mount("devpts", "/dev/pts", "devpts", 0, NULL); 39 } 40 41 int main(int argc, char *argv[]) 42 { 43 pid_t child; 44 int status; 45 46 puts("Mounting..."); 47 48 do_mounts(); 49 50 /* get session leader */ 51 setsid(); 52 53 /* set controlling terminal */ 54 ioctl(0, TIOCSCTTY, 1); 55 56 child = fork(); 57 if (child < 0) { 58 printf("Fatal: fork() failed with %d\n", child); 59 return 0; 60 } else if (child == 0) { 61 if (access("/virt/sandbox.sh", R_OK) == 0) 62 run_process_sandbox("/bin/sh"); 63 else 64 run_process("/bin/sh"); 65 } else { 66 pid_t corpse; 67 68 do { 69 corpse = waitpid(-1, &status, 0); 70 } while (corpse != child); 71 } 72 73 reboot(RB_AUTOBOOT); 74 75 printf("Init failed: %s\n", strerror(errno)); 76 77 return 0; 78 } 79