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
run_process(char * filename)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
run_process_sandbox(char * filename)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
do_mounts(void)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("sysfs", "/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
main(int argc,char * argv[])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 sync();
76 reboot(RB_AUTOBOOT);
77
78 printf("Init failed: %s\n", strerror(errno));
79
80 return 0;
81 }
82