Builder script for the xenstore domain.
The initrd image is specified from the times when xenstored was inside a
linux initrd.
TODO: I've always given it 32M of RAM, but I imagine it would be fine
with *much* less.
TODO: Is this more generally useful with a little more abstraction?
Signed-off-by: Diego Ongaro <diego.ongaro@xxxxxxxxxx>
Signed-off-by: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx>
---
diff -r a138f1cc2ed9 .hgignore
--- a/.hgignore Wed Mar 18 16:17:11 2009 +0000
+++ b/.hgignore Wed Mar 18 16:28:52 2009 +0000
@@ -207,6 +207,7 @@
^tools/xcutils/xc_restore$
^tools/xcutils/xc_save$
^tools/xcutils/readnotes$
+^tools/xcutils/xs_dom_builder$
^tools/xenfb/sdlfb$
^tools/xenfb/vncfb$
^tools/xenmon/xentrace_setmask$
diff -r a138f1cc2ed9 tools/xcutils/Makefile
--- a/tools/xcutils/Makefile Wed Mar 18 16:17:11 2009 +0000
+++ b/tools/xcutils/Makefile Wed Mar 18 16:28:52 2009 +0000
@@ -14,7 +14,7 @@
CFLAGS += -Werror
CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore)
-PROGRAMS = xc_restore xc_save readnotes lsevtchn
+PROGRAMS = xc_restore xc_save readnotes lsevtchn xs_dom_builder
LDLIBS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore)
diff -r a138f1cc2ed9 tools/xcutils/xs_dom_builder.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/xcutils/xs_dom_builder.c Wed Mar 18 16:28:52 2009 +0000
@@ -0,0 +1,349 @@
+/*
+ * Builder script for the xenstore domain.
+ *
+ * Copyright 2008, Diego Ongaro <diego.ongaro@xxxxxxxxxx>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include <xenctrl.h>
+#include <xenguest.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <xenctrl.h>
+#include <xen/sys/xenbus.h>
+#include <unistd.h>
+
+#include <asm/ioctl.h>
+#include <stropts.h>
+
+#define DBG(...)
\
+do {
\
+ fprintf(stderr, "[%s:%d] %s(): ", __FILE__, __LINE__, __FUNCTION__);
\
+ fprintf(stderr, __VA_ARGS__);
\
+ fprintf(stderr, "\n");
\
+} while (0)
+#define DIE_TO(label, ...)
\
+do {
\
+ DBG(__VA_ARGS__);
\
+ goto label;
\
+} while (0)
+
+#define GENERATE_RANDOM_UUID 1
+
+static int xc_handle = -1;
+static int xce_handle = -1;
+
+struct build_info {
+ uint32_t domid;
+ xen_domain_handle_t uuid;
+ char *image_name;
+ char *ramdisk_name;
+ char *cmdline;
+ uint32_t dom0_grant_ref;
+ uint32_t dom0_port;
+ int use_ramdisk;
+ int num_vcpus;
+ int memory_size_mb;
+};
+
+static int
+write_domid(uint32_t domid)
+{
+ FILE *f;
+
+ f = fopen("/var/run/xenstore.did", "w");
+ if (f == NULL)
+ DIE_TO(fail, "fopen failed");
+
+ fprintf(f, "%" PRIu32 "\n", domid);
+ fclose(f);
+
+ return 0;
+
+fail:
+ return -1;
+}
+
+static int
+start(struct build_info *b)
+{
+ unsigned long store_mfn = -1;
+ unsigned long console_mfn = -1;
+ evtchn_port_or_error_t store_port = -1;
+ evtchn_port_or_error_t console_port = -1;
+ int rc;
+
+ /* an unbound port in the xenstore domain for its console */
+ console_port = xc_evtchn_alloc_unbound(xc_handle, b->domid, 0);
+ if (console_port == -1)
+ DIE_TO(fail, "alloc console_port failed (errno %d)", errno);
+
+ DBG("store_port=%d", store_port);
+ DBG("console_port=%d", console_port);
+ printf("STORE_PORT=%d\n", store_port);
+ printf("CONSOLE_PORT=%d\n", console_port);
+
+ DBG("starting domain with image = %s, ramdisk = %s, cmdline = '%s'",
+ b->image_name, b->ramdisk_name, b->cmdline);
+
+ rc = xc_linux_build(xc_handle,
+ b->domid,
+ b->memory_size_mb,
+ b->image_name,
+ b->use_ramdisk ? b->ramdisk_name : NULL,
+ b->cmdline,
+ "", /* elf xen features */
+ 0, /* flags */
+ store_port,
+ &store_mfn,
+ console_port,
+ &console_mfn);
+ if (rc != 0)
+ DIE_TO(fail, "xc_linux_build failed");
+
+ DBG("store_mfn=%lu", store_mfn);
+ DBG("console_mfn=%lu", console_mfn);
+ printf("STORE_MFN=%lu\n", store_mfn);
+ printf("CONSOLE_MFN=%lu\n", console_mfn);
+
+ rc = write_domid(b->domid);
+ if (rc != 0)
+ DIE_TO(fail, "writing domid in /var/run/ failed");
+
+ rc = xc_domain_unpause(xc_handle, b->domid);
+ if (rc != 0)
+ DIE_TO(fail, "unpause failed");
+
+ return 0;
+
+fail:
+ /* TODO: leaking domain, pages, ports, etc */
+ return -1;
+}
+
+static int
+prepare_cmdline(struct build_info *b)
+{
+ char buf[128];
+ int len;
+
+ len = sprintf(buf, " --local-domid=%" PRIu32
+ " --dom0-grant-ref=%" PRIu32
+ " --dom0-port=%" PRIu32,
+ b->domid, b->dom0_grant_ref, b->dom0_port);
+ if (len <= 0)
+ DIE_TO(fail, "sprintf failed");
+
+ len += strlen(b->cmdline) + 1;
+
+ b->cmdline = realloc(b->cmdline, len);
+ if (b->cmdline == NULL)
+ DIE_TO(fail, "realloc failed");
+
+ strcat(b->cmdline, buf);
+
+ return 0;
+
+fail:
+ return -1;
+}
+
+static int
+store_ioctl(struct build_info *b)
+{
+ struct xenbus_alloc xa = { .dom = b->domid };
+ int fd = -1;
+
+ fd = open("/proc/xen/xenbus", 0);
+ if (fd == -1)
+ DIE_TO(fail, "couldn't open /proc/xen/xenbus");
+
+ if (ioctl(fd, IOCTL_XENBUS_ALLOC, &xa) != 0)
+ DIE_TO(fail, "IOCTL_XENBUS_ALLOC failed (errno %d)", errno);
+
+ close(fd);
+
+ b->dom0_grant_ref = xa.grant_ref;
+ b->dom0_port = xa.port;
+
+ return 0;
+
+fail:
+ if (fd != -1)
+ close(fd);
+
+ return -1;
+}
+
+static int
+configure(struct build_info *b)
+{
+ struct xen_domctl domctl;
+ int rc;
+
+ /* TODO: is this necessary? */
+ rc = xc_domain_set_memmap_limit(xc_handle,
+ b->domid,
+ b->memory_size_mb * 1024);
+ if (rc != 0)
+ DIE_TO(fail, "xc_domain_set_memmap_limit failed (%d)", rc);
+
+ /* TODO: is this necessary? */
+ rc = xc_cpuid_apply_policy(xc_handle,
+ b->domid);
+ if (rc != 0)
+ DIE_TO(fail, "xc_cpuid_apply_policy failed (%d)", rc);
+
+ rc = xc_domain_setmaxmem(xc_handle,
+ b->domid,
+ b->memory_size_mb * 1024);
+ if (rc != 0)
+ DIE_TO(fail, "xc_domain_setmaxmem failed (%d)", rc);
+
+ /* TODO: is this necessary? */
+ rc = xc_domain_max_vcpus(xc_handle,
+ b->domid,
+ b->num_vcpus);
+ if (rc != 0)
+ DIE_TO(fail, "xc_domain_max_vcpus failed (%d)", rc);
+
+ domctl.cmd = XEN_DOMCTL_set_virq_handler;
+ domctl.domain = b->domid;
+ domctl.u.set_virq_handler.virq = VIRQ_DOM_EXC;
+ rc = xc_domctl(xc_handle, &domctl);
+ if (rc != 0) {
+ DIE_TO(fail, "xc_domctl set_virq_handler VIRQ_DOM_EXC failed "
+ "(%d, errno %d)", rc, errno);
+ }
+
+ return 0;
+
+fail:
+ return -1;
+}
+
+#if GENERATE_RANDOM_UUID
+static void
+generate_uuid(struct build_info *b)
+{
+ int i;
+ for (i = 0; i < sizeof(b->uuid); i++)
+ ((char*) b->uuid)[i] = (char) rand();
+}
+#else
+static void
+generate_uuid(struct build_info *b)
+{
+ memset(&b->uuid, 0, sizeof(b->uuid));
+}
+#endif
+
+static int
+build(struct build_info *b)
+{
+ generate_uuid(b);
+
+ if ((xc_domain_create(xc_handle,
+ 0, /* ssidref */
+ b->uuid,
+ 0, /* flags */
+ &b->domid)) != 0) {
+ DIE_TO(fail, "xc_domain_create failed");
+ }
+
+ DBG("domain create assigned domid %" PRIu32, b->domid);
+ printf("DOMID=%" PRIu32 "\n", b->domid);
+
+ if (configure(b) != 0)
+ DIE_TO(destroy, "configure failed");
+
+ if (store_ioctl(b) != 0)
+ DIE_TO(destroy, "store_ioctl failed");
+
+ if (prepare_cmdline(b) != 0)
+ DIE_TO(destroy, "prepare_cmdline failed");
+
+ if (start(b) != 0)
+ DIE_TO(destroy, "start failed");
+
+ return 0;
+
+destroy:
+ if (xc_domain_destroy(xc_handle, b->domid) != 0)
+ DBG("xc_domain_destroy failed");
+fail:
+ return -1;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct build_info b = {
+ .domid = -1,
+ .uuid = {0},
+ .image_name = NULL,
+ .ramdisk_name = NULL,
+ .cmdline = NULL,
+ .use_ramdisk = 0,
+ .num_vcpus = 1,
+ .memory_size_mb = 32
+ };
+
+ if (argc != 4) {
+ fprintf(stderr, "Usage: %s image_name ramdisk_name cmdline\n",
argv[0]);
+ goto fail;
+ }
+
+ b.image_name = strdup(argv[1]);
+ b.ramdisk_name = strdup(argv[2]);
+ b.cmdline = strdup(argv[3]);
+ if (b.image_name == NULL || b.ramdisk_name == NULL || b.cmdline == NULL)
+ DIE_TO(free, "strdup failed");
+
+ b.use_ramdisk = (strcmp(b.ramdisk_name, "-") != 0);
+
+ if ((xc_handle = xc_interface_open()) == -1)
+ DIE_TO(free, "xc_interface_open failed");
+
+ if ((xce_handle = xc_evtchn_open()) == -1)
+ DIE_TO(close_xc_handle, "xc_evtchn_open failed");
+
+ if (build(&b) != 0)
+ DIE_TO(close_xce_handle, "build failed");
+
+ if (xc_evtchn_close(xce_handle) == -1)
+ DIE_TO(close_xc_handle, "xc_evtchn_close failed");
+
+ if (xc_interface_close(xc_handle) == -1)
+ DIE_TO(fail, "xc_interface_close failed");
+
+ free(b.image_name);
+ free(b.ramdisk_name);
+ free(b.cmdline);
+
+ return 0;
+
+close_xce_handle:
+ if (xc_evtchn_close(xce_handle) == -1)
+ DBG("xc_evtchn_close failed");
+close_xc_handle:
+ if (xc_interface_close(xc_handle) == -1)
+ DBG("xc_interface_close failed");
+free:
+ free(b.image_name);
+ free(b.ramdisk_name);
+ free(b.cmdline);
+fail:
+ return -1;
+}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|