* [PATCH 20/24] [xen-unstable.hg] new builder for creating xenstore stubdom
@ 2009-03-23 15:21 Alex Zeffertt
0 siblings, 0 replies; only message in thread
From: Alex Zeffertt @ 2009-03-23 15:21 UTC (permalink / raw)
To: xen-devel@lists.xensource.com
[-- Attachment #1: Type: text/plain, Size: 2 bytes --]
[-- Attachment #2: xs_dom_builder --]
[-- Type: text/plain, Size: 9490 bytes --]
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@citrix.com>
Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com>
---
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@citrix.com>
+ *
+ * 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;
+}
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-03-23 15:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-23 15:21 [PATCH 20/24] [xen-unstable.hg] new builder for creating xenstore stubdom Alex Zeffertt
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.