xref: /kvmtool/guest/init.c (revision 372f583d359a5bdcbbe7268809c8d1dc179c64d2)
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