1282113fdSPekka Enberg /* 29cec19c8SSasha Levin * This is a simple init for shared rootfs guests. This part should be limited 39cec19c8SSasha Levin * to doing mounts and running stage 2 of the init process. 4282113fdSPekka Enberg */ 5282113fdSPekka Enberg #include <sys/mount.h> 6282113fdSPekka Enberg #include <string.h> 7282113fdSPekka Enberg #include <unistd.h> 8282113fdSPekka Enberg #include <stdio.h> 9282113fdSPekka Enberg #include <errno.h> 109ed717c3SAndre Przywara #include <sys/stat.h> 119ed717c3SAndre Przywara #include <sys/wait.h> 12372f583dSAndre Przywara #include <sys/reboot.h> 13282113fdSPekka Enberg 14282113fdSPekka Enberg static int run_process(char *filename) 15282113fdSPekka Enberg { 16282113fdSPekka Enberg char *new_argv[] = { filename, NULL }; 175fab5964SSasha Levin char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0", 185fab5964SSasha Levin "HOME=/virt/home", NULL }; 19282113fdSPekka Enberg 20282113fdSPekka Enberg return execve(filename, new_argv, new_env); 21282113fdSPekka Enberg } 22282113fdSPekka Enberg 2391d6a8e3SAsias He static int run_process_sandbox(char *filename) 2491d6a8e3SAsias He { 2591d6a8e3SAsias He char *new_argv[] = { filename, "/virt/sandbox.sh", NULL }; 265fab5964SSasha Levin char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL }; 2791d6a8e3SAsias He 2891d6a8e3SAsias He return execve(filename, new_argv, new_env); 2991d6a8e3SAsias He } 3091d6a8e3SAsias He 31282113fdSPekka Enberg static void do_mounts(void) 32282113fdSPekka Enberg { 335614f9d9SOleg Nesterov #ifndef CONFIG_GUEST_PRE_INIT 34282113fdSPekka Enberg mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L"); 355614f9d9SOleg Nesterov #endif 36*2f61a442SDmitry Monakhov mount("sysfs", "/sys", "sysfs", 0, NULL); 37282113fdSPekka Enberg mount("proc", "/proc", "proc", 0, NULL); 38282113fdSPekka Enberg mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); 3969071bceSAsias He mkdir("/dev/pts", 0755); 4069071bceSAsias He mount("devpts", "/dev/pts", "devpts", 0, NULL); 41282113fdSPekka Enberg } 42282113fdSPekka Enberg 43282113fdSPekka Enberg int main(int argc, char *argv[]) 44282113fdSPekka Enberg { 4591d6a8e3SAsias He pid_t child; 4691d6a8e3SAsias He int status; 4791d6a8e3SAsias He 48282113fdSPekka Enberg puts("Mounting..."); 49282113fdSPekka Enberg 50282113fdSPekka Enberg do_mounts(); 51282113fdSPekka Enberg 5291d6a8e3SAsias He /* get session leader */ 5391d6a8e3SAsias He setsid(); 5491d6a8e3SAsias He 5591d6a8e3SAsias He /* set controlling terminal */ 5691d6a8e3SAsias He ioctl(0, TIOCSCTTY, 1); 5791d6a8e3SAsias He 5891d6a8e3SAsias He child = fork(); 5991d6a8e3SAsias He if (child < 0) { 6091d6a8e3SAsias He printf("Fatal: fork() failed with %d\n", child); 6191d6a8e3SAsias He return 0; 6291d6a8e3SAsias He } else if (child == 0) { 6391d6a8e3SAsias He if (access("/virt/sandbox.sh", R_OK) == 0) 6491d6a8e3SAsias He run_process_sandbox("/bin/sh"); 6591d6a8e3SAsias He else 6691d6a8e3SAsias He run_process("/bin/sh"); 6791d6a8e3SAsias He } else { 681ad95468SMarc Zyngier pid_t corpse; 691ad95468SMarc Zyngier 701ad95468SMarc Zyngier do { 711ad95468SMarc Zyngier corpse = waitpid(-1, &status, 0); 721ad95468SMarc Zyngier } while (corpse != child); 7391d6a8e3SAsias He } 7491d6a8e3SAsias He 75372f583dSAndre Przywara reboot(RB_AUTOBOOT); 76282113fdSPekka Enberg 77282113fdSPekka Enberg printf("Init failed: %s\n", strerror(errno)); 78282113fdSPekka Enberg 79282113fdSPekka Enberg return 0; 80282113fdSPekka Enberg } 81