xref: /kvmtool/guest/init.c (revision 5fab5964e210bc82340ea89ef65a6309cd08a8c2)
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 <linux/reboot.h>
11 
12 static int run_process(char *filename)
13 {
14 	char *new_argv[] = { filename, NULL };
15 	char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0",
16 				"HOME=/virt/home", NULL };
17 
18 	return execve(filename, new_argv, new_env);
19 }
20 
21 static int run_process_sandbox(char *filename)
22 {
23 	char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
24 	char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL };
25 
26 	return execve(filename, new_argv, new_env);
27 }
28 
29 static void do_mounts(void)
30 {
31 	mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L");
32 	mount("", "/sys", "sysfs", 0, NULL);
33 	mount("proc", "/proc", "proc", 0, NULL);
34 	mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
35 	mkdir("/dev/pts", 0755);
36 	mount("devpts", "/dev/pts", "devpts", 0, NULL);
37 }
38 
39 int main(int argc, char *argv[])
40 {
41 	pid_t child;
42 	int status;
43 
44 	puts("Mounting...");
45 
46 	do_mounts();
47 
48 	/* get session leader */
49 	setsid();
50 
51 	/* set controlling terminal */
52 	ioctl(0, TIOCSCTTY, 1);
53 
54 	child = fork();
55 	if (child < 0) {
56 		printf("Fatal: fork() failed with %d\n", child);
57 		return 0;
58 	} else if (child == 0) {
59 		if (access("/virt/sandbox.sh", R_OK) == 0)
60 			run_process_sandbox("/bin/sh");
61 		else
62 			run_process("/bin/sh");
63 	} else {
64 		waitpid(child, &status, 0);
65 	}
66 
67 	reboot(LINUX_REBOOT_CMD_RESTART);
68 
69 	printf("Init failed: %s\n", strerror(errno));
70 
71 	return 0;
72 }
73