[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |