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 #ifndef CONFIG_GUEST_PRE_INIT 34 mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L"); 35 #endif 36 mount("", "/sys", "sysfs", 0, NULL); 37 mount("proc", "/proc", "proc", 0, NULL); 38 mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); 39 mkdir("/dev/pts", 0755); 40 mount("devpts", "/dev/pts", "devpts", 0, NULL); 41 } 42 43 int main(int argc, char *argv[]) 44 { 45 pid_t child; 46 int status; 47 48 puts("Mounting..."); 49 50 do_mounts(); 51 52 /* get session leader */ 53 setsid(); 54 55 /* set controlling terminal */ 56 ioctl(0, TIOCSCTTY, 1); 57 58 child = fork(); 59 if (child < 0) { 60 printf("Fatal: fork() failed with %d\n", child); 61 return 0; 62 } else if (child == 0) { 63 if (access("/virt/sandbox.sh", R_OK) == 0) 64 run_process_sandbox("/bin/sh"); 65 else 66 run_process("/bin/sh"); 67 } else { 68 pid_t corpse; 69 70 do { 71 corpse = waitpid(-1, &status, 0); 72 } while (corpse != child); 73 } 74 75 reboot(RB_AUTOBOOT); 76 77 printf("Init failed: %s\n", strerror(errno)); 78 79 return 0; 80 } 81