debuggers.hg

changeset 20462:8a91056bea81

libxenlight: initial libxenlight implementation under tools/libxl

Signed-off-by: Vincent Hanquez <Vincent.Hanquez@eu.citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Nov 09 19:54:28 2009 +0000 (2009-11-09)
parents 9479190566fd
children 9b393d47b22a
files tools/Makefile tools/libxl/Makefile tools/libxl/flexarray.c tools/libxl/flexarray.h tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_device.c tools/libxl/libxl_dom.c tools/libxl/libxl_exec.c tools/libxl/libxl_internal.c tools/libxl/libxl_internal.h tools/libxl/libxl_utils.c tools/libxl/libxl_utils.h tools/libxl/libxl_xshelp.c tools/libxl/osdeps.c tools/libxl/osdeps.h tools/libxl/xenguest.c tools/libxl/xl.c
line diff
     1.1 --- a/tools/Makefile	Mon Nov 09 19:45:06 2009 +0000
     1.2 +++ b/tools/Makefile	Mon Nov 09 19:54:28 2009 +0000
     1.3 @@ -32,6 +32,7 @@ SUBDIRS-$(CONFIG_Linux) += fs-back
     1.4  SUBDIRS-$(CONFIG_NetBSD) += fs-back
     1.5  SUBDIRS-$(CONFIG_IOEMU) += ioemu-dir
     1.6  SUBDIRS-y += xenpmd
     1.7 +SUBDIRS-y += libxl
     1.8  
     1.9  # These don't cross-compile
    1.10  ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/libxl/Makefile	Mon Nov 09 19:54:28 2009 +0000
     2.3 @@ -0,0 +1,72 @@
     2.4 +#
     2.5 +# tools/libxl/Makefile
     2.6 +#
     2.7 +
     2.8 +XEN_ROOT = ../..
     2.9 +include $(XEN_ROOT)/tools/Rules.mk
    2.10 +
    2.11 +MAJOR = 1.0
    2.12 +MINOR = 0
    2.13 +
    2.14 +#CFLAGS += -Werror
    2.15 +CFLAGS += -I. -fPIC
    2.16 +CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) $(CFLAGS_libxenstore)
    2.17 +
    2.18 +LDFLAGS = $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenguest) $(LDFLAGS_libxenstore) -luuid
    2.19 +
    2.20 +LIBCONFIG_URL ?= http://www.hyperrealm.com/libconfig
    2.21 +LIBCONFIG_SOURCE = libconfig-1.3.2
    2.22 +LIBCONFIG_OUTPUT = $(LIBCONFIG_SOURCE)/.libs
    2.23 +WGET=wget -c
    2.24 +
    2.25 +LIBXL_OBJS = flexarray.o libxl.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o xenguest.o osdeps.o libxl_utils.o
    2.26 +
    2.27 +CLIENTS = xl
    2.28 +
    2.29 +.PHONY: all
    2.30 +all: $(CLIENTS) libxenlight.so libxenlight.a
    2.31 +
    2.32 +libxenlight.so: libxenlight.so.$(MAJOR)
    2.33 +	ln -sf $< $@
    2.34 +
    2.35 +libxenlight.so.$(MAJOR): libxenlight.so.$(MAJOR).$(MINOR)
    2.36 +	ln -sf $< $@
    2.37 +
    2.38 +libxenlight.so.$(MAJOR).$(MINOR): $(LIBXL_OBJS)
    2.39 +	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenlight.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^
    2.40 +
    2.41 +libxenlight.a: $(LIBXL_OBJS)
    2.42 +	$(AR) rcs libxenlight.a $^
    2.43 +
    2.44 +$(LIBCONFIG_SOURCE).tar.gz:
    2.45 +	$(WGET) $(LIBCONFIG_URL)/$@
    2.46 +
    2.47 +$(LIBCONFIG_SOURCE): $(LIBCONFIG_SOURCE).tar.gz
    2.48 +	tar xzf $<
    2.49 +
    2.50 +$(LIBCONFIG_OUTPUT)/libconfig.so: $(LIBCONFIG_SOURCE)
    2.51 +	cd $(LIBCONFIG_SOURCE) && ./configure --prefix=$(DESTDIR)$(PREFIX) && $(MAKE)
    2.52 +
    2.53 +xl.o: $(LIBCONFIG_SOURCE)
    2.54 +	$(CC) $(CFLAGS) -I$(LIBCONFIG_SOURCE) -c xl.c
    2.55 +
    2.56 +$(CLIENTS): xl.o libxenlight.so $(LIBCONFIG_OUTPUT)/libconfig.so
    2.57 +	$(CC) $(LDFLAGS) -o $@ $< -L . -lxenlight -L$(LIBCONFIG_OUTPUT) -lconfig
    2.58 +
    2.59 +.PHONY: install
    2.60 +install: all
    2.61 +	$(INSTALL_PROG) xl $(DESTDIR)$(SBINDIR)
    2.62 +	$(INSTALL_PROG) libxenlight.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
    2.63 +	ln -sf libxenlight.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenlight.so.$(MAJOR)
    2.64 +	ln -sf libxenlight.so.$(MAJOR) $(DESTDIR)$(LIBDIR)/libxenlight.so
    2.65 +	$(INSTALL_DATA) libxenlight.a $(DESTDIR)$(LIBDIR)
    2.66 +	cd $(LIBCONFIG_SOURCE) && DESTDIR= $(MAKE) install
    2.67 +
    2.68 +.PHONY: clean
    2.69 +clean:
    2.70 +	$(RM) -f *.o *.so* *.a $(CLIENTS)
    2.71 +	$(RM) -rf $(LIBCONFIG_SOURCE)
    2.72 +
    2.73 +distclean: clean
    2.74 +	$(RM) -f $(LIBCONFIG_SOURCE).tar.gz
    2.75 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/libxl/flexarray.c	Mon Nov 09 19:54:28 2009 +0000
     3.3 @@ -0,0 +1,78 @@
     3.4 +/*
     3.5 + * Copyright (C) 2009      Citrix Ltd.
     3.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     3.7 + *
     3.8 + * This program is free software; you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU Lesser General Public License as published
    3.10 + * by the Free Software Foundation; version 2.1 only. with the special
    3.11 + * exception on linking described in file LICENSE.
    3.12 + *
    3.13 + * This program is distributed in the hope that it will be useful,
    3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.16 + * GNU Lesser General Public License for more details.
    3.17 + */
    3.18 +
    3.19 +#include <stdlib.h>
    3.20 +#include "flexarray.h"
    3.21 +
    3.22 +flexarray_t *flexarray_make(int size, int autogrow)
    3.23 +{
    3.24 +    flexarray_t *array = malloc(sizeof(struct flexarray));
    3.25 +    if (array) {
    3.26 +        array->size = size;
    3.27 +        array->autogrow = autogrow;
    3.28 +        array->data = calloc(size, sizeof(void *));
    3.29 +    }
    3.30 +    return array;
    3.31 +}
    3.32 +
    3.33 +void flexarray_free(flexarray_t *array)
    3.34 +{
    3.35 +    free(array->data);
    3.36 +    free(array);
    3.37 +}
    3.38 +
    3.39 +int flexarray_grow(flexarray_t *array, int extents)
    3.40 +{
    3.41 +    void **data;
    3.42 +    int newsize;
    3.43 +
    3.44 +    newsize = array->size + extents;
    3.45 +    data = realloc(array->data, sizeof(void *) * newsize);
    3.46 +    if (!data)
    3.47 +        return 1;
    3.48 +    array->size += extents;
    3.49 +    array->data = data;
    3.50 +    return 0;
    3.51 +}
    3.52 +
    3.53 +int flexarray_set(flexarray_t *array, unsigned int index, void *ptr)
    3.54 +{
    3.55 +    if (index >= array->size) {
    3.56 +        int newsize;
    3.57 +        if (!array->autogrow)
    3.58 +            return 1;
    3.59 +        newsize = (array->size * 2 < index) ? index + 1 : array->size * 2;
    3.60 +        if (flexarray_grow(array, newsize - array->size))
    3.61 +            return 2;
    3.62 +    }
    3.63 +    array->data[index] = ptr;
    3.64 +    return 0;
    3.65 +}
    3.66 +
    3.67 +int flexarray_get(flexarray_t *array, int index, void **ptr)
    3.68 +{
    3.69 +    if (index >= array->size)
    3.70 +        return 1;
    3.71 +    *ptr = array->data[index];
    3.72 +    return 0;
    3.73 +}
    3.74 +
    3.75 +void **flexarray_contents(flexarray_t *array)
    3.76 +{
    3.77 +    void **data;
    3.78 +    data = array->data;
    3.79 +    free(array);
    3.80 +    return data;
    3.81 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/libxl/flexarray.h	Mon Nov 09 19:54:28 2009 +0000
     4.3 @@ -0,0 +1,33 @@
     4.4 +/*
     4.5 + * Copyright (C) 2009      Citrix Ltd.
     4.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     4.7 + *
     4.8 + * This program is free software; you can redistribute it and/or modify
     4.9 + * it under the terms of the GNU Lesser General Public License as published
    4.10 + * by the Free Software Foundation; version 2.1 only. with the special
    4.11 + * exception on linking described in file LICENSE.
    4.12 + *
    4.13 + * This program is distributed in the hope that it will be useful,
    4.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.16 + * GNU Lesser General Public License for more details.
    4.17 + */
    4.18 +
    4.19 +#ifndef FLEXARRAY_H
    4.20 +#define FLEXARRAY_H
    4.21 +
    4.22 +typedef struct flexarray {
    4.23 +    int size;
    4.24 +    int autogrow;
    4.25 +    void **data; /* array of pointer */
    4.26 +} flexarray_t;
    4.27 +
    4.28 +flexarray_t *flexarray_make(int size, int autogrow);
    4.29 +void flexarray_free(flexarray_t *array);
    4.30 +int flexarray_grow(flexarray_t *array, int extents);
    4.31 +int flexarray_set(flexarray_t *array, unsigned int index, void *ptr);
    4.32 +int flexarray_get(flexarray_t *array, int index, void **ptr);
    4.33 +
    4.34 +void **flexarray_contents(flexarray_t *array);
    4.35 +
    4.36 +#endif
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/libxl/libxl.c	Mon Nov 09 19:54:28 2009 +0000
     5.3 @@ -0,0 +1,742 @@
     5.4 +/*
     5.5 + * Copyright (C) 2009      Citrix Ltd.
     5.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     5.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
     5.8 + *
     5.9 + * This program is free software; you can redistribute it and/or modify
    5.10 + * it under the terms of the GNU Lesser General Public License as published
    5.11 + * by the Free Software Foundation; version 2.1 only. with the special
    5.12 + * exception on linking described in file LICENSE.
    5.13 + *
    5.14 + * This program is distributed in the hope that it will be useful,
    5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.17 + * GNU Lesser General Public License for more details.
    5.18 + */
    5.19 +
    5.20 +#include <stdio.h>
    5.21 +#include <string.h>
    5.22 +#include <stdlib.h>
    5.23 +#include <sys/stat.h>
    5.24 +#include <sys/types.h>
    5.25 +#include <fcntl.h>
    5.26 +#include <sys/select.h>
    5.27 +#include <signal.h>
    5.28 +#include "libxl.h"
    5.29 +#include "libxl_utils.h"
    5.30 +#include "libxl_internal.h"
    5.31 +#include "flexarray.h"
    5.32 +
    5.33 +int libxl_ctx_init(struct libxl_ctx *ctx)
    5.34 +{
    5.35 +    memset(ctx, 0, sizeof(struct libxl_ctx));
    5.36 +    ctx->alloc_maxsize = 256;
    5.37 +    ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *));
    5.38 +    if (!ctx->alloc_ptrs)
    5.39 +        return ERROR_NOMEM;
    5.40 +
    5.41 +    ctx->xch = xc_interface_open();
    5.42 +    ctx->xsh = xs_daemon_open();
    5.43 +    return 0;
    5.44 +}
    5.45 +
    5.46 +int libxl_ctx_free(struct libxl_ctx *ctx)
    5.47 +{
    5.48 +    libxl_free_all(ctx);
    5.49 +    free(ctx->alloc_ptrs);
    5.50 +    ctx->alloc_ptrs = NULL;
    5.51 +    xc_interface_close(ctx->xch);
    5.52 +    xs_daemon_close(ctx->xsh);
    5.53 +    return 0;
    5.54 +}
    5.55 +
    5.56 +int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data)
    5.57 +{
    5.58 +    ctx->log_callback = log_callback;
    5.59 +    ctx->log_userdata = log_data;
    5.60 +    return 0;
    5.61 +}
    5.62 +
    5.63 +/******************************************************************************/
    5.64 +
    5.65 +int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info,
    5.66 +                       uint32_t *domid)
    5.67 +{
    5.68 +    int flags, ret, i;
    5.69 +        char *uuid_string;
    5.70 +    char *rw_paths[] = { "device" };
    5.71 +    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
    5.72 +                         "control", "attr", "data", "messages" };
    5.73 +    char *dom_path, *vm_path, *vss_path;
    5.74 +    struct xs_permissions roperm[2];
    5.75 +    struct xs_permissions rwperm[1];
    5.76 +    xs_transaction_t t;
    5.77 +
    5.78 +    uuid_string = uuid_to_string(ctx, info->uuid);
    5.79 +    if (!uuid_string) {
    5.80 +        XL_LOG(ctx, XL_LOG_ERROR, "missing uuid");
    5.81 +        return ERROR_FAIL;
    5.82 +    }
    5.83 +
    5.84 +    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
    5.85 +    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
    5.86 +    *domid = 0;
    5.87 +
    5.88 +    ret = xc_domain_create(ctx->xch, info->ssidref, info->uuid, flags, domid);
    5.89 +    if (ret < 0) {
    5.90 +        XL_LOG(ctx, XL_LOG_ERROR, "domain creation fail: %d", ret);
    5.91 +        return ERROR_FAIL;
    5.92 +    }
    5.93 +
    5.94 +    dom_path = libxl_xs_get_dompath(ctx, *domid);
    5.95 +    vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string);
    5.96 +    vss_path = libxl_sprintf(ctx, "/vss/%s", uuid_string);
    5.97 +    if (!dom_path || !vm_path || !vss_path) {
    5.98 +        XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths");
    5.99 +        return ERROR_FAIL;
   5.100 +    }
   5.101 +
   5.102 +    roperm[0].id = 0;
   5.103 +    roperm[0].perms = XS_PERM_NONE;
   5.104 +    roperm[1].id = *domid;
   5.105 +    roperm[1].perms = XS_PERM_READ;
   5.106 +    rwperm[0].id = *domid;
   5.107 +    rwperm[0].perms = XS_PERM_NONE;
   5.108 +
   5.109 +retry_transaction:
   5.110 +    t = xs_transaction_start(ctx->xsh);
   5.111 +    xs_rm(ctx->xsh, t, dom_path);
   5.112 +    xs_mkdir(ctx->xsh, t, dom_path);
   5.113 +    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
   5.114 +
   5.115 +    xs_rm(ctx->xsh, t, vm_path);
   5.116 +    xs_mkdir(ctx->xsh, t, vm_path);
   5.117 +    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
   5.118 +
   5.119 +    xs_rm(ctx->xsh, t, vss_path);
   5.120 +    xs_mkdir(ctx->xsh, t, vss_path);
   5.121 +    xs_set_permissions(ctx->xsh, t, vss_path, rwperm, ARRAY_SIZE(rwperm));
   5.122 +
   5.123 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, strlen(vm_path));
   5.124 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vss", dom_path), vss_path, strlen(vss_path));
   5.125 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", dom_path), info->name, strlen(info->name));
   5.126 +
   5.127 +    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
   5.128 +        char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]);
   5.129 +        xs_mkdir(ctx->xsh, t, path);
   5.130 +        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
   5.131 +        libxl_free(ctx, path);
   5.132 +    }
   5.133 +    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
   5.134 +        char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]);
   5.135 +        xs_mkdir(ctx->xsh, t, path);
   5.136 +        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
   5.137 +        libxl_free(ctx, path);
   5.138 +    }
   5.139 +
   5.140 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
   5.141 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, strlen(info->name));
   5.142 +
   5.143 +    libxl_xs_writev(ctx, t, dom_path, info->xsdata);
   5.144 +    libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), info->platformdata);
   5.145 +
   5.146 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
   5.147 +
   5.148 +    if (!xs_transaction_end(ctx->xsh, t, 0))
   5.149 +        if (errno == EAGAIN)
   5.150 +            goto retry_transaction;
   5.151 +    return 0;
   5.152 +}
   5.153 +
   5.154 +int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid)
   5.155 +{
   5.156 +    libxl_domain_build_state state;
   5.157 +    char **vments = NULL, **localents = NULL;
   5.158 +
   5.159 +    memset(&state, '\0', sizeof(state));
   5.160 +
   5.161 +    build_pre(ctx, domid, info, &state);
   5.162 +    if (info->hvm) {
   5.163 +        build_hvm(ctx, domid, info, &state);
   5.164 +        vments = libxl_calloc(ctx, 4, sizeof(char *));
   5.165 +        vments[0] = libxl_sprintf(ctx, "rtc/timeoffset");
   5.166 +        vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "");
   5.167 +    } else {
   5.168 +        build_pv(ctx, domid, info, &state);
   5.169 +    }
   5.170 +    build_post(ctx, domid, info, &state, vments, localents);
   5.171 +    return 0;
   5.172 +}
   5.173 +
   5.174 +int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info,
   5.175 +                          uint32_t domid, int fd)
   5.176 +{
   5.177 +    libxl_domain_build_state state;
   5.178 +    char **vments = NULL, **localents = NULL;
   5.179 +
   5.180 +    memset(&state, '\0', sizeof(state));
   5.181 +
   5.182 +    build_pre(ctx, domid, info, &state);
   5.183 +    restore_common(ctx, domid, info, &state, fd);
   5.184 +    if (info->hvm) {
   5.185 +        vments = libxl_calloc(ctx, 4, sizeof(char *));
   5.186 +        vments[0] = libxl_sprintf(ctx, "rtc/timeoffset");
   5.187 +        vments[1] = libxl_sprintf(ctx, "%s", (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "");
   5.188 +    } else {
   5.189 +        localents = libxl_calloc(ctx, 4 * 2, sizeof(char *));
   5.190 +        localents[0] = libxl_sprintf(ctx, "serial/0/limit");
   5.191 +        localents[1] = libxl_sprintf(ctx, "%d", 65536);
   5.192 +        localents[2] = libxl_sprintf(ctx, "console/port");
   5.193 +        localents[3] = libxl_sprintf(ctx, "%d", state.console_port);
   5.194 +        localents[4] = libxl_sprintf(ctx, "console/ring-ref");
   5.195 +        localents[5] = libxl_sprintf(ctx, "%ld", state.console_mfn);
   5.196 +    }
   5.197 +    build_post(ctx, domid, info, &state, vments, localents);
   5.198 +    return 0;
   5.199 +}
   5.200 +
   5.201 +struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain)
   5.202 +{
   5.203 +    struct libxl_dominfo *ptr;
   5.204 +    int index, i, ret, first_domain;
   5.205 +    xc_domaininfo_t info[16];
   5.206 +    int size = 16;
   5.207 +
   5.208 +    first_domain = 1;
   5.209 +    index = 0;
   5.210 +    ptr = libxl_calloc(ctx, size, sizeof(struct libxl_dominfo));
   5.211 +    if (!ptr)
   5.212 +        return NULL;
   5.213 +redo:
   5.214 +    ret = xc_domain_getinfolist(ctx->xch, first_domain, 16, info);
   5.215 +    for (i = 0; i < ret; i++) {
   5.216 +        if (index == size) {
   5.217 +            struct libxl_dominfo *ptr2;
   5.218 +
   5.219 +            ptr2 = libxl_calloc(ctx, size * 2, sizeof(struct libxl_dominfo));
   5.220 +            if (!ptr2) {
   5.221 +                libxl_free(ctx, ptr);
   5.222 +                return NULL;
   5.223 +            }
   5.224 +            memcpy(ptr2, ptr, sizeof(struct libxl_dominfo) * size);
   5.225 +            libxl_free(ctx, ptr);
   5.226 +            ptr = ptr2;
   5.227 +            size *= 2;
   5.228 +        }
   5.229 +        memcpy(ptr[index].uuid, info[i].handle, 16 * sizeof(uint8_t));
   5.230 +        ptr[index].domid = info[i].domain;
   5.231 +        first_domain = info[i].domain + 1;
   5.232 +        index++;
   5.233 +    }
   5.234 +    if (ret == 16)
   5.235 +        goto redo;
   5.236 +    *nb_domain = index;
   5.237 +    return ptr;
   5.238 +}
   5.239 +
   5.240 +xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain)
   5.241 +{
   5.242 +    int index, first_domain;
   5.243 +    xc_dominfo_t *info;
   5.244 +    int size = 1024;
   5.245 +
   5.246 +    first_domain = 0;
   5.247 +    index = 0;
   5.248 +    info = (xc_dominfo_t *) libxl_calloc(ctx, size, sizeof(xc_dominfo_t));
   5.249 +    if (!info) {
   5.250 +        *nb_domain = 0;
   5.251 +        return NULL;
   5.252 +    }
   5.253 +    *nb_domain = xc_domain_getinfo(ctx->xch, first_domain, 1024, info);
   5.254 +    return info;
   5.255 +}
   5.256 +
   5.257 +int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info,
   5.258 +                         uint32_t domid, int fd)
   5.259 +{
   5.260 +    int hvm = 1;
   5.261 +    int live = 0;
   5.262 +    int debug = 0;
   5.263 +    char savesig[] = "XenSavedDomain\n";
   5.264 +
   5.265 +    write(fd, savesig, strlen(savesig));
   5.266 +
   5.267 +    core_suspend(ctx, domid, fd, hvm, live, debug);
   5.268 +
   5.269 +    return 0;
   5.270 +}
   5.271 +
   5.272 +int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid)
   5.273 +{
   5.274 +    xc_domain_pause(ctx->xch, domid);
   5.275 +    return 0;
   5.276 +}
   5.277 +
   5.278 +int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid)
   5.279 +{
   5.280 +    xc_domain_unpause(ctx->xch, domid);
   5.281 +    return 0;
   5.282 +}
   5.283 +
   5.284 +static char *req_table[] = {
   5.285 +    [0] = "poweroff",
   5.286 +    [1] = "reboot",
   5.287 +    [2] = "suspend",
   5.288 +    [3] = "crash",
   5.289 +    [4] = "halt",
   5.290 +};
   5.291 +
   5.292 +int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req)
   5.293 +{
   5.294 +    char *shutdown_path;
   5.295 +    char *dom_path;
   5.296 +
   5.297 +    if (req > ARRAY_SIZE(req_table))
   5.298 +        return ERROR_INVAL;
   5.299 +
   5.300 +    dom_path = libxl_xs_get_dompath(ctx, domid);
   5.301 +    shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path);
   5.302 +
   5.303 +    xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], strlen(req_table[req]));
   5.304 +    if (/* hvm */ 0) {
   5.305 +        unsigned long acpi_s_state = 0;
   5.306 +        unsigned long pvdriver = 0;
   5.307 +        xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, &acpi_s_state);
   5.308 +        xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, &pvdriver);
   5.309 +        if (!pvdriver && acpi_s_state != 0)
   5.310 +            xc_domain_shutdown(ctx->xch, domid, req);
   5.311 +    }
   5.312 +    return 0;
   5.313 +}
   5.314 +
   5.315 +static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid)
   5.316 +{
   5.317 +    char *pid;
   5.318 +    int ret;
   5.319 +
   5.320 +    pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "/local/domain/%d/image/device-model-pid", domid));
   5.321 +    if (!pid) {
   5.322 +        XL_LOG(ctx, XL_LOG_ERROR, "Couldn't find device model's pid\n");
   5.323 +        return -1;
   5.324 +    }
   5.325 +    xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "/local/domain/0/device-model/%d", domid));
   5.326 +
   5.327 +    ret = kill(atoi(pid), SIGHUP);
   5.328 +    if (ret < 0 && errno == ESRCH) {
   5.329 +        XL_LOG(ctx, XL_LOG_DEBUG, "Device Model already exited\n");
   5.330 +        ret = 0;
   5.331 +    } else if (ret == 0) {
   5.332 +        XL_LOG(ctx, XL_LOG_DEBUG, "Device Model signaled\n");
   5.333 +        ret = 0;
   5.334 +    } else {
   5.335 +        XL_LOG(ctx, XL_LOG_ERROR, "kill %d returned %d errno=%d\n", atoi(pid), ret, errno);
   5.336 +    }
   5.337 +    return ret;
   5.338 +}
   5.339 +
   5.340 +int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force)
   5.341 +{
   5.342 +    char *dom_path, vm_path[41];
   5.343 +    uint8_t *uuid;
   5.344 +
   5.345 +    dom_path = libxl_xs_get_dompath(ctx, domid);
   5.346 +    if (!dom_path) {
   5.347 +        XL_LOG(ctx, XL_LOG_ERROR, "dompath doesn't exist for %d\n", domid);
   5.348 +        return -1;
   5.349 +    }
   5.350 +    if (libxl_domid_to_uuid(ctx, &uuid, domid) < 0) {
   5.351 +        XL_LOG(ctx, XL_LOG_ERROR, "failed ot get uuid for %d\n", domid);
   5.352 +        return -1;
   5.353 +    }
   5.354 +    xs_write(ctx->xsh, XBT_NULL,
   5.355 +             libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid),
   5.356 +             "shutdown", strlen("shutdown"));
   5.357 +    if (xc_domain_pause(ctx->xch, domid) < 0) {
   5.358 +        XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_pause failed for %d\n", domid);
   5.359 +        return -1;
   5.360 +    }
   5.361 +    /* do_FLR */
   5.362 +    if (xc_domain_destroy(ctx->xch, domid) < 0) {
   5.363 +        XL_LOG(ctx, XL_LOG_ERROR, "xc_domain_destroy failed for %d\n", domid);
   5.364 +        return -1;
   5.365 +    }
   5.366 +    if (libxl_devices_destroy(ctx, domid, force) < 0)
   5.367 +        XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d\n", domid);
   5.368 +    if (libxl_destroy_device_model(ctx, domid) < 0)
   5.369 +        XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d\n", domid);
   5.370 +    if (!xs_rm(ctx->xsh, XBT_NULL, dom_path))
   5.371 +        XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", dom_path);
   5.372 +    snprintf(vm_path, sizeof(vm_path), "/vm/%s", uuid_to_string(ctx, uuid));
   5.373 +    if (!xs_rm(ctx->xsh, XBT_NULL, vm_path))
   5.374 +        XL_LOG(ctx, XL_LOG_ERROR, "xs_rm failed for %s\n", vm_path);
   5.375 +    return 0;
   5.376 +}
   5.377 +
   5.378 +static char ** libxl_build_device_model_args(struct libxl_ctx *ctx,
   5.379 +                                             libxl_device_model_info *info,
   5.380 +                                             libxl_device_nic *vifs,
   5.381 +                                             int num_vifs)
   5.382 +{
   5.383 +    int num = 0, i;
   5.384 +    flexarray_t *dm_args;
   5.385 +    dm_args = flexarray_make(16, 1);
   5.386 +    if (!dm_args)
   5.387 +        return NULL;
   5.388 +
   5.389 +    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "qemu-dm"));
   5.390 +    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-d"));
   5.391 +
   5.392 +    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid));
   5.393 +
   5.394 +    if (info->dom_name) {
   5.395 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-domain-name"));
   5.396 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->dom_name));
   5.397 +    }
   5.398 +    if (info->videoram) {
   5.399 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-videoram"));
   5.400 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->videoram));
   5.401 +    }
   5.402 +    if (info->stdvga) {
   5.403 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-std-vga"));
   5.404 +    }
   5.405 +    if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) {
   5.406 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vnc"));
   5.407 +        if (info->vncdisplay) {
   5.408 +            if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
   5.409 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:%d", info->vnclisten, info->vncdisplay));
   5.410 +            } else {
   5.411 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:%d", info->vncdisplay));
   5.412 +            }
   5.413 +        } else if (info->vnclisten) {
   5.414 +            if (strchr(info->vnclisten, ':') != NULL) {
   5.415 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->vnclisten));
   5.416 +            } else {
   5.417 +                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", info->vnclisten));
   5.418 +            }
   5.419 +        } else {
   5.420 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "127.0.0.1:0"));
   5.421 +        }
   5.422 +        if (info->vncunused) {
   5.423 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-vncunused"));
   5.424 +        }
   5.425 +    }
   5.426 +    if (info->sdl || info->opengl) {
   5.427 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-sdl"));
   5.428 +        if (info->opengl) {
   5.429 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-disable-opengl"));
   5.430 +        }
   5.431 +    }
   5.432 +    if (info->keymap) {
   5.433 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-k"));
   5.434 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->keymap));
   5.435 +    }
   5.436 +    if (info->nographic && (!info->sdl && !info->vnc)) {
   5.437 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-nographic"));
   5.438 +    }
   5.439 +    if (info->serial) {
   5.440 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-serial"));
   5.441 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->serial));
   5.442 +    }
   5.443 +    if (info->boot) {
   5.444 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-boot"));
   5.445 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->boot));
   5.446 +    }
   5.447 +    if (info->usb) {
   5.448 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usb"));
   5.449 +        if (info->usbdevice) {
   5.450 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-usbdevice"));
   5.451 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->usbdevice));
   5.452 +        }
   5.453 +    }
   5.454 +    if (info->apic) {
   5.455 +        flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-acpi"));
   5.456 +    }
   5.457 +    if (info->extra) {
   5.458 +        int i = 0;
   5.459 +        while (info->extra[i] != NULL) {
   5.460 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s", info->extra[i]));
   5.461 +        }
   5.462 +    }
   5.463 +    for (i = 0; i < num_vifs; i++) {
   5.464 +        if (vifs[i].nictype == NICTYPE_IOEMU) {
   5.465 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
   5.466 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s",
   5.467 +                                                        vifs[i].devid, vifs[i].smac, vifs[i].model));
   5.468 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-net"));
   5.469 +            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s",
   5.470 +                                                        vifs[i].devid, vifs[i].ifname, vifs[i].bridge));
   5.471 +        }
   5.472 +    }
   5.473 +    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-M"));
   5.474 +    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "xenfv"));
   5.475 +    flexarray_set(dm_args, num++, NULL);
   5.476 +
   5.477 +    return (char **) flexarray_contents(dm_args);
   5.478 +}
   5.479 +
   5.480 +int libxl_create_device_model(struct libxl_ctx *ctx,
   5.481 +                              libxl_device_model_info *info,
   5.482 +                              libxl_device_nic *vifs, int num_vifs)
   5.483 +{
   5.484 +    char *dom_path, *path, *logfile, *logfile_new;
   5.485 +    char *kvs[3];
   5.486 +    struct stat stat_buf;
   5.487 +    int logfile_w, null, pid;
   5.488 +    int i;
   5.489 +    char **args;
   5.490 +
   5.491 +    args = libxl_build_device_model_args(ctx, info, vifs, num_vifs);
   5.492 +    if (!args)
   5.493 +        return ERROR_FAIL;
   5.494 +
   5.495 +    dom_path = libxl_xs_get_dompath(ctx, info->domid);
   5.496 +
   5.497 +    path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid);
   5.498 +    xs_mkdir(ctx->xsh, XBT_NULL, path);
   5.499 +
   5.500 +    logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name);
   5.501 +    if (stat(logfile, &stat_buf) == 0) {
   5.502 +        /* file exists, rotate */
   5.503 +        logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.10", info->dom_name);
   5.504 +        unlink(logfile);
   5.505 +        for (i = 9; i > 0; i--) {
   5.506 +            logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i);
   5.507 +            logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.%d", info->dom_name, i + 1);
   5.508 +            rename(logfile, logfile_new);
   5.509 +        }
   5.510 +        logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name);
   5.511 +        logfile_new = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log.1", info->dom_name);
   5.512 +        rename(logfile, logfile_new);
   5.513 +    }
   5.514 +    logfile = libxl_sprintf(ctx, "/var/log/xen/qemu-dm-%s.log", info->dom_name);
   5.515 +    logfile_w = open(logfile, O_WRONLY|O_CREAT);
   5.516 +    null = open("/dev/null", O_RDONLY);
   5.517 +    pid = libxl_exec(ctx, null, logfile_w, logfile_w, info->device_model, args);
   5.518 +    close(null);
   5.519 +    close(logfile_w);
   5.520 +
   5.521 +    kvs[0] = libxl_sprintf(ctx, "image/device-model-pid");
   5.522 +    kvs[1] = libxl_sprintf(ctx, "%d", pid);
   5.523 +    kvs[2] = NULL;
   5.524 +    libxl_xs_writev(ctx, XBT_NULL, dom_path, kvs);
   5.525 +
   5.526 +    return 0;
   5.527 +}
   5.528 +
   5.529 +/******************************************************************************/
   5.530 +int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk)
   5.531 +{
   5.532 +    flexarray_t *front;
   5.533 +    flexarray_t *back;
   5.534 +    char *backend_type;
   5.535 +    unsigned int boffset = 0;
   5.536 +    unsigned int foffset = 0;
   5.537 +    int devid;
   5.538 +    libxl_device device;
   5.539 +
   5.540 +    front = flexarray_make(16, 1);
   5.541 +    if (!front)
   5.542 +        return ERROR_NOMEM;
   5.543 +    back = flexarray_make(16, 1);
   5.544 +    if (!back) /* leaks front if error */
   5.545 +        return ERROR_NOMEM;
   5.546 +
   5.547 +    backend_type = device_disk_backend_type_of_phystype(disk->phystype);
   5.548 +    devid = device_disk_dev_number(disk->virtpath);
   5.549 +
   5.550 +    device.backend_devid = devid;
   5.551 +    device.backend_domid = disk->backend_domid;
   5.552 +    device.devid = devid;
   5.553 +    device.domid = disk->domid;
   5.554 +    device.kind = DEVICE_VBD;
   5.555 +
   5.556 +    switch (disk->phystype) {
   5.557 +        case PHYSTYPE_FILE:
   5.558 +            return ERROR_NI; /* FIXME */
   5.559 +            break;
   5.560 +        case PHYSTYPE_PHY: {
   5.561 +            int major, minor;
   5.562 +
   5.563 +            device_disk_major_minor(disk->virtpath, &major, &minor);
   5.564 +            flexarray_set(back, boffset++, libxl_sprintf(ctx, "physical-device"));
   5.565 +            flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, minor));
   5.566 +
   5.567 +            flexarray_set(back, boffset++, libxl_sprintf(ctx, "params"));
   5.568 +            flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->physpath));
   5.569 +
   5.570 +            device.backend_kind = DEVICE_VBD;
   5.571 +            break;
   5.572 +        }
   5.573 +        case PHYSTYPE_AIO: case PHYSTYPE_QCOW: case PHYSTYPE_QCOW2: case PHYSTYPE_VHD:
   5.574 +            flexarray_set(back, boffset++, libxl_sprintf(ctx, "params"));
   5.575 +            flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s",
   5.576 +                          device_disk_string_of_phystype(disk->phystype), disk->physpath));
   5.577 +
   5.578 +            device.backend_kind = DEVICE_TAP;
   5.579 +            break;
   5.580 +    }
   5.581 +
   5.582 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
   5.583 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid));
   5.584 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
   5.585 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
   5.586 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "removable"));
   5.587 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", (disk->unpluggable) ? 1 : 0));
   5.588 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
   5.589 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
   5.590 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev"));
   5.591 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", disk->virtpath));
   5.592 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "type"));
   5.593 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", backend_type));
   5.594 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "mode"));
   5.595 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", (disk->readwrite) ? "w" : "r"));
   5.596 +
   5.597 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
   5.598 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", disk->backend_domid));
   5.599 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
   5.600 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
   5.601 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "virtual-device"));
   5.602 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid));
   5.603 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "device-type"));
   5.604 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%s", (disk->is_cdrom) ? "cdrom" : "disk"));
   5.605 +
   5.606 +    if (0 /* protocol != native*/) {
   5.607 +        flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol"));
   5.608 +        flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */
   5.609 +    }
   5.610 +
   5.611 +    libxl_device_generic_add(ctx, &device,
   5.612 +                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
   5.613 +                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
   5.614 +    /* leaks both flexarray here */
   5.615 +    return 0;
   5.616 +}
   5.617 +
   5.618 +int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.619 +{
   5.620 +    return ERROR_NI;
   5.621 +}
   5.622 +
   5.623 +int libxl_device_disk_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.624 +{
   5.625 +    return ERROR_NI;
   5.626 +}
   5.627 +
   5.628 +/******************************************************************************/
   5.629 +int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
   5.630 +{
   5.631 +    flexarray_t *front;
   5.632 +    flexarray_t *back;
   5.633 +    unsigned int boffset = 0;
   5.634 +    unsigned int foffset = 0;
   5.635 +    libxl_device device;
   5.636 +
   5.637 +    front = flexarray_make(16, 1);
   5.638 +    if (!front)
   5.639 +        return ERROR_NOMEM;
   5.640 +    back = flexarray_make(16, 1);
   5.641 +    if (!back)
   5.642 +        return ERROR_NOMEM;
   5.643 +
   5.644 +    device.backend_devid = nic->devid;
   5.645 +    device.backend_domid = nic->backend_domid;
   5.646 +    device.backend_kind = DEVICE_VIF;
   5.647 +    device.devid = nic->devid;
   5.648 +    device.domid = nic->domid;
   5.649 +    device.kind = DEVICE_VIF;
   5.650 +
   5.651 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "frontend-id"));
   5.652 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid));
   5.653 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "online"));
   5.654 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "1"));
   5.655 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "state"));
   5.656 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
   5.657 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "script"));
   5.658 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s", nic->script));
   5.659 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "mac"));
   5.660 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x",
   5.661 +                                                 nic->mac[0], nic->mac[1], nic->mac[2],
   5.662 +                                                 nic->mac[3], nic->mac[4], nic->mac[5]));
   5.663 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "handle"));
   5.664 +    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid));
   5.665 +
   5.666 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "backend-id"));
   5.667 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->backend_domid));
   5.668 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "state"));
   5.669 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
   5.670 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "handle"));
   5.671 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid));
   5.672 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "mac"));
   5.673 +    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x",
   5.674 +                                                  nic->mac[0], nic->mac[1], nic->mac[2],
   5.675 +                                                  nic->mac[3], nic->mac[4], nic->mac[5]));
   5.676 +    if (0 /* protocol != native*/) {
   5.677 +        flexarray_set(front, foffset++, libxl_sprintf(ctx, "protocol"));
   5.678 +        flexarray_set(front, foffset++, libxl_sprintf(ctx, "x86_32-abi")); /* hardcoded ! */
   5.679 +    }
   5.680 +
   5.681 +    libxl_device_generic_add(ctx, &device,
   5.682 +                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
   5.683 +                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
   5.684 +
   5.685 +    /* FIXME: wait for plug */
   5.686 +    return 0;
   5.687 +}
   5.688 +
   5.689 +int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.690 +{
   5.691 +    return ERROR_NI;
   5.692 +}
   5.693 +
   5.694 +int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.695 +{
   5.696 +    return ERROR_NI;
   5.697 +}
   5.698 +
   5.699 +/******************************************************************************/
   5.700 +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid)
   5.701 +{
   5.702 +    return ERROR_NI;
   5.703 +}
   5.704 +
   5.705 +int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.706 +{
   5.707 +    return ERROR_NI;
   5.708 +}
   5.709 +
   5.710 +int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.711 +{
   5.712 +    return ERROR_NI;
   5.713 +}
   5.714 +
   5.715 +/******************************************************************************/
   5.716 +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid)
   5.717 +{
   5.718 +    return ERROR_NI;
   5.719 +}
   5.720 +
   5.721 +int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.722 +{
   5.723 +    return ERROR_NI;
   5.724 +}
   5.725 +
   5.726 +int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.727 +{
   5.728 +    return ERROR_NI;
   5.729 +}
   5.730 +
   5.731 +/******************************************************************************/
   5.732 +int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid)
   5.733 +{
   5.734 +    return ERROR_NI;
   5.735 +}
   5.736 +
   5.737 +int libxl_device_pci_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.738 +{
   5.739 +    return ERROR_NI;
   5.740 +}
   5.741 +
   5.742 +int libxl_device_pci_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid)
   5.743 +{
   5.744 +    return ERROR_NI;
   5.745 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/libxl/libxl.h	Mon Nov 09 19:54:28 2009 +0000
     6.3 @@ -0,0 +1,200 @@
     6.4 +/*
     6.5 + * Copyright (C) 2009      Citrix Ltd.
     6.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     6.7 + *
     6.8 + * This program is free software; you can redistribute it and/or modify
     6.9 + * it under the terms of the GNU Lesser General Public License as published
    6.10 + * by the Free Software Foundation; version 2.1 only. with the special
    6.11 + * exception on linking described in file LICENSE.
    6.12 + *
    6.13 + * This program is distributed in the hope that it will be useful,
    6.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 + * GNU Lesser General Public License for more details.
    6.17 + */
    6.18 +#ifndef LIBXL_H
    6.19 +#define LIBXL_H
    6.20 +
    6.21 +#include "osdeps.h"
    6.22 +#include <stdint.h>
    6.23 +#include <stdarg.h>
    6.24 +#include <netinet/in.h>
    6.25 +#include <xenctrl.h>
    6.26 +
    6.27 +typedef int bool;
    6.28 +
    6.29 +typedef void (*libxl_log_callback)(void *userdata, int loglevel, const char *file,
    6.30 +                                   int line, const char *func, char *s);
    6.31 +
    6.32 +struct libxl_dominfo {
    6.33 +    uint8_t uuid[16];
    6.34 +    uint32_t domid;
    6.35 +};
    6.36 +
    6.37 +struct libxl_ctx {
    6.38 +    int xch;
    6.39 +    struct xs_handle *xsh;
    6.40 +    /* errors/debug buf */
    6.41 +    void *log_userdata;
    6.42 +    libxl_log_callback log_callback;
    6.43 +
    6.44 +    /* mini-GC */
    6.45 +    int alloc_maxsize;
    6.46 +    void **alloc_ptrs;
    6.47 +};
    6.48 +
    6.49 +typedef struct {
    6.50 +    bool hvm;
    6.51 +    bool hap;
    6.52 +    int ssidref;
    6.53 +    char *name;
    6.54 +    uint8_t *uuid;
    6.55 +    char **xsdata;
    6.56 +    char **platformdata;
    6.57 +} libxl_domain_create_info;
    6.58 +
    6.59 +typedef struct {
    6.60 +    int timer_mode;
    6.61 +    int hpet;
    6.62 +    int vpt_align;
    6.63 +    int max_vcpus;
    6.64 +    uint32_t max_memkb;
    6.65 +    uint32_t video_memkb;
    6.66 +    uint32_t shadow_memkb;
    6.67 +    const char *kernel;
    6.68 +    int hvm;
    6.69 +    union {
    6.70 +        struct {
    6.71 +            bool pae;
    6.72 +            bool apic;
    6.73 +            bool acpi;
    6.74 +            bool nx;
    6.75 +            bool viridian;
    6.76 +            char *timeoffset;
    6.77 +        } hvm;
    6.78 +        struct {
    6.79 +            const char *cmdline;
    6.80 +            const char *ramdisk;
    6.81 +        } pv;
    6.82 +    } u;
    6.83 +} libxl_domain_build_info;
    6.84 +
    6.85 +typedef struct {
    6.86 +    int flags;
    6.87 +    int (*suspend_callback)(void *, int);
    6.88 +} libxl_domain_suspend_info;
    6.89 +
    6.90 +typedef struct {
    6.91 +    int domid;
    6.92 +    char *dom_name;
    6.93 +    char *device_model;
    6.94 +    int videoram; /* size of the videoram in MB */
    6.95 +    bool stdvga; /* stdvga enabled or disabled */
    6.96 +    bool vnc; /* vnc enabled or disabled */
    6.97 +    char *vnclisten; /* address:port that should be listened on for the VNC server if vnc is set */
    6.98 +    int vncdisplay; /* set VNC display number */
    6.99 +    bool vncunused; /* try to find an unused port for the VNC server */
   6.100 +    char *keymap; /* set keyboard layout, default is en-us keyboard */
   6.101 +    bool sdl; /* sdl enabled or disabled */
   6.102 +    bool opengl; /* opengl enabled or disabled (if enabled requires sdl enabled) */
   6.103 +    bool nographic; /* no graphics, use serial port */
   6.104 +    char *serial; /* serial port re-direct to pty deivce */
   6.105 +    char *boot; /* boot order, for example dca */
   6.106 +    bool usb; /* usb support enabled or disabled */
   6.107 +    char *usbdevice; /* enable usb mouse: tablet for absolute mouse, mouse for PS/2 protocol relative mouse */
   6.108 +    bool apic; /* apic enabled or disabled */
   6.109 +    char **extra; /* extra parameters pass directly to qemu, NULL terminated */
   6.110 +    /* Network is missing */
   6.111 +} libxl_device_model_info;
   6.112 +
   6.113 +typedef enum {
   6.114 +    PHYSTYPE_QCOW,
   6.115 +    PHYSTYPE_QCOW2,
   6.116 +    PHYSTYPE_VHD,
   6.117 +    PHYSTYPE_AIO,
   6.118 +    PHYSTYPE_FILE,
   6.119 +    PHYSTYPE_PHY,
   6.120 +} libxl_disk_phystype;
   6.121 +
   6.122 +typedef struct {
   6.123 +    uint32_t backend_domid;
   6.124 +    uint32_t domid;
   6.125 +    char *physpath;
   6.126 +    libxl_disk_phystype phystype;
   6.127 +    char *virtpath;
   6.128 +    int unpluggable;
   6.129 +    int readwrite;
   6.130 +    int is_cdrom;
   6.131 +} libxl_device_disk;
   6.132 +
   6.133 +typedef enum {
   6.134 +    NICTYPE_IOEMU,
   6.135 +    NICTYPE_VIF,
   6.136 +} libxl_nic_type;
   6.137 +
   6.138 +typedef struct {
   6.139 +    uint32_t backend_domid;
   6.140 +    uint32_t domid;
   6.141 +    int devid;
   6.142 +    int mtu;
   6.143 +    char *model;
   6.144 +    uint8_t mac[6];
   6.145 +    char *smac;
   6.146 +    struct in_addr ip;
   6.147 +    char *bridge;
   6.148 +    char *ifname;
   6.149 +    char *script;
   6.150 +    libxl_nic_type nictype;
   6.151 +} libxl_device_nic;
   6.152 +
   6.153 +#define ERROR_FAIL (-2)
   6.154 +#define ERROR_NI (-101)
   6.155 +#define ERROR_NOMEM (-1032)
   6.156 +#define ERROR_INVAL (-1245)
   6.157 +
   6.158 +/* context functions */
   6.159 +int libxl_ctx_init(struct libxl_ctx *ctx);
   6.160 +int libxl_ctx_free(struct libxl_ctx *ctx);
   6.161 +int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data);
   6.162 +
   6.163 +/* domain related functions */
   6.164 +int libxl_domain_make(struct libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid);
   6.165 +int libxl_domain_build(struct libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid);
   6.166 +int libxl_domain_restore(struct libxl_ctx *ctx, libxl_domain_build_info *info,
   6.167 +                          uint32_t domid, int fd);
   6.168 +int libxl_domain_suspend(struct libxl_ctx *ctx, libxl_domain_suspend_info *info,
   6.169 +                          uint32_t domid, int fd);
   6.170 +int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req);
   6.171 +int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force);
   6.172 +
   6.173 +int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid);
   6.174 +int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid);
   6.175 +
   6.176 +struct libxl_dominfo * libxl_domain_list(struct libxl_ctx *ctx, int *nb_domain);
   6.177 +xc_dominfo_t * libxl_domain_infolist(struct libxl_ctx *ctx, int *nb_domain);
   6.178 +
   6.179 +int libxl_create_device_model(struct libxl_ctx *ctx,
   6.180 +                              libxl_device_model_info *info,
   6.181 +                              libxl_device_nic *vifs, int num_vifs);
   6.182 +
   6.183 +int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk);
   6.184 +int libxl_device_disk_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.185 +int libxl_device_disk_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.186 +
   6.187 +int libxl_device_nic_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic);
   6.188 +int libxl_device_nic_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.189 +int libxl_device_nic_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.190 +
   6.191 +int libxl_device_vkb_add(struct libxl_ctx *ctx, uint32_t domid);
   6.192 +int libxl_device_vkb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.193 +int libxl_device_vkb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.194 +
   6.195 +int libxl_device_vfb_add(struct libxl_ctx *ctx, uint32_t domid);
   6.196 +int libxl_device_vfb_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.197 +int libxl_device_vfb_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.198 +
   6.199 +int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid);
   6.200 +int libxl_device_pci_clean_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.201 +int libxl_device_pci_hard_shutdown(struct libxl_ctx *ctx, uint32_t domid);
   6.202 +
   6.203 +#endif
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/libxl/libxl_device.c	Mon Nov 09 19:54:28 2009 +0000
     7.3 @@ -0,0 +1,241 @@
     7.4 +/*
     7.5 + * Copyright (C) 2009      Citrix Ltd.
     7.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     7.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
     7.8 + *
     7.9 + * This program is free software; you can redistribute it and/or modify
    7.10 + * it under the terms of the GNU Lesser General Public License as published
    7.11 + * by the Free Software Foundation; version 2.1 only. with the special
    7.12 + * exception on linking described in file LICENSE.
    7.13 + *
    7.14 + * This program is distributed in the hope that it will be useful,
    7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 + * GNU Lesser General Public License for more details.
    7.18 + */
    7.19 +
    7.20 +#include <string.h>
    7.21 +#include "libxl.h"
    7.22 +#include "libxl_internal.h"
    7.23 +
    7.24 +char *string_of_kinds[] = {
    7.25 +    [DEVICE_VIF] = "vif",
    7.26 +    [DEVICE_VBD] = "vbd",
    7.27 +    [DEVICE_TAP] = "tap",
    7.28 +    [DEVICE_PCI] = "pci",
    7.29 +    [DEVICE_VFB] = "vfb",
    7.30 +    [DEVICE_VKBD] = "vkbd",
    7.31 +};
    7.32 +
    7.33 +int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,
    7.34 +                             char **bents, char **fents)
    7.35 +{
    7.36 +    char *dom_path_backend, *dom_path, *frontend_path, *backend_path, *hotplug_path;
    7.37 +    xs_transaction_t t;
    7.38 +    struct xs_permissions frontend_perms[2];
    7.39 +    struct xs_permissions backend_perms[2];
    7.40 +    struct xs_permissions hotplug_perms[1];
    7.41 +
    7.42 +    dom_path_backend = xs_get_domain_path(ctx->xsh, device->backend_domid);
    7.43 +    dom_path = xs_get_domain_path(ctx->xsh, device->domid);
    7.44 +
    7.45 +    frontend_path = libxl_sprintf(ctx, "%s/device/%s/%d",
    7.46 +                                  dom_path, string_of_kinds[device->kind], device->devid);
    7.47 +    backend_path = libxl_sprintf(ctx, "%s/backend/%s/%u/%d",
    7.48 +                                 dom_path_backend, string_of_kinds[device->backend_kind], device->domid, device->devid);
    7.49 +    hotplug_path = libxl_sprintf(ctx, "/xapi/%d/hotplug/%s/%d",
    7.50 +                                  device->domid, string_of_kinds[device->kind], device->devid);
    7.51 +
    7.52 +    frontend_perms[0].id = device->domid;
    7.53 +    frontend_perms[0].perms = XS_PERM_NONE;
    7.54 +    frontend_perms[1].id = device->backend_domid;
    7.55 +    frontend_perms[1].perms = XS_PERM_READ;
    7.56 +
    7.57 +    backend_perms[0].id = device->backend_domid;
    7.58 +    backend_perms[0].perms = XS_PERM_NONE;
    7.59 +    backend_perms[1].id = device->domid;
    7.60 +    backend_perms[1].perms = XS_PERM_READ;
    7.61 +
    7.62 +    hotplug_perms[0].id = device->backend_domid;
    7.63 +    hotplug_perms[0].perms = XS_PERM_NONE;
    7.64 +
    7.65 +retry_transaction:
    7.66 +    t = xs_transaction_start(ctx->xsh);
    7.67 +    /* FIXME: read frontend_path and check state before removing stuff */
    7.68 +
    7.69 +    xs_rm(ctx->xsh, t, frontend_path);
    7.70 +    xs_rm(ctx->xsh, t, backend_path);
    7.71 +
    7.72 +    xs_mkdir(ctx->xsh, t, frontend_path);
    7.73 +    xs_set_permissions(ctx->xsh, t, frontend_path, frontend_perms, ARRAY_SIZE(frontend_perms));
    7.74 +
    7.75 +    xs_mkdir(ctx->xsh, t, backend_path);
    7.76 +    xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, ARRAY_SIZE(backend_perms));
    7.77 +
    7.78 +    xs_mkdir(ctx->xsh, t, hotplug_path);
    7.79 +    xs_set_permissions(ctx->xsh, t, hotplug_path, hotplug_perms, ARRAY_SIZE(hotplug_perms));
    7.80 +
    7.81 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/backend", frontend_path), backend_path, strlen(backend_path));
    7.82 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/frontend", backend_path), frontend_path, strlen(frontend_path));
    7.83 +
    7.84 +    /* and write frontend kvs and backend kvs */
    7.85 +    libxl_xs_writev(ctx, t, backend_path, bents);
    7.86 +    libxl_xs_writev(ctx, t, frontend_path, fents);
    7.87 +
    7.88 +    if (!xs_transaction_end(ctx->xsh, t, 0))
    7.89 +        if (errno == EAGAIN)
    7.90 +            goto retry_transaction;
    7.91 +    return 0;
    7.92 +}
    7.93 +
    7.94 +char *device_disk_string_of_phystype(libxl_disk_phystype phystype)
    7.95 +{
    7.96 +    switch (phystype) {
    7.97 +        case PHYSTYPE_QCOW: return "qcow";
    7.98 +        case PHYSTYPE_QCOW2: return "qcow2";
    7.99 +        case PHYSTYPE_VHD: return "vhd";
   7.100 +        case PHYSTYPE_AIO: return "aio";
   7.101 +        case PHYSTYPE_FILE: return "file";
   7.102 +        case PHYSTYPE_PHY: return "phy";
   7.103 +        default: return NULL;
   7.104 +    }
   7.105 +}
   7.106 +
   7.107 +char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype)
   7.108 +{
   7.109 +    switch (phystype) {
   7.110 +        case PHYSTYPE_QCOW: return "tap";
   7.111 +        case PHYSTYPE_VHD: return "tap";
   7.112 +        case PHYSTYPE_AIO: return "tap";
   7.113 +        case PHYSTYPE_FILE: return "file";
   7.114 +        case PHYSTYPE_PHY: return "phy";
   7.115 +        default: return NULL;
   7.116 +    }
   7.117 +}
   7.118 +
   7.119 +int device_disk_major_minor(char *virtpath, int *major, int *minor)
   7.120 +{
   7.121 +    if (strstr(virtpath, "sd") == virtpath) {
   7.122 +        return -1;
   7.123 +    } else if (strstr(virtpath, "xvd") == virtpath) {
   7.124 +        return -1;
   7.125 +    } else if (strstr(virtpath, "hd") == virtpath) {
   7.126 +        char letter, letter2;
   7.127 +
   7.128 +        *major = 0; *minor = 0;
   7.129 +        letter = virtpath[2];
   7.130 +        if (letter < 'a' || letter > 't')
   7.131 +            return -1;
   7.132 +        letter2 = virtpath[3];
   7.133 +
   7.134 +        *major = letter - 'a';
   7.135 +        *minor = atoi(virtpath + 3);
   7.136 +        return 0;
   7.137 +    } else {
   7.138 +        return -1;
   7.139 +    }
   7.140 +}
   7.141 +
   7.142 +int device_disk_dev_number(char *virtpath)
   7.143 +{
   7.144 +    int majors_table[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 };
   7.145 +    int major, minor;
   7.146 +
   7.147 +    if (device_disk_major_minor(virtpath, &major, &minor))
   7.148 +        return -1;
   7.149 +    return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor;
   7.150 +}
   7.151 +
   7.152 +int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force)
   7.153 +{
   7.154 +    xs_transaction_t t;
   7.155 +    char *state_path = libxl_sprintf(ctx, "%s/state", be_path);
   7.156 +    char *state = libxl_xs_read(ctx, XBT_NULL, state_path);
   7.157 +    if (!state)
   7.158 +        return 0;
   7.159 +    if (atoi(state) <= 3) {
   7.160 +        xs_rm(ctx->xsh, XBT_NULL, be_path);
   7.161 +        return 0;
   7.162 +    }
   7.163 +
   7.164 +retry_transaction:
   7.165 +    t = xs_transaction_start(ctx->xsh);
   7.166 +    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/online", be_path), "0", strlen("0"));
   7.167 +    xs_write(ctx->xsh, t, state_path, "5", strlen("5"));
   7.168 +    if (!xs_transaction_end(ctx->xsh, t, 0)) {
   7.169 +        if (errno == EAGAIN)
   7.170 +            goto retry_transaction;
   7.171 +        else
   7.172 +            return -1;
   7.173 +    }
   7.174 +    if (!force) {
   7.175 +        xs_watch(ctx->xsh, state_path, be_path);
   7.176 +        return 1;
   7.177 +    } else
   7.178 +        return 0;
   7.179 +}
   7.180 +
   7.181 +int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force)
   7.182 +{
   7.183 +    char *path, *be_path, *fe_path;
   7.184 +    unsigned int num1, num2;
   7.185 +    char **l1 = NULL, **l2 = NULL;
   7.186 +    int i, j, nfds, n = 0, n_watches = 0;
   7.187 +    fd_set rfds;
   7.188 +    struct timeval tv;
   7.189 +    flexarray_t *toremove;
   7.190 +
   7.191 +    toremove = flexarray_make(16, 1);
   7.192 +    path = libxl_sprintf(ctx, "/local/domain/%d/device", domid);
   7.193 +    l1 = libxl_xs_directory(ctx, XBT_NULL, path, &num1);
   7.194 +    if (!l1) {
   7.195 +        XL_LOG(ctx, XL_LOG_ERROR, "%s is empty\n", path);
   7.196 +        return -1;
   7.197 +    }
   7.198 +    for (i = 0; i < num1; i++) {
   7.199 +        path = libxl_sprintf(ctx, "/local/domain/%d/device/%s", domid, l1[i]);
   7.200 +        l2 = libxl_xs_directory(ctx, XBT_NULL, path, &num2);
   7.201 +        if (!l2)
   7.202 +            continue;
   7.203 +        for (j = 0; j < num2; j++) {
   7.204 +            fe_path = libxl_sprintf(ctx, "/local/domain/%d/device/%s/%s", domid, l1[i], l2[j]);
   7.205 +            be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", fe_path));
   7.206 +            if (be_path != NULL) {
   7.207 +                if (libxl_device_destroy(ctx, be_path, force) > 0)
   7.208 +                    n_watches++;
   7.209 +                flexarray_set(toremove, n++, libxl_dirname(ctx, be_path));
   7.210 +            } else {
   7.211 +                xs_rm(ctx->xsh, XBT_NULL, path);
   7.212 +            }
   7.213 +        }
   7.214 +    }
   7.215 +    if (!force) {
   7.216 +        nfds = xs_fileno(ctx->xsh) + 1;
   7.217 +        /* Linux-ism */
   7.218 +        tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
   7.219 +        tv.tv_usec = 0;
   7.220 +        while (n_watches > 0 && tv.tv_sec > 0) {
   7.221 +            FD_ZERO(&rfds);
   7.222 +            FD_SET(xs_fileno(ctx->xsh), &rfds);
   7.223 +            if (select(nfds, &rfds, NULL, NULL, &tv) > 0) {
   7.224 +                l1 = xs_read_watch(ctx->xsh, &num1);
   7.225 +                if (l1 != NULL) {
   7.226 +                    char *state = libxl_xs_read(ctx, XBT_NULL, l1[0]);
   7.227 +                    if (!state || atoi(state) == 6) {
   7.228 +                        xs_unwatch(ctx->xsh, l1[0], l1[1]);
   7.229 +                        xs_rm(ctx->xsh, XBT_NULL, l1[1]);
   7.230 +                        XL_LOG(ctx, XL_LOG_DEBUG, "Destroyed device backend at %s\n", l1[1]);
   7.231 +                        n_watches--;
   7.232 +                    }
   7.233 +                }
   7.234 +            } else
   7.235 +                break;
   7.236 +        }
   7.237 +    }
   7.238 +    for (i = 0; i < n; i++) {
   7.239 +        flexarray_get(toremove, i, (void**) &path);
   7.240 +        xs_rm(ctx->xsh, XBT_NULL, path);
   7.241 +    }
   7.242 +    flexarray_free(toremove);
   7.243 +    return 0;
   7.244 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/libxl/libxl_dom.c	Mon Nov 09 19:54:28 2009 +0000
     8.3 @@ -0,0 +1,271 @@
     8.4 +/*
     8.5 + * Copyright (C) 2009      Citrix Ltd.
     8.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     8.7 + *
     8.8 + * This program is free software; you can redistribute it and/or modify
     8.9 + * it under the terms of the GNU Lesser General Public License as published
    8.10 + * by the Free Software Foundation; version 2.1 only. with the special
    8.11 + * exception on linking described in file LICENSE.
    8.12 + *
    8.13 + * This program is distributed in the hope that it will be useful,
    8.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.16 + * GNU Lesser General Public License for more details.
    8.17 + */
    8.18 +
    8.19 +#include "libxl.h"
    8.20 +#include "libxl_internal.h"
    8.21 +#include <inttypes.h>
    8.22 +#include <xenguest.h>
    8.23 +#include <string.h>
    8.24 +
    8.25 +int is_hvm(struct libxl_ctx *ctx, uint32_t domid)
    8.26 +{
    8.27 +    xc_domaininfo_t info;
    8.28 +    int ret;
    8.29 +
    8.30 +    ret = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
    8.31 +    if (ret != 1)
    8.32 +        return -1;
    8.33 +    if (info.domain != domid)
    8.34 +        return -1;
    8.35 +    return !!(info.flags & XEN_DOMINF_hvm_guest);
    8.36 +}
    8.37 +
    8.38 +int build_pre(struct libxl_ctx *ctx, uint32_t domid,
    8.39 +              libxl_domain_build_info *info, libxl_domain_build_state *state)
    8.40 +{
    8.41 +    unsigned long shadow;
    8.42 +    if (info->timer_mode != -1)
    8.43 +        xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_TIMER_MODE,
    8.44 +                (unsigned long) info->timer_mode);
    8.45 +    if (info->hpet != -1)
    8.46 +        xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) info->hpet);
    8.47 +    if (info->vpt_align != -1)
    8.48 +        xc_set_hvm_param(ctx->xch, domid, HVM_PARAM_VPT_ALIGN, (unsigned long) info->vpt_align);
    8.49 +    xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus);
    8.50 +    xc_domain_setmaxmem(ctx->xch, domid, info->max_memkb + info->video_memkb);
    8.51 +    xc_domain_set_memmap_limit(ctx->xch, domid, info->max_memkb);
    8.52 +    shadow = (info->shadow_memkb + 1023) / 1024;
    8.53 +    xc_shadow_control(ctx->xch, domid, XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL);
    8.54 +
    8.55 +    state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0);
    8.56 +    state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 0);
    8.57 +    return 0;
    8.58 +}
    8.59 +
    8.60 +int build_post(struct libxl_ctx *ctx, uint32_t domid,
    8.61 +               libxl_domain_build_info *info, libxl_domain_build_state *state,
    8.62 +               char **vms_ents, char **local_ents)
    8.63 +{
    8.64 +    char *dom_path, *vm_path;
    8.65 +    xs_transaction_t t;
    8.66 +    char **ents;
    8.67 +
    8.68 +    ents = libxl_calloc(ctx, 6 * 2, sizeof(char *));
    8.69 +    ents[0] = libxl_sprintf(ctx, "memory/static-max");
    8.70 +    ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb);
    8.71 +    ents[2] = libxl_sprintf(ctx, "memory/target");
    8.72 +    ents[3] = libxl_sprintf(ctx, "%d", info->max_memkb); /* PROBABLY WRONG */
    8.73 +    ents[4] = libxl_sprintf(ctx, "domid");
    8.74 +    ents[5] = libxl_sprintf(ctx, "%d", domid);
    8.75 +    ents[6] = libxl_sprintf(ctx, "store/port");
    8.76 +    ents[7] = libxl_sprintf(ctx, "%"PRIu32, state->store_port);
    8.77 +    ents[8] = libxl_sprintf(ctx, "store/ring-ref");
    8.78 +    ents[9] = libxl_sprintf(ctx, "%lu", state->store_mfn);
    8.79 +
    8.80 +    dom_path = libxl_xs_get_dompath(ctx, domid);
    8.81 +    vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dom_path), NULL);
    8.82 +retry_transaction:
    8.83 +    t = xs_transaction_start(ctx->xsh);
    8.84 +
    8.85 +    libxl_xs_writev(ctx, t, dom_path, ents);
    8.86 +    libxl_xs_writev(ctx, t, dom_path, local_ents);
    8.87 +    libxl_xs_writev(ctx, t, vm_path, vms_ents);
    8.88 +
    8.89 +    if (!xs_transaction_end(ctx->xsh, t, 0))
    8.90 +        if (errno == EAGAIN)
    8.91 +            goto retry_transaction;
    8.92 +    xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port);
    8.93 +    return 0;
    8.94 +}
    8.95 +
    8.96 +int build_pv(struct libxl_ctx *ctx, uint32_t domid,
    8.97 +             libxl_domain_build_info *info, libxl_domain_build_state *state)
    8.98 +{
    8.99 +    int mem_target_kib = info->max_memkb;
   8.100 +    char *domid_str = libxl_sprintf(ctx, "%d", domid);
   8.101 +    char *memsize_str = libxl_sprintf(ctx, "%d", mem_target_kib / 1024);
   8.102 +    char *store_port_str = libxl_sprintf(ctx, "%d", state->store_port);
   8.103 +    char *console_port_str = libxl_sprintf(ctx, "%d", state->console_port);
   8.104 +    return ERROR_NI;
   8.105 +}
   8.106 +
   8.107 +int build_hvm(struct libxl_ctx *ctx, uint32_t domid,
   8.108 +              libxl_domain_build_info *info, libxl_domain_build_state *state)
   8.109 +{
   8.110 +    int ret;
   8.111 +
   8.112 +    ret = xc_hvm_build(ctx->xch, domid, info->max_memkb / 1024, info->kernel);
   8.113 +    if (ret) {
   8.114 +        XL_LOG(ctx, XL_LOG_ERROR, "hvm building failed: %d", ret);
   8.115 +        return ERROR_FAIL;
   8.116 +    }
   8.117 +    ret = hvm_build_set_params(ctx->xch, domid, info->u.hvm.apic, info->u.hvm.acpi,
   8.118 +                               info->u.hvm.pae, info->u.hvm.nx, info->u.hvm.viridian,
   8.119 +                               info->max_vcpus,
   8.120 +                               state->store_port, &state->store_mfn);
   8.121 +    if (ret) {
   8.122 +        XL_LOG(ctx, XL_LOG_ERROR, "hvm build set params failed: %d", ret);
   8.123 +        return ERROR_FAIL;
   8.124 +    }
   8.125 +    xc_cpuid_apply_policy(ctx->xch, domid);
   8.126 +    return 0;
   8.127 +}
   8.128 +
   8.129 +int restore_common(struct libxl_ctx *ctx, uint32_t domid,
   8.130 +                   libxl_domain_build_info *info, libxl_domain_build_state *state,
   8.131 +                   int fd)
   8.132 +{
   8.133 +    /* read signature */
   8.134 +    xc_domain_restore(ctx->xch, fd, domid,
   8.135 +                      state->store_port, &state->store_mfn,
   8.136 +                      state->console_port, &state->console_mfn,
   8.137 +                      info->hvm, info->u.hvm.pae, 0);
   8.138 +    return 0;
   8.139 +}
   8.140 +
   8.141 +/* the following code is extremely ugly and racy without forking.
   8.142 +   we intend to fix the re-entrancy of the underlying code instead of forking */
   8.143 +static struct libxl_ctx *global_suspend_ctx = NULL;
   8.144 +static struct suspendinfo {
   8.145 +    int xch;
   8.146 +    int xce; /* event channel handle */
   8.147 +    int suspend_eventchn;
   8.148 +    int domid;
   8.149 +    int hvm;
   8.150 +    unsigned int flags;
   8.151 +} si;
   8.152 +
   8.153 +void core_suspend_switch_qemu_logdirty(int domid, unsigned int enable)
   8.154 +{
   8.155 +    struct xs_handle *xs;
   8.156 +    char *path, *ret_path, *cmd_path, *ret_str, *cmd_str, **watch;
   8.157 +    unsigned int len;
   8.158 +    struct timeval tv;
   8.159 +    fd_set fdset;
   8.160 +    struct libxl_ctx *ctx = global_suspend_ctx;
   8.161 +
   8.162 +    xs = xs_daemon_open();
   8.163 +    if (!xs)
   8.164 +        return;
   8.165 +    path = libxl_sprintf(ctx, "/local/domain/0/device-model/%i/logdirty", domid);
   8.166 +    if (!path)
   8.167 +        return;
   8.168 +    ret_path = libxl_sprintf(ctx, "%s/ret", path);
   8.169 +    if (!ret_path)
   8.170 +        return;
   8.171 +    cmd_path = libxl_sprintf(ctx, "%s/cmd", path);
   8.172 +    if (!ret_path)
   8.173 +        return;
   8.174 +
   8.175 +    /* Watch for qemu's return value */
   8.176 +    if (!xs_watch(xs, ret_path, "qemu-logdirty-ret"))
   8.177 +        return;
   8.178 +
   8.179 +    cmd_str = (enable == 0) ? "disable" : "enable";
   8.180 +
   8.181 +    /* Tell qemu that we want it to start logging dirty page to Xen */
   8.182 +    if (!xs_write(xs, XBT_NULL, cmd_path, cmd_str, strlen(cmd_str)))
   8.183 +        return;
   8.184 +
   8.185 +    /* Wait a while for qemu to signal that it has service logdirty command */
   8.186 +read_again:
   8.187 +    tv.tv_sec = 5;
   8.188 +    tv.tv_usec = 0;
   8.189 +    FD_ZERO(&fdset);
   8.190 +    FD_SET(xs_fileno(xs), &fdset);
   8.191 +
   8.192 +    if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1)
   8.193 +        return;
   8.194 +
   8.195 +    watch = xs_read_watch(xs, &len);
   8.196 +    free(watch);
   8.197 +
   8.198 +    ret_str = xs_read(xs, XBT_NULL, ret_path, &len);
   8.199 +    if (ret_str == NULL || strcmp(ret_str, cmd_str))
   8.200 +        /* Watch fired but value is not yet right */
   8.201 +        goto read_again;
   8.202 +    free(ret_str);
   8.203 +}
   8.204 +
   8.205 +static int core_suspend_callback(void)
   8.206 +{
   8.207 +    unsigned long s_state = 0;
   8.208 +    int ret;
   8.209 +
   8.210 +    if (si.hvm)
   8.211 +        xc_get_hvm_param(si.xch, si.domid, HVM_PARAM_ACPI_S_STATE, &s_state);
   8.212 +    if ((s_state == 0) && (si.suspend_eventchn >= 0)) {
   8.213 +        ret = xc_evtchn_notify(si.xch, si.suspend_eventchn);
   8.214 +        if (ret < 0) {
   8.215 +            return 0;
   8.216 +        }
   8.217 +        ret = xc_await_suspend(si.xch, si.suspend_eventchn);
   8.218 +        if (ret < 0) {
   8.219 +            return 0;
   8.220 +        }
   8.221 +        return 1;
   8.222 +    }
   8.223 +    /* need to shutdown (to suspend) the domain here */
   8.224 +    return 0;
   8.225 +}
   8.226 +
   8.227 +int core_suspend(struct libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, int debug)
   8.228 +{
   8.229 +    int flags;
   8.230 +    int port;
   8.231 +
   8.232 +    flags = (live) ? XCFLAGS_LIVE : 0
   8.233 +          | (debug) ? XCFLAGS_DEBUG : 0;
   8.234 +
   8.235 +    /* crappy global lock until we make everything clean */
   8.236 +    while (global_suspend_ctx) {
   8.237 +        sleep(1);
   8.238 +    }
   8.239 +    global_suspend_ctx = ctx;
   8.240 +
   8.241 +    si.domid = domid;
   8.242 +    si.flags = flags;
   8.243 +    si.hvm = hvm;
   8.244 +    si.suspend_eventchn = si.xce = -1;
   8.245 +    si.xch = ctx->xch;
   8.246 +
   8.247 +    si.xce = xc_evtchn_open();
   8.248 +    if (si.xce < 0)
   8.249 +        return -1;
   8.250 +
   8.251 +    if (si.xce > 0) {
   8.252 +        port = xs_suspend_evtchn_port(si.domid);
   8.253 +
   8.254 +        if (port < 0) {
   8.255 +        } else {
   8.256 +            si.suspend_eventchn = xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port);
   8.257 +
   8.258 +            if (si.suspend_eventchn < 0) {
   8.259 +            }
   8.260 +        }
   8.261 +    }
   8.262 +
   8.263 +    xc_domain_save(ctx->xch, fd, domid, 0, 0, flags,
   8.264 +                   core_suspend_callback, hvm,
   8.265 +                   core_suspend_switch_qemu_logdirty);
   8.266 +
   8.267 +    if (si.suspend_eventchn > 0)
   8.268 +        xc_suspend_evtchn_release(si.xce, si.suspend_eventchn);
   8.269 +    if (si.xce > 0)
   8.270 +        xc_evtchn_close(si.xce);
   8.271 +
   8.272 +    global_suspend_ctx = NULL;
   8.273 +    return 0;
   8.274 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/libxl/libxl_exec.c	Mon Nov 09 19:54:28 2009 +0000
     9.3 @@ -0,0 +1,48 @@
     9.4 +
     9.5 +/*
     9.6 + * Copyright (C) 2009      Citrix Ltd.
     9.7 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     9.8 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
     9.9 + *
    9.10 + * This program is free software; you can redistribute it and/or modify
    9.11 + * it under the terms of the GNU Lesser General Public License as published
    9.12 + * by the Free Software Foundation; version 2.1 only. with the special
    9.13 + * exception on linking described in file LICENSE.
    9.14 + *
    9.15 + * This program is distributed in the hope that it will be useful,
    9.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9.18 + * GNU Lesser General Public License for more details.
    9.19 + */
    9.20 +
    9.21 +#include <stdio.h>
    9.22 +#include <unistd.h>
    9.23 +#include <stdlib.h>
    9.24 +#include "libxl.h"
    9.25 +#include "libxl_internal.h"
    9.26 +
    9.27 +int libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int stderrfd,
    9.28 +               char *arg0, char **args)
    9.29 +{
    9.30 +    int pid, i;
    9.31 +
    9.32 +    pid = fork();
    9.33 +    if (pid == -1) {
    9.34 +        XL_LOG(ctx, XL_LOG_ERROR, "fork failed");
    9.35 +        return -1;
    9.36 +    }
    9.37 +    if (pid == 0) {
    9.38 +        /* child */
    9.39 +        if (stdinfd != -1)
    9.40 +            dup2(stdinfd, STDIN_FILENO);
    9.41 +        if (stdoutfd != -1)
    9.42 +            dup2(stdoutfd, STDOUT_FILENO);
    9.43 +        if (stderrfd != -1)
    9.44 +            dup2(stderrfd, STDERR_FILENO);
    9.45 +        for (i = 4; i < 256; i++)
    9.46 +            close(i);
    9.47 +        execv(arg0, args);
    9.48 +        exit(256);
    9.49 +    }
    9.50 +    return pid;
    9.51 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/libxl/libxl_internal.c	Mon Nov 09 19:54:28 2009 +0000
    10.3 @@ -0,0 +1,159 @@
    10.4 +/*
    10.5 + * Copyright (C) 2009      Citrix Ltd.
    10.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
    10.7 + *
    10.8 + * This program is free software; you can redistribute it and/or modify
    10.9 + * it under the terms of the GNU Lesser General Public License as published
   10.10 + * by the Free Software Foundation; version 2.1 only. with the special
   10.11 + * exception on linking described in file LICENSE.
   10.12 + *
   10.13 + * This program is distributed in the hope that it will be useful,
   10.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10.16 + * GNU Lesser General Public License for more details.
   10.17 + */
   10.18 +#include "libxl.h"
   10.19 +#include "libxl_internal.h"
   10.20 +#include "libxl_utils.h"
   10.21 +#include <stdio.h>
   10.22 +#include <stdarg.h>
   10.23 +#include <string.h>
   10.24 +
   10.25 +int libxl_error_set(struct libxl_ctx *ctx, int code)
   10.26 +{
   10.27 +    return 0;
   10.28 +}
   10.29 +
   10.30 +int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr)
   10.31 +{
   10.32 +    int i;
   10.33 +    void **re;
   10.34 +
   10.35 +    if (!ptr)
   10.36 +        return 0;
   10.37 +
   10.38 +    /* fast case: we have space in the array for storing the pointer */
   10.39 +    for (i = 0; i < ctx->alloc_maxsize; i++) {
   10.40 +        if (!ctx->alloc_ptrs[i]) {
   10.41 +            ctx->alloc_ptrs[i] = ptr;
   10.42 +            return 0;
   10.43 +        }
   10.44 +    }
   10.45 +    /* realloc alloc_ptrs manually with calloc/free/replace */
   10.46 +    re = calloc(ctx->alloc_maxsize + 25, sizeof(void *));
   10.47 +    if (!re)
   10.48 +        return -1;
   10.49 +    for (i = 0; i < ctx->alloc_maxsize; i++)
   10.50 +        re[i] = ctx->alloc_ptrs[i];
   10.51 +    /* assign the next pointer */
   10.52 +    re[i] = ptr;
   10.53 +
   10.54 +    /* replace the old alloc_ptr */
   10.55 +    free(ctx->alloc_ptrs);
   10.56 +    ctx->alloc_ptrs = re;
   10.57 +    ctx->alloc_maxsize += 25;
   10.58 +    return 0;
   10.59 +}
   10.60 +
   10.61 +int libxl_free(struct libxl_ctx *ctx, void *ptr)
   10.62 +{
   10.63 +    int i;
   10.64 +
   10.65 +    if (!ptr)
   10.66 +        return 0;
   10.67 +
   10.68 +    /* remove the pointer from the tracked ptrs */
   10.69 +    for (i = 0; i < ctx->alloc_maxsize; i++) {
   10.70 +        if (ctx->alloc_ptrs[i] == ptr) {
   10.71 +            ctx->alloc_ptrs[i] = NULL;
   10.72 +            free(ptr);
   10.73 +            return 0;
   10.74 +        }
   10.75 +    }
   10.76 +    /* haven't find the pointer, really bad */
   10.77 +    return -1;
   10.78 +}
   10.79 +
   10.80 +int libxl_free_all(struct libxl_ctx *ctx)
   10.81 +{
   10.82 +    void *ptr;
   10.83 +    int i;
   10.84 +
   10.85 +    for (i = 0; i < ctx->alloc_maxsize; i++) {
   10.86 +        ptr = ctx->alloc_ptrs[i];
   10.87 +        ctx->alloc_ptrs[i] = NULL;
   10.88 +        free(ptr);
   10.89 +    }
   10.90 +    return 0;
   10.91 +}
   10.92 +
   10.93 +void *libxl_zalloc(struct libxl_ctx *ctx, int bytes)
   10.94 +{
   10.95 +    void *ptr = calloc(bytes, 1);
   10.96 +    if (!ptr) {
   10.97 +        libxl_error_set(ctx, ENOMEM);
   10.98 +        return NULL;
   10.99 +    }
  10.100 +
  10.101 +    libxl_ptr_add(ctx, ptr);
  10.102 +    return ptr;
  10.103 +}
  10.104 +
  10.105 +void *libxl_calloc(struct libxl_ctx *ctx, size_t nmemb, size_t size)
  10.106 +{
  10.107 +    void *ptr = calloc(nmemb, size);
  10.108 +    if (!ptr) {
  10.109 +        libxl_error_set(ctx, ENOMEM);
  10.110 +        return NULL;
  10.111 +    }
  10.112 +
  10.113 +    libxl_ptr_add(ctx, ptr);
  10.114 +    return ptr;
  10.115 +}
  10.116 +
  10.117 +char *libxl_sprintf(struct libxl_ctx *ctx, const char *fmt, ...)
  10.118 +{
  10.119 +    char *s;
  10.120 +    va_list ap;
  10.121 +    int ret;
  10.122 +
  10.123 +    va_start(ap, fmt);
  10.124 +    ret = vsnprintf(NULL, 0, fmt, ap);
  10.125 +    va_end(ap);
  10.126 +
  10.127 +    if (ret < 0) {
  10.128 +        return NULL;
  10.129 +    }
  10.130 +
  10.131 +    s = libxl_zalloc(ctx, ret + 1);
  10.132 +    if (s) {
  10.133 +        va_start(ap, fmt);
  10.134 +        ret = vsnprintf(s, ret + 1, fmt, ap);
  10.135 +        va_end(ap);
  10.136 +    }
  10.137 +    return s;
  10.138 +}
  10.139 +
  10.140 +char *libxl_dirname(struct libxl_ctx *ctx, const char *s)
  10.141 +{
  10.142 +    char *c;
  10.143 +    char *ptr = libxl_sprintf(ctx, "%s", s);
  10.144 +
  10.145 +    c = strrchr(ptr, '/');
  10.146 +    if (!c)
  10.147 +        return NULL;
  10.148 +    *c = '\0';
  10.149 +    return ptr;
  10.150 +}
  10.151 +
  10.152 +void xl_log(struct libxl_ctx *ctx, int loglevel, const char *file, int line, const char *func, char *fmt, ...)
  10.153 +{
  10.154 +    va_list ap;
  10.155 +    char *s;
  10.156 +    va_start(ap, fmt);
  10.157 +    vasprintf(&s, fmt, ap);
  10.158 +    va_end(ap);
  10.159 +
  10.160 +    ctx->log_callback(ctx->log_userdata, loglevel, file, line, func, s);
  10.161 +    free(s);
  10.162 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/libxl/libxl_internal.h	Mon Nov 09 19:54:28 2009 +0000
    11.3 @@ -0,0 +1,135 @@
    11.4 +/*
    11.5 + * Copyright (C) 2009      Citrix Ltd.
    11.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
    11.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    11.8 + *
    11.9 + * This program is free software; you can redistribute it and/or modify
   11.10 + * it under the terms of the GNU Lesser General Public License as published
   11.11 + * by the Free Software Foundation; version 2.1 only. with the special
   11.12 + * exception on linking described in file LICENSE.
   11.13 + *
   11.14 + * This program is distributed in the hope that it will be useful,
   11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.17 + * GNU Lesser General Public License for more details.
   11.18 + */
   11.19 +
   11.20 +#ifndef LIBXL_INTERNAL_H
   11.21 +# define LIBXL_INTERNAL_H
   11.22 +
   11.23 +#include <stdint.h>
   11.24 +#include <stdarg.h>
   11.25 +#include <stdlib.h>
   11.26 +
   11.27 +#include <xs.h>
   11.28 +#include <xenctrl.h>
   11.29 +
   11.30 +#include "flexarray.h"
   11.31 +#include "libxl_utils.h"
   11.32 +
   11.33 +#define LIBXL_DESTROY_TIMEOUT 10
   11.34 +
   11.35 +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
   11.36 +
   11.37 +
   11.38 +#define XL_LOGGING_ENABLED
   11.39 +
   11.40 +#ifdef XL_LOGGING_ENABLED
   11.41 +#define XL_LOG(ctx, loglevel, _f, _a...)   xl_log(ctx, loglevel, __FILE__, __LINE__, __func__, _f, ##_a)
   11.42 +#else
   11.43 +#define XL_LOG(ctx, loglevel, _f, _a...)
   11.44 +#endif
   11.45 +
   11.46 +#define XL_LOG_DEBUG 3
   11.47 +#define XL_LOG_INFO 2
   11.48 +#define XL_LOG_WARNING 1
   11.49 +#define XL_LOG_ERROR 0
   11.50 +
   11.51 +void xl_log(struct libxl_ctx *ctx, int loglevel, const char *file, int line, const char *func, char *fmt, ...);
   11.52 +
   11.53 +typedef struct {
   11.54 +    uint32_t store_port;
   11.55 +    unsigned long store_mfn;
   11.56 +    uint32_t console_port;
   11.57 +    unsigned long console_mfn;
   11.58 +} libxl_domain_build_state;
   11.59 +
   11.60 +typedef enum {
   11.61 +    DEVICE_VIF,
   11.62 +    DEVICE_VBD,
   11.63 +    DEVICE_TAP,
   11.64 +    DEVICE_PCI,
   11.65 +    DEVICE_VFB,
   11.66 +    DEVICE_VKBD,
   11.67 +} libxl_device_kinds;
   11.68 +
   11.69 +typedef struct {
   11.70 +    uint32_t backend_devid;
   11.71 +    uint32_t backend_domid;
   11.72 +    uint32_t devid;
   11.73 +    uint32_t domid;
   11.74 +    libxl_device_kinds backend_kind;
   11.75 +    libxl_device_kinds kind;
   11.76 +} libxl_device;
   11.77 +
   11.78 +#define PRINTF_ATTRIBUTE(x, y) __attribute__((format(printf, x, y)))
   11.79 +
   11.80 +/* memory allocation tracking/helpers */
   11.81 +int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr);
   11.82 +int libxl_free(struct libxl_ctx *ctx, void *ptr);
   11.83 +int libxl_free_all(struct libxl_ctx *ctx);
   11.84 +void *libxl_zalloc(struct libxl_ctx *ctx, int bytes);
   11.85 +void *libxl_calloc(struct libxl_ctx *ctx, size_t nmemb, size_t size);
   11.86 +char *libxl_sprintf(struct libxl_ctx *ctx, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
   11.87 +char *libxl_dirname(struct libxl_ctx *ctx, const char *s);
   11.88 +char *uuid_to_string(struct libxl_ctx *ctx, uint8_t *uuid);
   11.89 +
   11.90 +char **libxl_xs_kvs_of_flexarray(struct libxl_ctx *ctx, flexarray_t *array, int length);
   11.91 +int libxl_xs_writev(struct libxl_ctx *ctx, xs_transaction_t t,
   11.92 +                    char *dir, char **kvs);
   11.93 +int libxl_xs_write(struct libxl_ctx *ctx, xs_transaction_t t,
   11.94 +                   char *path, char *fmt, ...);
   11.95 +char *libxl_xs_get_dompath(struct libxl_ctx *ctx, uint32_t domid);
   11.96 +char *libxl_xs_read(struct libxl_ctx *ctx, xs_transaction_t t, char *path);
   11.97 +char **libxl_xs_directory(struct libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb);
   11.98 +
   11.99 +/* from xd_dom */
  11.100 +int is_hvm(struct libxl_ctx *ctx, uint32_t domid);
  11.101 +int build_pre(struct libxl_ctx *ctx, uint32_t domid,
  11.102 +              libxl_domain_build_info *info, libxl_domain_build_state *state);
  11.103 +int build_post(struct libxl_ctx *ctx, uint32_t domid,
  11.104 +               libxl_domain_build_info *info, libxl_domain_build_state *state,
  11.105 +               char **vms_ents, char **local_ents);
  11.106 +
  11.107 +int build_pv(struct libxl_ctx *ctx, uint32_t domid,
  11.108 +             libxl_domain_build_info *info, libxl_domain_build_state *state);
  11.109 +int build_hvm(struct libxl_ctx *ctx, uint32_t domid,
  11.110 +              libxl_domain_build_info *info, libxl_domain_build_state *state);
  11.111 +
  11.112 +int restore_common(struct libxl_ctx *ctx, uint32_t domid,
  11.113 +                   libxl_domain_build_info *info, libxl_domain_build_state *state, int fd);
  11.114 +int core_suspend(struct libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, int debug);
  11.115 +
  11.116 +/* from xd_device */
  11.117 +char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype);
  11.118 +char *device_disk_string_of_phystype(libxl_disk_phystype phystype);
  11.119 +
  11.120 +int device_disk_major_minor(char *virtpath, int *major, int *minor);
  11.121 +int device_disk_dev_number(char *virtpath);
  11.122 +
  11.123 +int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,
  11.124 +                             char **bents, char **fents);
  11.125 +int libxl_device_destroy(struct libxl_ctx *ctx, char *be_path, int force);
  11.126 +int libxl_devices_destroy(struct libxl_ctx *ctx, uint32_t domid, int force);
  11.127 +
  11.128 +/* from xenguest (helper */
  11.129 +int hvm_build_set_params(int handle, uint32_t domid,
  11.130 +                         int apic, int acpi, int pae, int nx, int viridian,
  11.131 +                         int vcpus, int store_evtchn, unsigned long *store_mfn);
  11.132 +
  11.133 +/* xd_exec */
  11.134 +int libxl_exec(struct libxl_ctx *ctx, int stdinfd, int stdoutfd, int stderrfd,
  11.135 +               char *arg0, char **args);
  11.136 +
  11.137 +#endif
  11.138 +
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/tools/libxl/libxl_utils.c	Mon Nov 09 19:54:28 2009 +0000
    12.3 @@ -0,0 +1,159 @@
    12.4 +/*
    12.5 + * Copyright (C) 2009      Citrix Ltd.
    12.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    12.7 + *
    12.8 + * This program is free software; you can redistribute it and/or modify
    12.9 + * it under the terms of the GNU Lesser General Public License as published
   12.10 + * by the Free Software Foundation; version 2.1 only. with the special
   12.11 + * exception on linking described in file LICENSE.
   12.12 + *
   12.13 + * This program is distributed in the hope that it will be useful,
   12.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.16 + * GNU Lesser General Public License for more details.
   12.17 + */
   12.18 +
   12.19 +#include "libxl_utils.h"
   12.20 +#include "libxl_internal.h"
   12.21 +#include <stdio.h>
   12.22 +#include <stdlib.h>
   12.23 +#include <stdint.h>
   12.24 +#include <string.h>
   12.25 +#include <xs.h>
   12.26 +#include <xenctrl.h>
   12.27 +#include <ctype.h>
   12.28 +#include <errno.h>
   12.29 +
   12.30 +
   12.31 +
   12.32 +unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus)
   12.33 +{
   12.34 +    /* 256 pages (1MB) per vcpu,
   12.35 +       plus 1 page per MiB of RAM for the P2M map,
   12.36 +       plus 1 page per MiB of RAM to shadow the resident processes.
   12.37 +       This is higher than the minimum that Xen would allocate if no value
   12.38 +       were given (but the Xen minimum is for safety, not performance).
   12.39 +     */
   12.40 +    return 4 * (256 * smp_cpus + 2 * (maxmem_kb / 1024));
   12.41 +}
   12.42 +
   12.43 +char *libxl_domid_to_name(struct libxl_ctx *ctx, uint32_t domid)
   12.44 +{
   12.45 +    unsigned int len;
   12.46 +    char path[strlen("/local/domain") + 12];
   12.47 +    char *s;
   12.48 +
   12.49 +    snprintf(path, sizeof(path), "/local/domain/%d/name", domid);
   12.50 +    s = xs_read(ctx->xsh, XBT_NULL, path, &len);
   12.51 +    libxl_ptr_add(ctx, s);
   12.52 +    return s;
   12.53 +}
   12.54 +
   12.55 +int libxl_name_to_domid(struct libxl_ctx *ctx, char *name, uint32_t *domid)
   12.56 +{
   12.57 +    unsigned int num, len;
   12.58 +    char path[strlen("/local/domain") + 12];
   12.59 +    int i;
   12.60 +    char *domname, **l;
   12.61 +
   12.62 +    l = xs_directory(ctx->xsh, XBT_NULL, "/local/domain", &num);
   12.63 +    for (i = 0; i < num; i++) {
   12.64 +        snprintf(path, sizeof(path), "/local/domain/%s/name", l[i]);
   12.65 +        domname = xs_read(ctx->xsh, XBT_NULL, path, &len);
   12.66 +        if (domname != NULL && !strncmp(domname, name, len)) {
   12.67 +            *domid = atoi(l[i]);
   12.68 +            free(l);
   12.69 +            free(domname);
   12.70 +            return 0;
   12.71 +        }
   12.72 +        free(domname);
   12.73 +    }
   12.74 +    free(l);
   12.75 +    return -1;
   12.76 +}
   12.77 +
   12.78 +int libxl_uuid_to_domid(struct libxl_ctx *ctx, uint8_t *uuid, uint32_t *domid)
   12.79 +{
   12.80 +    int nb_domain, i;
   12.81 +    struct libxl_dominfo *info = libxl_domain_list(ctx, &nb_domain);
   12.82 +    for (i = 0; i < nb_domain; i++) {
   12.83 +        if (!memcmp(info[i].uuid, uuid, 16)) {
   12.84 +            *domid = info[i].domid;
   12.85 +            return 0;
   12.86 +        }
   12.87 +    }
   12.88 +    return -1;
   12.89 +}
   12.90 +
   12.91 +int libxl_domid_to_uuid(struct libxl_ctx *ctx, uint8_t **uuid, uint32_t domid)
   12.92 +{
   12.93 +    int nb_domain, i;
   12.94 +    struct libxl_dominfo *info = libxl_domain_list(ctx, &nb_domain);
   12.95 +    for (i = 0; i < nb_domain; i++) {
   12.96 +        if (domid == info[i].domid) {
   12.97 +            *uuid = libxl_zalloc(ctx, 16);
   12.98 +            memcpy(*uuid, info[i].uuid, 16);
   12.99 +            return 0;
  12.100 +        }
  12.101 +    }
  12.102 +    return -1;
  12.103 +}
  12.104 +
  12.105 +int libxl_is_uuid(char *s)
  12.106 +{
  12.107 +    int i;
  12.108 +    if (!s || strlen(s) != 36)
  12.109 +        return 0;
  12.110 +    for (i = 0; i < 36; i++) {
  12.111 +        if (i == 8 || i == 13 || i == 18 || i == 23) {
  12.112 +            if (s[i] != '-')
  12.113 +                return 0;
  12.114 +        } else {
  12.115 +            if (!isxdigit(s[i]))
  12.116 +                return 0;
  12.117 +        }
  12.118 +    }
  12.119 +    return 1;
  12.120 +}
  12.121 +
  12.122 +uint8_t *string_to_uuid(struct libxl_ctx *ctx, char *s)
  12.123 +{
  12.124 +    uint8_t *buf;
  12.125 +    if (!s || !ctx)
  12.126 +        return NULL;
  12.127 +
  12.128 +    buf = libxl_zalloc(ctx, 16);
  12.129 +    sscanf(s, UUID_FMT, &buf[0], &buf[1], &buf[2], &buf[3], &buf[4], &buf[5],
  12.130 +           &buf[6], &buf[7], &buf[8], &buf[9], &buf[10], &buf[11], &buf[12],
  12.131 +           &buf[13], &buf[14], &buf[15]);
  12.132 +    return buf;
  12.133 +}
  12.134 +
  12.135 +char *uuid_to_string(struct libxl_ctx *ctx, uint8_t *uuid)
  12.136 +{
  12.137 +    if (!uuid)
  12.138 +        return NULL;
  12.139 +    return libxl_sprintf(ctx, UUID_FMT,
  12.140 +                         uuid[0], uuid[1], uuid[2], uuid[3],
  12.141 +                         uuid[4], uuid[5], uuid[6], uuid[7],
  12.142 +                         uuid[8], uuid[9], uuid[10], uuid[11],
  12.143 +                         uuid[12], uuid[13], uuid[14], uuid[15]);
  12.144 +}
  12.145 +
  12.146 +int libxl_param_to_domid(struct libxl_ctx *ctx, char *p, uint32_t *domid)
  12.147 +{
  12.148 +    uint8_t *uuid;
  12.149 +    uint32_t d;
  12.150 +
  12.151 +    if (libxl_is_uuid(p)) {
  12.152 +        uuid = string_to_uuid(ctx, p);
  12.153 +        return libxl_uuid_to_domid(ctx, uuid, domid);
  12.154 +    }
  12.155 +    errno = 0;
  12.156 +    d = strtol(p, (char **) NULL, 10);
  12.157 +    if (!errno && d != 0 && d != LONG_MAX && d != LONG_MIN) {
  12.158 +        *domid = d;
  12.159 +        return 0;
  12.160 +    }
  12.161 +    return libxl_name_to_domid(ctx, p, domid);
  12.162 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/tools/libxl/libxl_utils.h	Mon Nov 09 19:54:28 2009 +0000
    13.3 @@ -0,0 +1,34 @@
    13.4 +/*
    13.5 + * Copyright (C) 2009      Citrix Ltd.
    13.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    13.7 + *
    13.8 + * This program is free software; you can redistribute it and/or modify
    13.9 + * it under the terms of the GNU Lesser General Public License as published
   13.10 + * by the Free Software Foundation; version 2.1 only. with the special
   13.11 + * exception on linking described in file LICENSE.
   13.12 + *
   13.13 + * This program is distributed in the hope that it will be useful,
   13.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 + * GNU Lesser General Public License for more details.
   13.17 + */
   13.18 +
   13.19 +#ifndef LIBXL_UTILS_H
   13.20 +#define LIBXL_UTILS_H
   13.21 +
   13.22 +#include "libxl.h"
   13.23 +
   13.24 +#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
   13.25 +
   13.26 +unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus);
   13.27 +int libxl_name_to_domid(struct libxl_ctx *ctx, char *name, uint32_t *domid);
   13.28 +char *libxl_domid_to_name(struct libxl_ctx *ctx, uint32_t domid);
   13.29 +int libxl_uuid_to_domid(struct libxl_ctx *ctx, uint8_t *uuid, uint32_t *domid);
   13.30 +int libxl_domid_to_uuid(struct libxl_ctx *ctx, uint8_t **uuid, uint32_t domid);
   13.31 +int libxl_is_uuid(char *s);
   13.32 +uint8_t *string_to_uuid(struct libxl_ctx *ctx, char *s);
   13.33 +char *uuid_to_string(struct libxl_ctx *ctx, uint8_t *uuid);
   13.34 +int libxl_param_to_domid(struct libxl_ctx *ctx, char *p, uint32_t *domid);
   13.35 +
   13.36 +#endif
   13.37 +
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/tools/libxl/libxl_xshelp.c	Mon Nov 09 19:54:28 2009 +0000
    14.3 @@ -0,0 +1,108 @@
    14.4 +/*
    14.5 + * Copyright (C) 2009      Citrix Ltd.
    14.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
    14.7 + *
    14.8 + * This program is free software; you can redistribute it and/or modify
    14.9 + * it under the terms of the GNU Lesser General Public License as published
   14.10 + * by the Free Software Foundation; version 2.1 only. with the special
   14.11 + * exception on linking described in file LICENSE.
   14.12 + *
   14.13 + * This program is distributed in the hope that it will be useful,
   14.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.16 + * GNU Lesser General Public License for more details.
   14.17 + */
   14.18 +
   14.19 +#include <string.h>
   14.20 +#include <stddef.h>
   14.21 +#include "libxl.h"
   14.22 +#include "libxl_internal.h"
   14.23 +#include <stdio.h>
   14.24 +#include <stdarg.h>
   14.25 +
   14.26 +char **libxl_xs_kvs_of_flexarray(struct libxl_ctx *ctx, flexarray_t *array, int length)
   14.27 +{
   14.28 +    char **kvs;
   14.29 +    int i;
   14.30 +
   14.31 +    kvs = libxl_calloc(ctx, length + 2, sizeof(char *));
   14.32 +    if (kvs) {
   14.33 +        for (i = 0; i < length; i += 2) {
   14.34 +            void *ptr;
   14.35 +
   14.36 +            flexarray_get(array, i, &ptr);
   14.37 +            kvs[i] = (char *) ptr;
   14.38 +            flexarray_get(array, i + 1, &ptr);
   14.39 +            kvs[i + 1] = (char *) ptr;
   14.40 +        }
   14.41 +        kvs[i] = NULL;
   14.42 +        kvs[i + 1] = NULL;
   14.43 +    }
   14.44 +    return kvs;
   14.45 +}
   14.46 +
   14.47 +int libxl_xs_writev(struct libxl_ctx *ctx, xs_transaction_t t,
   14.48 +                    char *dir, char *kvs[])
   14.49 +{
   14.50 +    char *path;
   14.51 +    int i;
   14.52 +
   14.53 +    if (!kvs)
   14.54 +        return 0;
   14.55 +
   14.56 +    for (i = 0; kvs[i] != NULL; i += 2) {
   14.57 +        path = libxl_sprintf(ctx, "%s/%s", dir, kvs[i]);
   14.58 +        if (path) {
   14.59 +            int length = strlen(kvs[i + 1]);
   14.60 +            xs_write(ctx->xsh, t, path, kvs[i + 1], length);
   14.61 +        }
   14.62 +        libxl_free(ctx, path);
   14.63 +    }
   14.64 +    return 0;
   14.65 +}
   14.66 +
   14.67 +int libxl_xs_write(struct libxl_ctx *ctx, xs_transaction_t t,
   14.68 +                   char *path, char *fmt, ...)
   14.69 +{
   14.70 +    char *s;
   14.71 +    va_list ap;
   14.72 +    int ret;
   14.73 +    va_start(ap, fmt);
   14.74 +    ret = vasprintf(&s, fmt, ap);
   14.75 +    va_end(ap);
   14.76 +
   14.77 +    if (ret == -1) {
   14.78 +        return -1;
   14.79 +    }
   14.80 +    xs_write(ctx->xsh, t, path, s, ret);
   14.81 +    free(s);
   14.82 +    return 0;
   14.83 +}
   14.84 +
   14.85 +char * libxl_xs_read(struct libxl_ctx *ctx, xs_transaction_t t, char *path)
   14.86 +{
   14.87 +    unsigned int len;
   14.88 +    char *ptr;
   14.89 +
   14.90 +    ptr = xs_read(ctx->xsh, t, path, &len);
   14.91 +    if (ptr != NULL) {
   14.92 +        libxl_ptr_add(ctx, ptr);
   14.93 +        return ptr;
   14.94 +    }
   14.95 +    return 0;
   14.96 +}
   14.97 +
   14.98 +char *libxl_xs_get_dompath(struct libxl_ctx *ctx, uint32_t domid)
   14.99 +{
  14.100 +    char *s = xs_get_domain_path(ctx->xsh, domid);
  14.101 +    libxl_ptr_add(ctx, s);
  14.102 +    return s;
  14.103 +}
  14.104 +
  14.105 +char **libxl_xs_directory(struct libxl_ctx *ctx, xs_transaction_t t, char *path, unsigned int *nb)
  14.106 +{
  14.107 +    char **ret = NULL;
  14.108 +    ret = xs_directory(ctx->xsh, XBT_NULL, path, nb);
  14.109 +    libxl_ptr_add(ctx, ret);
  14.110 +    return ret;
  14.111 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/tools/libxl/osdeps.c	Mon Nov 09 19:54:28 2009 +0000
    15.3 @@ -0,0 +1,62 @@
    15.4 +/*
    15.5 + * Copyright (C) 2009      Citrix Ltd.
    15.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    15.7 + *
    15.8 + * This program is free software; you can redistribute it and/or modify
    15.9 + * it under the terms of the GNU Lesser General Public License as published
   15.10 + * by the Free Software Foundation; version 2.1 only. with the special
   15.11 + * exception on linking described in file LICENSE.
   15.12 + *
   15.13 + * This program is distributed in the hope that it will be useful,
   15.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.16 + * GNU Lesser General Public License for more details.
   15.17 + */
   15.18 +
   15.19 +#include <unistd.h>
   15.20 +#include <stdarg.h>
   15.21 +#include <stdio.h>
   15.22 +#include <sys/time.h>
   15.23 +#include <stdlib.h>
   15.24 +
   15.25 +int vasprintf(char **buffer, const char *fmt, va_list ap)
   15.26 +{
   15.27 +    int size = 0;
   15.28 +    int nchars;
   15.29 +
   15.30 +    *buffer = 0;
   15.31 +
   15.32 +    nchars = vsnprintf(*buffer, 0, fmt, ap);
   15.33 +
   15.34 +    if (nchars >= size)
   15.35 +    {
   15.36 +        char *tmpbuff;
   15.37 +        /* Reallocate buffer now that we know how much space is needed. */
   15.38 +        size = nchars+1;
   15.39 +        tmpbuff = (char*)realloc(*buffer, size);
   15.40 +
   15.41 +
   15.42 +        if (tmpbuff == NULL) { /* we need to free it*/
   15.43 +            free(*buffer);
   15.44 +            return -1;
   15.45 +        }
   15.46 +
   15.47 +        *buffer=tmpbuff;
   15.48 +        /* Try again. */
   15.49 +        nchars = vsnprintf(*buffer, size, fmt, ap);
   15.50 +    }
   15.51 +
   15.52 +    if (nchars < 0) return nchars;
   15.53 +    return size;
   15.54 +}
   15.55 +
   15.56 +int asprintf(char **buffer, char *fmt, ...)
   15.57 +{
   15.58 +    int status;
   15.59 +    va_list ap;
   15.60 +
   15.61 +    va_start (ap, fmt);
   15.62 +    status = vasprintf (buffer, fmt, ap);
   15.63 +    va_end (ap);
   15.64 +    return status;
   15.65 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/tools/libxl/osdeps.h	Mon Nov 09 19:54:28 2009 +0000
    16.3 @@ -0,0 +1,24 @@
    16.4 +/*
    16.5 + * Copyright (C) 2009      Citrix Ltd.
    16.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    16.7 + *
    16.8 + * This program is free software; you can redistribute it and/or modify
    16.9 + * it under the terms of the GNU Lesser General Public License as published
   16.10 + * by the Free Software Foundation; version 2.1 only. with the special
   16.11 + * exception on linking described in file LICENSE.
   16.12 + *
   16.13 + * This program is distributed in the hope that it will be useful,
   16.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.16 + * GNU Lesser General Public License for more details.
   16.17 + */
   16.18 +
   16.19 +#ifndef LIBXL_OSDEP
   16.20 +#define LIBXL_OSDEP
   16.21 +
   16.22 +#include <stdarg.h>
   16.23 +
   16.24 +int asprintf(char **buffer, char *fmt, ...);
   16.25 +int vasprintf(char **buffer, const char *fmt, va_list ap);
   16.26 +
   16.27 +#endif
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/tools/libxl/xenguest.c	Mon Nov 09 19:54:28 2009 +0000
    17.3 @@ -0,0 +1,49 @@
    17.4 +/*
    17.5 + * Copyright (C) 2009      Citrix Ltd.
    17.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
    17.7 + *
    17.8 + * This program is free software; you can redistribute it and/or modify
    17.9 + * it under the terms of the GNU Lesser General Public License as published
   17.10 + * by the Free Software Foundation; version 2.1 only. with the special
   17.11 + * exception on linking described in file LICENSE.
   17.12 + *
   17.13 + * This program is distributed in the hope that it will be useful,
   17.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.16 + * GNU Lesser General Public License for more details.
   17.17 + */
   17.18 +
   17.19 +#include <xenctrl.h>
   17.20 +#include <xenguest.h>
   17.21 +#include <sys/mman.h>
   17.22 +#include <xen/hvm/hvm_info_table.h>
   17.23 +
   17.24 +int hvm_build_set_params(int handle, uint32_t domid,
   17.25 +                         int apic, int acpi, int pae, int nx, int viridian,
   17.26 +                         int vcpus, int store_evtchn, unsigned long *store_mfn)
   17.27 +{
   17.28 +    struct hvm_info_table *va_hvm;
   17.29 +    uint8_t *va_map, sum;
   17.30 +    int i;
   17.31 +
   17.32 +    va_map = xc_map_foreign_range(handle, domid,
   17.33 +                                  XC_PAGE_SIZE, PROT_READ | PROT_WRITE,
   17.34 +                                  HVM_INFO_PFN);
   17.35 +    if (va_map == NULL)
   17.36 +        return -1;
   17.37 +
   17.38 +    va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
   17.39 +    va_hvm->acpi_enabled = acpi;
   17.40 +    va_hvm->apic_mode = apic;
   17.41 +    va_hvm->nr_vcpus = vcpus;
   17.42 +    for (i = 0, sum = 0; i < va_hvm->length; i++)
   17.43 +        sum += ((uint8_t *) va_hvm)[i];
   17.44 +    va_hvm->checksum -= sum;
   17.45 +    munmap(va_map, XC_PAGE_SIZE);
   17.46 +
   17.47 +    xc_get_hvm_param(handle, domid, HVM_PARAM_STORE_PFN, store_mfn);
   17.48 +    xc_set_hvm_param(handle, domid, HVM_PARAM_PAE_ENABLED, pae);
   17.49 +    xc_set_hvm_param(handle, domid, HVM_PARAM_VIRIDIAN, viridian);
   17.50 +    xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
   17.51 +    return 0;
   17.52 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tools/libxl/xl.c	Mon Nov 09 19:54:28 2009 +0000
    18.3 @@ -0,0 +1,727 @@
    18.4 +/*
    18.5 + * Copyright (C) 2009      Citrix Ltd.
    18.6 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    18.7 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
    18.8 + *
    18.9 + * This program is free software; you can redistribute it and/or modify
   18.10 + * it under the terms of the GNU Lesser General Public License as published
   18.11 + * by the Free Software Foundation; version 2.1 only. with the special
   18.12 + * exception on linking described in file LICENSE.
   18.13 + *
   18.14 + * This program is distributed in the hope that it will be useful,
   18.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.17 + * GNU Lesser General Public License for more details.
   18.18 + */
   18.19 +
   18.20 +#include "libxl.h"
   18.21 +#include "libxl_utils.h"
   18.22 +#include <stdio.h>
   18.23 +#include <stdlib.h>
   18.24 +#include <string.h>
   18.25 +#include <uuid/uuid.h>
   18.26 +#include <libconfig.h>
   18.27 +#include <unistd.h>
   18.28 +#include <getopt.h>
   18.29 +#include <sys/types.h>
   18.30 +#include <sys/socket.h>
   18.31 +#include <arpa/inet.h>
   18.32 +#include <xenctrl.h>
   18.33 +
   18.34 +void log_callback(void *userdata, int loglevel, const char *file, int line, const char *func, char *s)
   18.35 +{
   18.36 +    fprintf(stderr, "[%d] %s:%d:%s: %s\n", loglevel, file, line, func, s);
   18.37 +}
   18.38 +
   18.39 +static void printf_info(libxl_domain_create_info *c_info,
   18.40 +                        libxl_domain_build_info *b_info,
   18.41 +                        libxl_device_disk *disks,
   18.42 +                        int num_disks,
   18.43 +                        libxl_device_nic *vifs,
   18.44 +                        int num_vifs,
   18.45 +                        libxl_device_model_info *dm_info)
   18.46 +{
   18.47 +    int i;
   18.48 +    printf("*** domain_create_info ***\n");
   18.49 +    printf("hvm: %d\n", c_info->hvm);
   18.50 +    printf("hap: %d\n", c_info->hap);
   18.51 +    printf("ssidref: %d\n", c_info->ssidref);
   18.52 +    printf("name: %s\n", c_info->name);
   18.53 +    printf("uuid: " UUID_FMT "\n", c_info->uuid[0], c_info->uuid[1], c_info->uuid[2], c_info->uuid[3],
   18.54 +           c_info->uuid[4], c_info->uuid[5], c_info->uuid[6], c_info->uuid[7],
   18.55 +           c_info->uuid[8], c_info->uuid[9], c_info->uuid[10], c_info->uuid[11],
   18.56 +           c_info->uuid[12], c_info->uuid[13], c_info->uuid[14], c_info->uuid[15]);
   18.57 +    if (c_info->xsdata)
   18.58 +        printf("xsdata: contains data\n");
   18.59 +    else
   18.60 +        printf("xsdata: (null)\n");
   18.61 +    if (c_info->platformdata)
   18.62 +        printf("platformdata: contains data\n");
   18.63 +    else
   18.64 +        printf("platformdata: (null)\n");
   18.65 +
   18.66 +
   18.67 +    printf("\n\n\n*** domain_build_info ***\n");
   18.68 +    printf("timer_mode: %d\n", b_info->timer_mode);
   18.69 +    printf("hpet: %d\n", b_info->hpet);
   18.70 +    printf("vpt_align: %d\n", b_info->vpt_align);
   18.71 +    printf("max_vcpus: %d\n", b_info->max_vcpus);
   18.72 +    printf("max_memkb: %d\n", b_info->max_memkb);
   18.73 +    printf("video_memkb: %d\n", b_info->video_memkb);
   18.74 +    printf("shadow_memkb: %d\n", b_info->shadow_memkb);
   18.75 +    printf("kernel: %s\n", b_info->kernel);
   18.76 +    printf("hvm: %d\n", b_info->hvm);
   18.77 +
   18.78 +    if (b_info->hvm) {
   18.79 +        printf("    pae: %d\n", b_info->u.hvm.pae);
   18.80 +        printf("    apic: %d\n", b_info->u.hvm.apic);
   18.81 +        printf("    acpi: %d\n", b_info->u.hvm.acpi);
   18.82 +        printf("    nx: %d\n", b_info->u.hvm.nx);
   18.83 +        printf("    viridian: %d\n", b_info->u.hvm.viridian);
   18.84 +    } else {
   18.85 +        printf("cmdline: %s\n", b_info->u.pv.cmdline);
   18.86 +        printf("ramdisk: %s\n", b_info->u.pv.ramdisk);
   18.87 +    }
   18.88 +
   18.89 +    for (i = 0; i < num_disks; i++) {
   18.90 +        printf("\n\n\n*** disks_info: %d ***\n", i);
   18.91 +        printf("backend_domid %d\n", disks[i].backend_domid);
   18.92 +        printf("domid %d\n", disks[i].domid);
   18.93 +        printf("physpath %s\n", disks[i].physpath);
   18.94 +        printf("phystype %d\n", disks[i].phystype);
   18.95 +        printf("virtpath %s\n", disks[i].virtpath);
   18.96 +        printf("unpluggable %d\n", disks[i].unpluggable);
   18.97 +        printf("readwrite %d\n", disks[i].readwrite);
   18.98 +        printf("is_cdrom %d\n", disks[i].is_cdrom);
   18.99 +    }
  18.100 +
  18.101 +    for (i = 0; i < num_vifs; i++) {
  18.102 +        printf("\n\n\n*** vifs_info: %d ***\n", i);
  18.103 +        printf("backend_domid %d\n", vifs[i].backend_domid);
  18.104 +        printf("domid %d\n", vifs[i].domid);
  18.105 +        printf("devid %d\n", vifs[i].devid);
  18.106 +        printf("mtu %d\n", vifs[i].mtu);
  18.107 +        printf("model %s\n", vifs[i].model);
  18.108 +        printf("mac %02x:%02x:%02x:%02x:%02x:%02x\n", vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]);
  18.109 +        printf("smac %s\n", vifs[i].mac);
  18.110 +    }
  18.111 +
  18.112 +    printf("\n\n\n*** device_model_info ***\n");
  18.113 +    printf("domid: %d\n", dm_info->domid);
  18.114 +    printf("dom_name: %s\n", dm_info->dom_name);
  18.115 +    printf("device_model: %s\n", dm_info->device_model);
  18.116 +    printf("videoram: %d\n", dm_info->videoram);
  18.117 +    printf("stdvga: %d\n", dm_info->stdvga);
  18.118 +    printf("vnc: %d\n", dm_info->vnc);
  18.119 +    printf("vnclisten: %s\n", dm_info->vnclisten);
  18.120 +    printf("vncdisplay: %d\n", dm_info->vncdisplay);
  18.121 +    printf("vncunused: %d\n", dm_info->vncunused);
  18.122 +    printf("keymap: %s\n", dm_info->keymap);
  18.123 +    printf("sdl: %d\n", dm_info->sdl);
  18.124 +    printf("opengl: %d\n", dm_info->opengl);
  18.125 +    printf("nographic: %d\n", dm_info->nographic);
  18.126 +    printf("serial: %s\n", dm_info->serial);
  18.127 +    printf("boot: %s\n", dm_info->boot);
  18.128 +    printf("usb: %d\n", dm_info->usb);
  18.129 +    printf("usbdevice: %s\n", dm_info->usbdevice);
  18.130 +    printf("apic: %d\n", dm_info->apic);
  18.131 +}
  18.132 +
  18.133 +static char* compat_config_file(const char *filename)
  18.134 +{
  18.135 +    char t;
  18.136 +    char *newfile = (char*) malloc(strlen(filename) + 4);
  18.137 +    char *buf = (char *) malloc(2048);
  18.138 +    int size = 2048, i;
  18.139 +    FILE *s;
  18.140 +    FILE *d;
  18.141 +
  18.142 +    sprintf(newfile, "%s.xl", filename);
  18.143 +
  18.144 +    s = fopen(filename, "r");
  18.145 +    if (!s) {
  18.146 +        perror("cannot open file for reading");
  18.147 +        return NULL;
  18.148 +    }
  18.149 +    d = fopen(newfile, "w");
  18.150 +    if (!d) {
  18.151 +        fclose(s);
  18.152 +        perror("cannot open file for writting");
  18.153 +        return NULL;
  18.154 +    }
  18.155 +
  18.156 +    while (!feof(s)) {
  18.157 +        fgets(buf, size, s);
  18.158 +        while (buf[strlen(buf) - 1] != '\n' && !feof(s)) {
  18.159 +            size += 1024;
  18.160 +            buf = realloc(buf, size + 1024);
  18.161 +            fgets(buf + (size - 1025), 1025, s);
  18.162 +        }
  18.163 +        for (i = 0; i < strlen(buf); i++)
  18.164 +            if (buf[i] == '\'')
  18.165 +                buf[i] = '\"';
  18.166 +        if (strchr(buf, '=') != NULL) {
  18.167 +            if ((buf[strlen(buf) - 1] == '\n' && buf[strlen(buf) - 2] == ';') ||
  18.168 +                    buf[strlen(buf) - 1] == ';') {
  18.169 +                fputs(buf, d);
  18.170 +            } else {
  18.171 +                t = buf[strlen(buf) - 1];
  18.172 +                buf[strlen(buf) - 1] = ';';
  18.173 +                fputs(buf, d);
  18.174 +                fputc(t, d);
  18.175 +            }
  18.176 +        } else if (buf[0] == '#' || buf[0] == ' ' || buf[0] == '\n') {
  18.177 +            fputs(buf, d);
  18.178 +        }
  18.179 +    }
  18.180 +
  18.181 +    fclose(s);
  18.182 +    fclose(d);
  18.183 +
  18.184 +    free(buf);
  18.185 +
  18.186 +    return newfile;
  18.187 +}
  18.188 +
  18.189 +void init_create_info(libxl_domain_create_info *c_info)
  18.190 +{
  18.191 +    memset(c_info, '\0', sizeof(*c_info));
  18.192 +    c_info->xsdata = NULL;
  18.193 +    c_info->platformdata = NULL;
  18.194 +    c_info->hvm = 1;
  18.195 +    c_info->ssidref = 0;
  18.196 +}
  18.197 +
  18.198 +void init_build_info(libxl_domain_build_info *b_info, libxl_domain_create_info *c_info)
  18.199 +{
  18.200 +    memset(b_info, '\0', sizeof(*b_info));
  18.201 +    b_info->timer_mode = -1;
  18.202 +    b_info->hpet = 1;
  18.203 +    b_info->vpt_align = -1;
  18.204 +    b_info->max_vcpus = 1;
  18.205 +    b_info->max_memkb = 32 * 1024;
  18.206 +    b_info->shadow_memkb = libxl_get_required_shadow_memory(b_info->max_memkb, b_info->max_vcpus);
  18.207 +    b_info->video_memkb = 8 * 1024;
  18.208 +    b_info->kernel = "/usr/lib/xen/boot/hvmloader";
  18.209 +    if (c_info->hvm) {
  18.210 +        b_info->hvm = 1;
  18.211 +        b_info->u.hvm.pae = 1;
  18.212 +        b_info->u.hvm.apic = 1;
  18.213 +        b_info->u.hvm.acpi = 1;
  18.214 +        b_info->u.hvm.nx = 1;
  18.215 +        b_info->u.hvm.viridian = 0;
  18.216 +    }
  18.217 +}
  18.218 +
  18.219 +void init_dm_info(libxl_device_model_info *dm_info,
  18.220 +        libxl_domain_create_info *c_info, libxl_domain_build_info *b_info)
  18.221 +{
  18.222 +    memset(dm_info, '\0', sizeof(*dm_info));
  18.223 +
  18.224 +    dm_info->dom_name = c_info->name;
  18.225 +    dm_info->device_model = "/usr/lib/xen/bin/qemu-dm";
  18.226 +    dm_info->videoram = b_info->video_memkb / 1024;
  18.227 +    dm_info->apic = b_info->u.hvm.apic;
  18.228 +
  18.229 +    dm_info->stdvga = 0;
  18.230 +    dm_info->vnc = 1;
  18.231 +    dm_info->vnclisten = "127.0.0.1";
  18.232 +    dm_info->vncdisplay = 0;
  18.233 +    dm_info->vncunused = 0;
  18.234 +    dm_info->keymap = NULL;
  18.235 +    dm_info->sdl = 0;
  18.236 +    dm_info->opengl = 0;
  18.237 +    dm_info->nographic = 0;
  18.238 +    dm_info->serial = NULL;
  18.239 +    dm_info->boot = "cda";
  18.240 +    dm_info->usb = 0;
  18.241 +    dm_info->usbdevice = NULL;
  18.242 +}
  18.243 +
  18.244 +void init_nic_info(libxl_device_nic *nic_info, int devnum)
  18.245 +{
  18.246 +    memset(nic_info, '\0', sizeof(*nic_info));
  18.247 +
  18.248 +
  18.249 +    nic_info->backend_domid = 0;
  18.250 +    nic_info->domid = 0;
  18.251 +    nic_info->devid = devnum;
  18.252 +    nic_info->mtu = 1492;
  18.253 +    nic_info->model = "e1000";
  18.254 +    srand(time(0));
  18.255 +    nic_info->mac[0] = 0x00;
  18.256 +    nic_info->mac[1] = 0x16;
  18.257 +    nic_info->mac[2] = 0x3e;
  18.258 +    nic_info->mac[3] = 1 + (int) (0x7f * (rand() / (RAND_MAX + 1.0)));
  18.259 +    nic_info->mac[4] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
  18.260 +    nic_info->mac[5] = 1 + (int) (0xff * (rand() / (RAND_MAX + 1.0)));
  18.261 +    asprintf(&(nic_info->smac), "%02x:%02x:%02x:%02x:%02x:%02x", nic_info->mac[0], nic_info->mac[1], nic_info->mac[2], nic_info->mac[3], nic_info->mac[4], nic_info->mac[5]);
  18.262 +    nic_info->ifname = NULL;
  18.263 +    nic_info->bridge = "xenbr0";
  18.264 +    nic_info->script = "/etc/xen/scripts/vif-bridge";
  18.265 +    nic_info->nictype = NICTYPE_IOEMU;
  18.266 +}
  18.267 +
  18.268 +void nic_info_domid_fixup(libxl_device_nic *nic_info, int domid)
  18.269 +{
  18.270 +    nic_info->domid = domid;
  18.271 +    if (!nic_info->ifname)
  18.272 +        asprintf(&(nic_info->ifname), "tap%d.%d", domid, nic_info->devid - 1);
  18.273 +}
  18.274 +
  18.275 +void disk_info_domid_fixup(libxl_device_disk *disk_info, int domid)
  18.276 +{
  18.277 +    disk_info->domid = domid;
  18.278 +}
  18.279 +
  18.280 +void device_model_info_domid_fixup(libxl_device_model_info *dm_info, int domid)
  18.281 +{
  18.282 +    dm_info->domid = domid;
  18.283 +}
  18.284 +
  18.285 +static void parse_config_file(const char *filename,
  18.286 +                              libxl_domain_create_info *c_info,
  18.287 +                              libxl_domain_build_info *b_info,
  18.288 +                              libxl_device_disk **disks,
  18.289 +                              int *num_disks,
  18.290 +                              libxl_device_nic **vifs,
  18.291 +                              int *num_vifs,
  18.292 +                              libxl_device_model_info *dm_info)
  18.293 +{
  18.294 +    const char *buf;
  18.295 +    uint8_t uuid[16];
  18.296 +    long l;
  18.297 +    struct config_t config;
  18.298 +    struct config_setting_t *vbds, *nics;
  18.299 +
  18.300 +    config_init (&config);
  18.301 +
  18.302 +    if (!config_read_file(&config, filename)) {
  18.303 +        char *newfilename;
  18.304 +        config_destroy(&config);
  18.305 +        newfilename = compat_config_file(filename);
  18.306 +        config_init (&config);
  18.307 +        if (!config_read_file(&config, newfilename)) {
  18.308 +            fprintf(stderr, "Failed to parse config file %s, try removing any embedded python code\n", config_error_text(&config));
  18.309 +            exit(1);
  18.310 +        }
  18.311 +        free(newfilename);
  18.312 +    }
  18.313 +
  18.314 +    init_create_info(c_info);
  18.315 +
  18.316 +    if (config_lookup_string (&config, "builder", &buf) == CONFIG_TRUE) {
  18.317 +        if (!strncmp(buf, "hvm", strlen(buf)))
  18.318 +            c_info->hvm = 1;
  18.319 +        else
  18.320 +            c_info->hvm = 0;
  18.321 +    }
  18.322 +
  18.323 +    /* hap is missing */
  18.324 +    if (config_lookup_string (&config, "name", &buf) == CONFIG_TRUE)
  18.325 +        c_info->name = strdup(buf);
  18.326 +    else
  18.327 +        c_info->name = "test";
  18.328 +    uuid_generate(uuid);
  18.329 +    c_info->uuid = uuid;
  18.330 +
  18.331 +    init_build_info(b_info, c_info);
  18.332 +
  18.333 +    /* the following is the actual config parsing with overriding values in the structures */
  18.334 +    if (config_lookup_int (&config, "vcpus", &l) == CONFIG_TRUE)
  18.335 +        b_info->max_vcpus = l;
  18.336 +
  18.337 +    if (config_lookup_int (&config, "memory", &l) == CONFIG_TRUE)
  18.338 +        b_info->max_memkb = l * 1024;
  18.339 +
  18.340 +    if (config_lookup_int (&config, "shadow_memory", &l) == CONFIG_TRUE)
  18.341 +        b_info->shadow_memkb = l * 1024;
  18.342 +
  18.343 +    if (config_lookup_int (&config, "videoram", &l) == CONFIG_TRUE)
  18.344 +        b_info->video_memkb = l * 1024;
  18.345 +
  18.346 +    if (config_lookup_string (&config, "kernel", &buf) == CONFIG_TRUE)
  18.347 +        b_info->kernel = strdup(buf);
  18.348 +
  18.349 +    if (c_info->hvm == 1) {
  18.350 +        if (config_lookup_int (&config, "pae", &l) == CONFIG_TRUE)
  18.351 +            b_info->u.hvm.pae = l;
  18.352 +        if (config_lookup_int (&config, "apic", &l) == CONFIG_TRUE)
  18.353 +            b_info->u.hvm.apic = l;
  18.354 +        if (config_lookup_int (&config, "acpi", &l) == CONFIG_TRUE)
  18.355 +            b_info->u.hvm.acpi = l;
  18.356 +        if (config_lookup_int (&config, "nx", &l) == CONFIG_TRUE)
  18.357 +            b_info->u.hvm.nx = l;
  18.358 +        if (config_lookup_int (&config, "viridian", &l) == CONFIG_TRUE)
  18.359 +            b_info->u.hvm.viridian = l;
  18.360 +    } else {
  18.361 +        if (config_lookup_string (&config, "cmdline", &buf) == CONFIG_TRUE)
  18.362 +            b_info->u.pv.cmdline = buf;
  18.363 +        if (config_lookup_string (&config, "ramdisk", &buf) == CONFIG_TRUE)
  18.364 +            b_info->u.pv.ramdisk = buf;
  18.365 +    }
  18.366 +
  18.367 +    if ((vbds = config_lookup (&config, "disk")) != NULL) {
  18.368 +        *num_disks = 0;
  18.369 +        *disks = NULL;
  18.370 +        while ((buf = config_setting_get_string_elem (vbds, *num_disks)) != NULL) {
  18.371 +            char *buf2 = strdup(buf);
  18.372 +            char *p, *p2;
  18.373 +            *disks = (libxl_device_disk *) realloc(*disks, sizeof (libxl_device_disk) * ((*num_disks) + 1));
  18.374 +            (*disks)[*num_disks].backend_domid = 0;
  18.375 +            (*disks)[*num_disks].domid = 0;
  18.376 +            (*disks)[*num_disks].unpluggable = 0;
  18.377 +            p = strtok(buf2, ",:");
  18.378 +            while (*p == ' ')
  18.379 +                p++;
  18.380 +            if (!strcmp(p, "phy")) {
  18.381 +                (*disks)[*num_disks].phystype = PHYSTYPE_PHY;
  18.382 +            } else if (!strcmp(p, "file")) {
  18.383 +                (*disks)[*num_disks].phystype = PHYSTYPE_FILE;
  18.384 +            } else if (!strcmp(p, "tap")) {
  18.385 +                p = strtok(NULL, ":");
  18.386 +                if (!strcmp(p, "aio")) {
  18.387 +                    (*disks)[*num_disks].phystype = PHYSTYPE_AIO;
  18.388 +                } else if (!strcmp(p, "vhd")) {
  18.389 +                    (*disks)[*num_disks].phystype = PHYSTYPE_VHD;
  18.390 +                } else if (!strcmp(p, "qcow")) {
  18.391 +                    (*disks)[*num_disks].phystype = PHYSTYPE_QCOW;
  18.392 +                } else if (!strcmp(p, "qcow2")) {
  18.393 +                    (*disks)[*num_disks].phystype = PHYSTYPE_QCOW2;
  18.394 +                }
  18.395 +            }
  18.396 +            p = strtok(NULL, ",");
  18.397 +            while (*p == ' ')
  18.398 +                p++;
  18.399 +            (*disks)[*num_disks].physpath= strdup(p);
  18.400 +            p = strtok(NULL, ",");
  18.401 +            while (*p == ' ')
  18.402 +                p++;
  18.403 +            p2 = strchr(p, ':');
  18.404 +            if (p2 == NULL) {
  18.405 +                (*disks)[*num_disks].virtpath = strdup(p);
  18.406 +                (*disks)[*num_disks].is_cdrom = 0;
  18.407 +            } else {
  18.408 +                *p2 = '\0';
  18.409 +                (*disks)[*num_disks].virtpath = strdup(p);
  18.410 +                if (!strcmp(p2 + 1, "cdrom"))
  18.411 +                    (*disks)[*num_disks].is_cdrom = 1;
  18.412 +                else
  18.413 +                    (*disks)[*num_disks].is_cdrom = 0;
  18.414 +            }
  18.415 +            p = strtok(NULL, ",");
  18.416 +            while (*p == ' ')
  18.417 +                p++;
  18.418 +            (*disks)[*num_disks].readwrite = (p[0] == 'w') ? 1 : 0;
  18.419 +            free(buf2);
  18.420 +            *num_disks = (*num_disks) + 1;
  18.421 +        }
  18.422 +    }
  18.423 +
  18.424 +    if ((nics = config_lookup (&config, "vif")) != NULL) {
  18.425 +        *num_vifs = 0;
  18.426 +        *vifs = NULL;
  18.427 +        while ((buf = config_setting_get_string_elem (nics, *num_vifs)) != NULL) {
  18.428 +            char *buf2 = strdup(buf);
  18.429 +            char *p, *p2;
  18.430 +            *vifs = (libxl_device_nic *) realloc(*vifs, sizeof (libxl_device_nic) * ((*num_vifs) + 1));
  18.431 +            init_nic_info((*vifs) + (*num_vifs), (*num_vifs) + 1);
  18.432 +            p = strtok(buf2, ",");
  18.433 +            if (!p)
  18.434 +                goto skip;
  18.435 +            do {
  18.436 +                while (*p == ' ')
  18.437 +                    p++;
  18.438 +                if ((p2 = strchr(p, '=')) == NULL)
  18.439 +                    break;
  18.440 +                *p2 = '\0';
  18.441 +                if (!strcmp(p, "model")) {
  18.442 +                    (*vifs)[*num_vifs].model = strdup(p2 + 1);
  18.443 +                } else if (!strcmp(p, "mac")) {
  18.444 +                    char *p3 = p2 + 1;
  18.445 +                    (*vifs)[*num_vifs].smac = strdup(p3);
  18.446 +                    *(p3 + 2) = '\0';
  18.447 +                    (*vifs)[*num_vifs].mac[0] = strtol(p3, NULL, 16);
  18.448 +                    p3 = p3 + 3;
  18.449 +                    *(p3 + 2) = '\0';
  18.450 +                    (*vifs)[*num_vifs].mac[1] = strtol(p3, NULL, 16);
  18.451 +                    p3 = p3 + 3;
  18.452 +                    *(p3 + 2) = '\0';
  18.453 +                    (*vifs)[*num_vifs].mac[2] = strtol(p3, NULL, 16);
  18.454 +                    p3 = p3 + 3;
  18.455 +                    *(p3 + 2) = '\0';
  18.456 +                    (*vifs)[*num_vifs].mac[3] = strtol(p3, NULL, 16);
  18.457 +                    p3 = p3 + 3;
  18.458 +                    *(p3 + 2) = '\0';
  18.459 +                    (*vifs)[*num_vifs].mac[4] = strtol(p3, NULL, 16);
  18.460 +                    p3 = p3 + 3;
  18.461 +                    *(p3 + 2) = '\0';
  18.462 +                    (*vifs)[*num_vifs].mac[5] = strtol(p3, NULL, 16);
  18.463 +                } else if (!strcmp(p, "bridge")) {
  18.464 +                    (*vifs)[*num_vifs].bridge = strdup(p2 + 1);
  18.465 +                } else if (!strcmp(p, "type")) {
  18.466 +                    if (!strcmp(p2 + 1, "ioemu"))
  18.467 +                        (*vifs)[*num_vifs].nictype = NICTYPE_IOEMU;
  18.468 +                    else
  18.469 +                        (*vifs)[*num_vifs].nictype = NICTYPE_VIF;
  18.470 +                } else if (!strcmp(p, "ip")) {
  18.471 +                    inet_pton(AF_INET, p2 + 1, &((*vifs)[*num_vifs].ip));
  18.472 +                } else if (!strcmp(p, "script")) {
  18.473 +                    (*vifs)[*num_vifs].script = strdup(p2 + 1);
  18.474 +                } else if (!strcmp(p, "vifname")) {
  18.475 +                    (*vifs)[*num_vifs].ifname = strdup(p2 + 1);
  18.476 +                } else if (!strcmp(p, "rate")) {
  18.477 +                    fprintf(stderr, "the rate parameter for vifs is currently not supported\n");
  18.478 +                } else if (!strcmp(p, "accel")) {
  18.479 +                    fprintf(stderr, "the accel parameter for vifs is currently not supported\n");
  18.480 +                }
  18.481 +            } while ((p = strtok(NULL, ",")) != NULL);
  18.482 +skip:
  18.483 +            free(buf2);
  18.484 +            *num_vifs = (*num_vifs) + 1;
  18.485 +        }
  18.486 +    }
  18.487 +
  18.488 +    /* init dm from c and b */
  18.489 +    init_dm_info(dm_info, c_info, b_info);
  18.490 +
  18.491 +    /* then process config related to dm */
  18.492 +    if (config_lookup_string (&config, "device_model", &buf) == CONFIG_TRUE)
  18.493 +        dm_info->device_model = strdup(buf);
  18.494 +    if (config_lookup_int (&config, "stdvga", &l) == CONFIG_TRUE)
  18.495 +        dm_info->stdvga = l;
  18.496 +    if (config_lookup_int (&config, "vnc", &l) == CONFIG_TRUE)
  18.497 +        dm_info->vnc = l;
  18.498 +    if (config_lookup_string (&config, "vnclisten", &buf) == CONFIG_TRUE)
  18.499 +        dm_info->vnclisten = strdup(buf);
  18.500 +    if (config_lookup_int (&config, "vncdisplay", &l) == CONFIG_TRUE)
  18.501 +        dm_info->vncdisplay = l;
  18.502 +    if (config_lookup_int (&config, "vncunused", &l) == CONFIG_TRUE)
  18.503 +        dm_info->vncunused = l;
  18.504 +    if (config_lookup_string (&config, "keymap", &buf) == CONFIG_TRUE)
  18.505 +        dm_info->keymap = strdup(buf);
  18.506 +    if (config_lookup_int (&config, "sdl", &l) == CONFIG_TRUE)
  18.507 +        dm_info->sdl = l;
  18.508 +    if (config_lookup_int (&config, "opengl", &l) == CONFIG_TRUE)
  18.509 +        dm_info->opengl = l;
  18.510 +    if (config_lookup_int (&config, "nographic", &l) == CONFIG_TRUE)
  18.511 +        dm_info->nographic = l;
  18.512 +    if (config_lookup_string (&config, "serial", &buf) == CONFIG_TRUE)
  18.513 +        dm_info->serial = strdup(buf);
  18.514 +    if (config_lookup_string (&config, "boot", &buf) == CONFIG_TRUE)
  18.515 +        dm_info->boot = strdup(buf);
  18.516 +    if (config_lookup_int (&config, "usb", &l) == CONFIG_TRUE)
  18.517 +        dm_info->usb = l;
  18.518 +    if (config_lookup_string (&config, "usbdevice", &buf) == CONFIG_TRUE)
  18.519 +        dm_info->usbdevice = strdup(buf);
  18.520 +
  18.521 +    config_destroy(&config);
  18.522 +}
  18.523 +
  18.524 +static void create_domain(int debug, const char *filename)
  18.525 +{
  18.526 +    struct libxl_ctx ctx;
  18.527 +    uint32_t domid;
  18.528 +    libxl_domain_create_info info1;
  18.529 +    libxl_domain_build_info info2;
  18.530 +    libxl_device_model_info dm_info;
  18.531 +    libxl_device_disk *disks = NULL;
  18.532 +    libxl_device_nic *vifs = NULL;
  18.533 +    int num_disks = 0, num_vifs = 0;
  18.534 +    int i;
  18.535 +
  18.536 +    printf("Parsing config file %s\n", filename);
  18.537 +    parse_config_file(filename, &info1, &info2, &disks, &num_disks, &vifs, &num_vifs, &dm_info);
  18.538 +    if (debug)
  18.539 +        printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, &dm_info);
  18.540 +
  18.541 +    libxl_ctx_init(&ctx);
  18.542 +    libxl_ctx_set_log(&ctx, log_callback, NULL);
  18.543 +    libxl_domain_make(&ctx, &info1, &domid);
  18.544 +    libxl_domain_build(&ctx, &info2, domid);
  18.545 +
  18.546 +    device_model_info_domid_fixup(&dm_info, domid);
  18.547 +
  18.548 +    for (i = 0; i < num_disks; i++) {
  18.549 +        disk_info_domid_fixup(disks + i, domid);
  18.550 +        libxl_device_disk_add(&ctx, domid, &disks[i]);
  18.551 +    }
  18.552 +    for (i = 0; i < num_vifs; i++) {
  18.553 +        nic_info_domid_fixup(vifs + i, domid);
  18.554 +        libxl_device_nic_add(&ctx, domid, &vifs[i]);
  18.555 +    }
  18.556 +    libxl_create_device_model(&ctx, &dm_info, vifs, num_vifs);
  18.557 +    libxl_domain_unpause(&ctx, domid);
  18.558 +
  18.559 +}
  18.560 +
  18.561 +static void help(char *command)
  18.562 +{
  18.563 +    if (!command || !strcmp(command, "help")) {
  18.564 +        printf("Usage xl <subcommand> [args]\n\n");
  18.565 +        printf("xl full list of subcommands:\n\n");
  18.566 +        printf(" create                                create a domain from config file <filename>\n\n");
  18.567 +        printf(" list                          list information about all domains\n\n");
  18.568 +        printf(" destroy                       terminate a domain immediately\n\n");
  18.569 +    } else if(!strcmp(command, "create")) {
  18.570 +        printf("Usage: xl create <ConfigFile> [options] [vars]\n\n");
  18.571 +        printf("Create a domain based on <ConfigFile>.\n\n");
  18.572 +        printf("Options:\n\n");
  18.573 +        printf("-h                     Print this help.\n");
  18.574 +        printf("-d                     Enable debug messages.\n");
  18.575 +    } else if(!strcmp(command, "list")) {
  18.576 +        printf("Usage: xl list [Domain]\n\n");
  18.577 +        printf("List information about all/some domains.\n\n");
  18.578 +    } else if(!strcmp(command, "destroy")) {
  18.579 +        printf("Usage: xl destroy <Domain>\n\n");
  18.580 +        printf("Terminate a domain immediately.\n\n");
  18.581 +    }
  18.582 +}
  18.583 +
  18.584 +void destroy_domain(char *p)
  18.585 +{
  18.586 +    struct libxl_ctx ctx;
  18.587 +    uint32_t domid;
  18.588 +
  18.589 +    libxl_ctx_init(&ctx);
  18.590 +    libxl_ctx_set_log(&ctx, log_callback, NULL);
  18.591 +
  18.592 +    if (libxl_param_to_domid(&ctx, p, &domid) < 0) {
  18.593 +        fprintf(stderr, "%s is an invalid domain identifier\n", p);
  18.594 +        exit(2);
  18.595 +    }
  18.596 +    libxl_domain_destroy(&ctx, domid, 0);
  18.597 +}
  18.598 +
  18.599 +void list_domains(void)
  18.600 +{
  18.601 +    struct libxl_ctx ctx;
  18.602 +    xc_dominfo_t *info;
  18.603 +    int nb_domain, i;
  18.604 +
  18.605 +    libxl_ctx_init(&ctx);
  18.606 +    libxl_ctx_set_log(&ctx, log_callback, NULL);
  18.607 +
  18.608 +    info = libxl_domain_infolist(&ctx, &nb_domain);
  18.609 +
  18.610 +    if (info < 0) {
  18.611 +        fprintf(stderr, "libxl_domain_infolist failed.\n");
  18.612 +        exit(1);
  18.613 +    }
  18.614 +    printf("Name                                        ID   Mem VCPUs\tState\tTime(s)\n");
  18.615 +    for (i = 0; i < nb_domain; i++) {
  18.616 +        printf("%-40s %5d %5lu %5d     %c%c%c%c%c%c %8.1f\n",
  18.617 +                libxl_domid_to_name(&ctx, info[i].domid),
  18.618 +                info[i].domid,
  18.619 +                info[i].nr_pages * XC_PAGE_SIZE/(1024*1024),
  18.620 +                info[i].nr_online_vcpus,
  18.621 +                info[i].running ? 'r' : '-',
  18.622 +                info[i].blocked ? 'b' : '-',
  18.623 +                info[i].paused ? 'p' : '-',
  18.624 +                info[i].shutdown ? 's' : '-',
  18.625 +                info[i].crashed ? 'c' : '-',
  18.626 +                info[i].dying ? 'd' : '-',
  18.627 +                ((float)info[i].cpu_time / 1e9));
  18.628 +    }
  18.629 +}
  18.630 +
  18.631 +int main_destroy(int argc, char **argv)
  18.632 +{
  18.633 +    int opt;
  18.634 +    char *p;
  18.635 +
  18.636 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  18.637 +        switch (opt) {
  18.638 +        case 'h':
  18.639 +            help("destroy");
  18.640 +            exit(0);
  18.641 +        default:
  18.642 +            fprintf(stderr, "option not supported\n");
  18.643 +            break;
  18.644 +        }
  18.645 +    }
  18.646 +    if (optind >= argc) {
  18.647 +        help("destroy");
  18.648 +        exit(2);
  18.649 +    }
  18.650 +
  18.651 +    p = argv[optind];
  18.652 +
  18.653 +    destroy_domain(p);
  18.654 +    exit(0);
  18.655 +}
  18.656 +
  18.657 +int main_list(int argc, char **argv)
  18.658 +{
  18.659 +    int opt;
  18.660 +
  18.661 +    while ((opt = getopt(argc, argv, "h")) != -1) {
  18.662 +        switch (opt) {
  18.663 +        case 'h':
  18.664 +            help("list");
  18.665 +            exit(0);
  18.666 +        default:
  18.667 +            fprintf(stderr, "option not supported\n");
  18.668 +            break;
  18.669 +        }
  18.670 +    }
  18.671 +
  18.672 +    list_domains();
  18.673 +    exit(0);
  18.674 +}
  18.675 +
  18.676 +int main_create(int argc, char **argv)
  18.677 +{
  18.678 +    char *filename = NULL;
  18.679 +    int debug = 0;
  18.680 +    int opt;
  18.681 +
  18.682 +    while ((opt = getopt(argc, argv, "hd")) != -1) {
  18.683 +        switch (opt) {
  18.684 +        case 'd':
  18.685 +            debug = 1;
  18.686 +            break;
  18.687 +        case 'h':
  18.688 +            help("create");
  18.689 +            exit(0);
  18.690 +        default:
  18.691 +            fprintf(stderr, "option not supported\n");
  18.692 +            break;
  18.693 +        }
  18.694 +    }
  18.695 +
  18.696 +    if (optind >= argc) {
  18.697 +        help("create");
  18.698 +        exit(2);
  18.699 +    }
  18.700 +
  18.701 +    filename = argv[optind];
  18.702 +    create_domain(debug, filename);
  18.703 +    exit(0);
  18.704 +}
  18.705 +
  18.706 +int main(int argc, char **argv)
  18.707 +{
  18.708 +    if (argc < 2) {
  18.709 +        help(NULL);
  18.710 +        exit(1);
  18.711 +    }
  18.712 +
  18.713 +    if (!strcmp(argv[1], "create")) {
  18.714 +        main_create(argc - 1, argv + 1);
  18.715 +    } else if (!strcmp(argv[1], "list")) {
  18.716 +        main_list(argc - 1, argv + 1);
  18.717 +    } else if (!strcmp(argv[1], "destroy")) {
  18.718 +        main_destroy(argc - 1, argv + 1);
  18.719 +    } else if (!strcmp(argv[1], "help")) {
  18.720 +        if (argc > 2)
  18.721 +            help(argv[2]);
  18.722 +        else
  18.723 +            help(NULL);
  18.724 +        exit(0);
  18.725 +    } else {
  18.726 +        fprintf(stderr, "command not implemented\n");
  18.727 +        exit(1);
  18.728 +    }
  18.729 +}
  18.730 +