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
run_process(char * filename)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
run_process_sandbox(char * filename)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
do_mounts(void)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
362f61a442SDmitry 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
main(int argc,char * argv[])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
75*0964955dSJean-Philippe Brucker sync();
76372f583dSAndre Przywara reboot(RB_AUTOBOOT);
77282113fdSPekka Enberg
78282113fdSPekka Enberg printf("Init failed: %s\n", strerror(errno));
79282113fdSPekka Enberg
80282113fdSPekka Enberg return 0;
81282113fdSPekka Enberg }
82