diff mbox

[1/4] kvm tools: Embed init and init_stage2 into lkvm binary

Message ID 1345639697-22680-1-git-send-email-asias.hejun@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Asias He Aug. 22, 2012, 12:48 p.m. UTC
We generate guest init and init_stage2 on the fly and put them in

   ~/.lkvm/$guest/virt/init
   ~/.lkvm/$guest/virt/init_stage2
.

This makes 'lkvm run' no longer depending on guest/{int, init_stage2}.

Further, we can merge init and init_stage2 since there is no need to
split the init function into two stages any more.

Signed-off-by: Asias He <asias.hejun@gmail.com>
---
 tools/kvm/Makefile      | 13 ++++++++-----
 tools/kvm/builtin-run.c | 50 +++++++++++++++++++++++++++++++++++--------------
 2 files changed, 44 insertions(+), 19 deletions(-)
diff mbox

Patch

diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 2bf931b..1099b76 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -286,14 +286,15 @@  KVMTOOLS-VERSION-FILE:
 # $(OTHEROBJS) are things that do not get substituted like this.
 #
 STATIC_OBJS = $(patsubst %.o,%.static.o,$(OBJS) $(OBJS_STATOPT))
+GUEST_OBJS = guest/guest_init.o guest/guest_init_stage2.o
 
-$(PROGRAM)-static:  $(DEPS) $(STATIC_OBJS) $(OTHEROBJS)
+$(PROGRAM)-static:  $(DEPS) $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_INIT) $(GUEST_INIT_S2)
 	$(E) "  LINK    " $@
-	$(Q) $(CC) -static $(CFLAGS) $(STATIC_OBJS) $(OTHEROBJS) $(LIBS) $(LIBS_STATOPT) -o $@
+	$(Q) $(CC) -static $(CFLAGS) $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_OBJS) $(LIBS) $(LIBS_STATOPT) -o $@
 
-$(PROGRAM): $(DEPS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS)
+$(PROGRAM): $(DEPS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_INIT) $(GUEST_INIT_S2)
 	$(E) "  LINK    " $@
-	$(Q) $(CC) $(CFLAGS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(LIBS) $(LIBS_DYNOPT) -o $@
+	$(Q) $(CC) $(CFLAGS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_OBJS) $(LIBS) $(LIBS_DYNOPT) -o $@
 
 $(PROGRAM_ALIAS): $(PROGRAM)
 	$(E) "  LN      " $@
@@ -302,10 +303,12 @@  $(PROGRAM_ALIAS): $(PROGRAM)
 $(GUEST_INIT): guest/init.c
 	$(E) "  LINK    " $@
 	$(Q) $(CC) -static guest/init.c -o $@
+	$(Q) ld -r -b binary -o guest/guest_init.o $(GUEST_INIT)
 
 $(GUEST_INIT_S2): guest/init_stage2.c
 	$(E) "  LINK    " $@
 	$(Q) $(CC) -static guest/init_stage2.c -o $@
+	$(Q) ld -r -b binary -o guest/guest_init_stage2.o $(GUEST_INIT_S2)
 
 $(DEPS):
 
@@ -403,7 +406,7 @@  clean:
 	$(Q) rm -f x86/bios/bios-rom.h
 	$(Q) rm -f tests/boot/boot_test.iso
 	$(Q) rm -rf tests/boot/rootfs/
-	$(Q) rm -f $(DEPS) $(OBJS) $(OTHEROBJS) $(OBJS_DYNOPT) $(STATIC_OBJS) $(PROGRAM) $(PROGRAM_ALIAS) $(PROGRAM)-static $(GUEST_INIT) $(GUEST_INIT_S2)
+	$(Q) rm -f $(DEPS) $(OBJS) $(OTHEROBJS) $(OBJS_DYNOPT) $(STATIC_OBJS) $(PROGRAM) $(PROGRAM_ALIAS) $(PROGRAM)-static $(GUEST_INIT) $(GUEST_INIT_S2) $(GUEST_OBJS)
 	$(Q) rm -f cscope.*
 	$(Q) rm -f tags
 	$(Q) rm -f TAGS
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index befce9e..1b407a6 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -111,6 +111,11 @@  bool do_debug_print = false;
 static int nrcpus;
 static int vidmode = -1;
 
+extern char _binary_guest_init_stage2_start;
+extern char _binary_guest_init_stage2_size;
+extern char _binary_guest_init_start;
+extern char _binary_guest_init_size;
+
 static const char * const run_usage[] = {
 	"lkvm run [<options>] [<kernel image>]",
 	NULL
@@ -803,24 +808,41 @@  void kvm_run_help(void)
 	usage_with_options(run_usage, options);
 }
 
-static int kvm_custom_stage2(void)
+static int kvm_setup_guest_init(void)
 {
-	char tmp[PATH_MAX], dst[PATH_MAX], *src;
 	const char *rootfs = custom_rootfs_name;
-	int r;
-
-	src = realpath("guest/init_stage2", NULL);
-	if (src == NULL)
-		return -ENOMEM;
+	char tmp[PATH_MAX];
+	size_t size;
+	int fd, ret;
+	char *data;
+
+	/* Setup /virt/init */
+	size = (size_t)&_binary_guest_init_size;
+	data = (char *)&_binary_guest_init_start;
+	snprintf(tmp, PATH_MAX, "%s%s/virt/init", kvm__get_dir(), rootfs);
+	remove(tmp);
+	fd = open(tmp, O_CREAT | O_WRONLY, 0755);
+	if (fd < 0)
+		die("Fail to setup %s", tmp);
+	ret = xwrite(fd, data, size);
+	if (ret < 0)
+		die("Fail to setup %s", tmp);
+	close(fd);
 
+	/* Setup /virt/init_stage2 */
+	size = (size_t)&_binary_guest_init_stage2_size;
+	data = (char *)&_binary_guest_init_stage2_start;
 	snprintf(tmp, PATH_MAX, "%s%s/virt/init_stage2", kvm__get_dir(), rootfs);
 	remove(tmp);
+	fd = open(tmp, O_CREAT | O_WRONLY, 0755);
+	if (fd < 0)
+		die("Fail to setup %s", tmp);
+	ret = xwrite(fd, data, size);
+	if (ret < 0)
+		die("Fail to setup %s", tmp);
+	close(fd);
 
-	snprintf(dst, PATH_MAX, "/host/%s", src);
-	r = symlink(dst, tmp);
-	free(src);
-
-	return r;
+	return 0;
 }
 
 static int kvm_run_set_sandbox(void)
@@ -1147,8 +1169,8 @@  static int kvm_cmd_run_init(int argc, const char **argv)
 
 			if (!no_dhcp)
 				strcat(real_cmdline, "  ip=dhcp");
-			if (kvm_custom_stage2())
-				die("Failed linking stage 2 of init.");
+			if (kvm_setup_guest_init())
+				die("Failed to setup init for guest.");
 		}
 	} else if (!strstr(real_cmdline, "root=")) {
 		strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline));