xref: /kvmtool/guest/init.c (revision 5fab5964e210bc82340ea89ef65a6309cd08a8c2)
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>
1091d6a8e3SAsias He #include <linux/reboot.h>
11282113fdSPekka Enberg 
12282113fdSPekka Enberg static int run_process(char *filename)
13282113fdSPekka Enberg {
14282113fdSPekka Enberg 	char *new_argv[] = { filename, NULL };
15*5fab5964SSasha Levin 	char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0",
16*5fab5964SSasha Levin 				"HOME=/virt/home", NULL };
17282113fdSPekka Enberg 
18282113fdSPekka Enberg 	return execve(filename, new_argv, new_env);
19282113fdSPekka Enberg }
20282113fdSPekka Enberg 
2191d6a8e3SAsias He static int run_process_sandbox(char *filename)
2291d6a8e3SAsias He {
2391d6a8e3SAsias He 	char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
24*5fab5964SSasha Levin 	char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL };
2591d6a8e3SAsias He 
2691d6a8e3SAsias He 	return execve(filename, new_argv, new_env);
2791d6a8e3SAsias He }
2891d6a8e3SAsias He 
29282113fdSPekka Enberg static void do_mounts(void)
30282113fdSPekka Enberg {
31282113fdSPekka Enberg 	mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L");
32282113fdSPekka Enberg 	mount("", "/sys", "sysfs", 0, NULL);
33282113fdSPekka Enberg 	mount("proc", "/proc", "proc", 0, NULL);
34282113fdSPekka Enberg 	mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
3569071bceSAsias He 	mkdir("/dev/pts", 0755);
3669071bceSAsias He 	mount("devpts", "/dev/pts", "devpts", 0, NULL);
37282113fdSPekka Enberg }
38282113fdSPekka Enberg 
39282113fdSPekka Enberg int main(int argc, char *argv[])
40282113fdSPekka Enberg {
4191d6a8e3SAsias He 	pid_t child;
4291d6a8e3SAsias He 	int status;
4391d6a8e3SAsias He 
44282113fdSPekka Enberg 	puts("Mounting...");
45282113fdSPekka Enberg 
46282113fdSPekka Enberg 	do_mounts();
47282113fdSPekka Enberg 
4891d6a8e3SAsias He 	/* get session leader */
4991d6a8e3SAsias He 	setsid();
5091d6a8e3SAsias He 
5191d6a8e3SAsias He 	/* set controlling terminal */
5291d6a8e3SAsias He 	ioctl(0, TIOCSCTTY, 1);
5391d6a8e3SAsias He 
5491d6a8e3SAsias He 	child = fork();
5591d6a8e3SAsias He 	if (child < 0) {
5691d6a8e3SAsias He 		printf("Fatal: fork() failed with %d\n", child);
5791d6a8e3SAsias He 		return 0;
5891d6a8e3SAsias He 	} else if (child == 0) {
5991d6a8e3SAsias He 		if (access("/virt/sandbox.sh", R_OK) == 0)
6091d6a8e3SAsias He 			run_process_sandbox("/bin/sh");
6191d6a8e3SAsias He 		else
6291d6a8e3SAsias He 			run_process("/bin/sh");
6391d6a8e3SAsias He 	} else {
6491d6a8e3SAsias He 		waitpid(child, &status, 0);
6591d6a8e3SAsias He 	}
6691d6a8e3SAsias He 
6791d6a8e3SAsias He 	reboot(LINUX_REBOOT_CMD_RESTART);
68282113fdSPekka Enberg 
69282113fdSPekka Enberg 	printf("Init failed: %s\n", strerror(errno));
70282113fdSPekka Enberg 
71282113fdSPekka Enberg 	return 0;
72282113fdSPekka Enberg }
73