[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 20/24] [xen-unstable.hg] new builder for creating xenstore stubdom





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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.