debuggers.hg

changeset 22767:ca75ceb02221

libxl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()

These functions are introduced as the new way to create domains with libxl
they prevent the callers from need to know about low-level implementation
details such as:
- libxl_domain_make()
- libxl_domain_build()
- libxl_domain_restore()
- when to attach the console
- how to start the device model

Above mentioned functions and all API's for the device model, which are now
redundant, have been made internal to libxl and no longer accessible.

The ocaml binding for libxl has not been properly updated to reflect the
changes, wrappers for the old functions have been removed but the code to wrap
the new functions has not been added.

Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
author Gianni Tedesco <gianni.tedesco@citrix.com>
date Tue Jan 11 18:29:43 2011 +0000 (2011-01-11)
parents 5b8034ce8b8c
children 77e8775fccef
files tools/libxl/Makefile tools/libxl/libxl.c tools/libxl/libxl.h tools/libxl/libxl_create.c tools/libxl/libxl_dm.c tools/libxl/libxl_exec.c tools/libxl/libxl_internal.h tools/libxl/xl_cmdimpl.c tools/ocaml/libs/xl/xl_stubs.c
line diff
     1.1 --- a/tools/libxl/Makefile	Tue Jan 11 18:16:45 2011 +0000
     1.2 +++ b/tools/libxl/Makefile	Tue Jan 11 18:29:43 2011 +0000
     1.3 @@ -20,7 +20,7 @@ ifeq ($(CONFIG_Linux),y)
     1.4  LIBS += -luuid
     1.5  endif
     1.6  
     1.7 -LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o
     1.8 +LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o
     1.9  ifeq ($(LIBXL_BLKTAP),y)
    1.10  LIBXL_OBJS-y += libxl_blktap2.o
    1.11  else
    1.12 @@ -29,7 +29,9 @@ endif
    1.13  LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o
    1.14  LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o
    1.15  
    1.16 -LIBXL_OBJS = flexarray.o libxl.o libxl_dm.o libxl_pci.o libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
    1.17 +LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
    1.18 +			libxl_dom.o libxl_exec.o libxl_xshelp.o libxl_device.o \
    1.19 +			libxl_internal.o libxl_utils.o $(LIBXL_OBJS-y)
    1.20  LIBXL_OBJS += _libxl_types.o
    1.21  
    1.22  AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h
     2.1 --- a/tools/libxl/libxl.c	Tue Jan 11 18:16:45 2011 +0000
     2.2 +++ b/tools/libxl/libxl.c	Tue Jan 11 18:29:43 2011 +0000
     2.3 @@ -104,114 +104,6 @@ void libxl_key_value_list_destroy(libxl_
     2.4  
     2.5  /******************************************************************************/
     2.6  
     2.7 -int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
     2.8 -                       uint32_t *domid)
     2.9 -{
    2.10 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
    2.11 -    int flags, ret, i, rc;
    2.12 -    char *uuid_string;
    2.13 -    char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
    2.14 -    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
    2.15 -                         "control", "attr", "messages" };
    2.16 -    char *dom_path, *vm_path;
    2.17 -    struct xs_permissions roperm[2];
    2.18 -    struct xs_permissions rwperm[1];
    2.19 -    xs_transaction_t t;
    2.20 -    xen_domain_handle_t handle;
    2.21 -
    2.22 -    uuid_string = libxl__uuid2string(&gc, info->uuid);
    2.23 -    if (!uuid_string) {
    2.24 -        libxl__free_all(&gc);
    2.25 -        return ERROR_NOMEM;
    2.26 -    }
    2.27 -
    2.28 -    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
    2.29 -    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
    2.30 -    flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off;
    2.31 -    *domid = -1;
    2.32 -
    2.33 -    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
    2.34 -    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
    2.35 -
    2.36 -    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
    2.37 -    if (ret < 0) {
    2.38 -        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail");
    2.39 -        libxl__free_all(&gc);
    2.40 -        return ERROR_FAIL;
    2.41 -    }
    2.42 -
    2.43 -    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
    2.44 -    if (ret < 0) {
    2.45 -        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
    2.46 -        libxl__free_all(&gc);
    2.47 -        return ERROR_FAIL;
    2.48 -    }
    2.49 -
    2.50 -    dom_path = libxl__xs_get_dompath(&gc, *domid);
    2.51 -    if (!dom_path) {
    2.52 -        libxl__free_all(&gc);
    2.53 -        return ERROR_FAIL;
    2.54 -    }
    2.55 -
    2.56 -    vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string);
    2.57 -    if (!vm_path) {
    2.58 -        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
    2.59 -        libxl__free_all(&gc);
    2.60 -        return ERROR_FAIL;
    2.61 -    }
    2.62 -
    2.63 -    roperm[0].id = 0;
    2.64 -    roperm[0].perms = XS_PERM_NONE;
    2.65 -    roperm[1].id = *domid;
    2.66 -    roperm[1].perms = XS_PERM_READ;
    2.67 -    rwperm[0].id = *domid;
    2.68 -    rwperm[0].perms = XS_PERM_NONE;
    2.69 -
    2.70 -retry_transaction:
    2.71 -    t = xs_transaction_start(ctx->xsh);
    2.72 -    xs_rm(ctx->xsh, t, dom_path);
    2.73 -    xs_mkdir(ctx->xsh, t, dom_path);
    2.74 -    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
    2.75 -
    2.76 -    xs_rm(ctx->xsh, t, vm_path);
    2.77 -    xs_mkdir(ctx->xsh, t, vm_path);
    2.78 -    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
    2.79 -
    2.80 -    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path));
    2.81 -    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
    2.82 -    if (rc) {
    2.83 -        libxl__free_all(&gc);
    2.84 -        return rc;
    2.85 -    }
    2.86 -
    2.87 -    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
    2.88 -        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
    2.89 -        xs_mkdir(ctx->xsh, t, path);
    2.90 -        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
    2.91 -    }
    2.92 -    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
    2.93 -        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
    2.94 -        xs_mkdir(ctx->xsh, t, path);
    2.95 -        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
    2.96 -    }
    2.97 -
    2.98 -    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
    2.99 -    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name));
   2.100 -    if (info->poolname)
   2.101 -        xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname));
   2.102 -
   2.103 -    libxl__xs_writev(&gc, t, dom_path, info->xsdata);
   2.104 -    libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata);
   2.105 -
   2.106 -    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
   2.107 -
   2.108 -    if (!xs_transaction_end(ctx->xsh, t, 0))
   2.109 -        if (errno == EAGAIN)
   2.110 -            goto retry_transaction;
   2.111 -
   2.112 -    libxl__free_all(&gc);
   2.113 -    return 0;
   2.114 -}
   2.115  
   2.116  int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid,
   2.117                          const char *old_name, const char *new_name,
   2.118 @@ -293,141 +185,6 @@ int libxl_domain_rename(libxl_ctx *ctx, 
   2.119   x_nomem: rc = ERROR_NOMEM; goto x_rc;
   2.120  }
   2.121  
   2.122 -int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state)
   2.123 -{
   2.124 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.125 -    char **vments = NULL, **localents = NULL;
   2.126 -    struct timeval start_time;
   2.127 -    int i, ret;
   2.128 -
   2.129 -    ret = libxl__build_pre(ctx, domid, info, state);
   2.130 -    if (ret)
   2.131 -        goto out;
   2.132 -
   2.133 -    gettimeofday(&start_time, NULL);
   2.134 -
   2.135 -    if (info->hvm) {
   2.136 -        ret = libxl__build_hvm(ctx, domid, info, state);
   2.137 -        if (ret)
   2.138 -            goto out;
   2.139 -
   2.140 -        vments = libxl__calloc(&gc, 7, sizeof(char *));
   2.141 -        vments[0] = "rtc/timeoffset";
   2.142 -        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
   2.143 -        vments[2] = "image/ostype";
   2.144 -        vments[3] = "hvm";
   2.145 -        vments[4] = "start_time";
   2.146 -        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   2.147 -    } else {
   2.148 -        ret = libxl__build_pv(ctx, domid, info, state);
   2.149 -        if (ret)
   2.150 -            goto out;
   2.151 -
   2.152 -        vments = libxl__calloc(&gc, 11, sizeof(char *));
   2.153 -        i = 0;
   2.154 -        vments[i++] = "image/ostype";
   2.155 -        vments[i++] = "linux";
   2.156 -        vments[i++] = "image/kernel";
   2.157 -        vments[i++] = (char*) info->kernel.path;
   2.158 -        vments[i++] = "start_time";
   2.159 -        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   2.160 -        if (info->u.pv.ramdisk.path) {
   2.161 -            vments[i++] = "image/ramdisk";
   2.162 -            vments[i++] = (char*) info->u.pv.ramdisk.path;
   2.163 -        }
   2.164 -        if (info->u.pv.cmdline) {
   2.165 -            vments[i++] = "image/cmdline";
   2.166 -            vments[i++] = (char*) info->u.pv.cmdline;
   2.167 -        }
   2.168 -    }
   2.169 -    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
   2.170 -out:
   2.171 -    libxl__file_reference_unmap(&info->kernel);
   2.172 -    if (!info->hvm)
   2.173 -	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
   2.174 -
   2.175 -    libxl__free_all(&gc);
   2.176 -    return ret;
   2.177 -}
   2.178 -
   2.179 -int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
   2.180 -                         uint32_t domid, int fd, libxl_domain_build_state *state,
   2.181 -                         libxl_device_model_info *dm_info)
   2.182 -{
   2.183 -    libxl__gc gc = LIBXL_INIT_GC(ctx);
   2.184 -    char **vments = NULL, **localents = NULL;
   2.185 -    struct timeval start_time;
   2.186 -    int i, ret, esave, flags;
   2.187 -
   2.188 -    ret = libxl__build_pre(ctx, domid, info, state);
   2.189 -    if (ret)
   2.190 -        goto out;
   2.191 -
   2.192 -    ret = libxl__domain_restore_common(ctx, domid, info, state, fd);
   2.193 -    if (ret)
   2.194 -        goto out;
   2.195 -
   2.196 -    gettimeofday(&start_time, NULL);
   2.197 -
   2.198 -    if (info->hvm) {
   2.199 -        vments = libxl__calloc(&gc, 7, sizeof(char *));
   2.200 -        vments[0] = "rtc/timeoffset";
   2.201 -        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
   2.202 -        vments[2] = "image/ostype";
   2.203 -        vments[3] = "hvm";
   2.204 -        vments[4] = "start_time";
   2.205 -        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   2.206 -    } else {
   2.207 -        vments = libxl__calloc(&gc, 11, sizeof(char *));
   2.208 -        i = 0;
   2.209 -        vments[i++] = "image/ostype";
   2.210 -        vments[i++] = "linux";
   2.211 -        vments[i++] = "image/kernel";
   2.212 -        vments[i++] = (char*) info->kernel.path;
   2.213 -        vments[i++] = "start_time";
   2.214 -        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   2.215 -        if (info->u.pv.ramdisk.path) {
   2.216 -            vments[i++] = "image/ramdisk";
   2.217 -            vments[i++] = (char*) info->u.pv.ramdisk.path;
   2.218 -        }
   2.219 -        if (info->u.pv.cmdline) {
   2.220 -            vments[i++] = "image/cmdline";
   2.221 -            vments[i++] = (char*) info->u.pv.cmdline;
   2.222 -        }
   2.223 -    }
   2.224 -    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
   2.225 -    if (ret)
   2.226 -        goto out;
   2.227 -
   2.228 -    dm_info->saved_state = NULL;
   2.229 -    if (info->hvm) {
   2.230 -        ret = asprintf(&dm_info->saved_state,
   2.231 -                       "/var/lib/xen/qemu-save.%d", domid);
   2.232 -        ret = (ret < 0) ? ERROR_FAIL : 0;
   2.233 -    }
   2.234 -
   2.235 -out:
   2.236 -    libxl__file_reference_unmap(&info->kernel);
   2.237 -    if (!info->hvm)
   2.238 -	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
   2.239 -
   2.240 -    esave = errno;
   2.241 -
   2.242 -    flags = fcntl(fd, F_GETFL);
   2.243 -    if (flags == -1) {
   2.244 -        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd");
   2.245 -    } else {
   2.246 -        flags &= ~O_NONBLOCK;
   2.247 -        if (fcntl(fd, F_SETFL, flags) == -1)
   2.248 -            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd"
   2.249 -                         " back to blocking mode");
   2.250 -    }
   2.251 -
   2.252 -    errno = esave;
   2.253 -    libxl__free_all(&gc);
   2.254 -    return ret;
   2.255 -}
   2.256 -
   2.257  int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid)
   2.258  {
   2.259      libxl__gc gc = LIBXL_INIT_GC(ctx);
     3.1 --- a/tools/libxl/libxl.h	Tue Jan 11 18:16:45 2011 +0000
     3.2 +++ b/tools/libxl/libxl.h	Tue Jan 11 18:29:43 2011 +0000
     3.3 @@ -241,6 +241,38 @@ enum {
     3.4  
     3.5  #define LIBXL_VERSION 0
     3.6  
     3.7 +enum libxl_action_on_shutdown {
     3.8 +    LIBXL_ACTION_DESTROY,
     3.9 +
    3.10 +    LIBXL_ACTION_RESTART,
    3.11 +    LIBXL_ACTION_RESTART_RENAME,
    3.12 +
    3.13 +    LIBXL_ACTION_PRESERVE,
    3.14 +
    3.15 +    LIBXL_ACTION_COREDUMP_DESTROY,
    3.16 +    LIBXL_ACTION_COREDUMP_RESTART,
    3.17 +};
    3.18 +
    3.19 +typedef struct {
    3.20 +    libxl_domain_create_info c_info;
    3.21 +    libxl_domain_build_info b_info;
    3.22 +    libxl_device_model_info dm_info;
    3.23 +
    3.24 +    int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
    3.25 +
    3.26 +    libxl_device_disk *disks;
    3.27 +    libxl_device_nic *vifs;
    3.28 +    libxl_device_net2 *vif2s;
    3.29 +    libxl_device_pci *pcidevs;
    3.30 +    libxl_device_vfb *vfbs;
    3.31 +    libxl_device_vkb *vkbs;
    3.32 +
    3.33 +    enum libxl_action_on_shutdown on_poweroff;
    3.34 +    enum libxl_action_on_shutdown on_reboot;
    3.35 +    enum libxl_action_on_shutdown on_watchdog;
    3.36 +    enum libxl_action_on_shutdown on_crash;
    3.37 +} libxl_domain_config;
    3.38 +
    3.39  /* context functions */
    3.40  int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*);
    3.41  int libxl_ctx_free(libxl_ctx *ctx);
    3.42 @@ -248,11 +280,10 @@ int libxl_ctx_set_log(libxl_ctx *ctx, xe
    3.43  int libxl_ctx_postfork(libxl_ctx *ctx);
    3.44  
    3.45  /* domain related functions */
    3.46 -int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid);
    3.47 -int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state);
    3.48 -int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
    3.49 -                         uint32_t domid, int fd, libxl_domain_build_state *state,
    3.50 -                         libxl_device_model_info *dm_info);
    3.51 +typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
    3.52 +int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid);
    3.53 +int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd);
    3.54 +void libxl_domain_config_destroy(libxl_domain_config *d_config);
    3.55  int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
    3.56                            uint32_t domid, int fd);
    3.57  int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid);
    3.58 @@ -375,27 +406,6 @@ libxl_dominfo * libxl_list_domain(libxl_
    3.59  libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool);
    3.60  libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm);
    3.61  
    3.62 -typedef struct libxl__device_model_starting libxl_device_model_starting;
    3.63 -int libxl_create_device_model(libxl_ctx *ctx,
    3.64 -                              libxl_device_model_info *info,
    3.65 -                              libxl_device_disk *disk, int num_disks,
    3.66 -                              libxl_device_nic *vifs, int num_vifs,
    3.67 -                              libxl_device_model_starting **starting_r);
    3.68 -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
    3.69 -                            libxl_device_model_starting **starting_r);
    3.70 -int libxl_need_xenpv_qemu(libxl_ctx *ctx,
    3.71 -        int nr_consoles, libxl_device_console *consoles,
    3.72 -        int nr_vfbs, libxl_device_vfb *vfbs,
    3.73 -        int nr_disks, libxl_device_disk *disks);
    3.74 -  /* Caller must either: pass starting_r==0, or on successful
    3.75 -   * return pass *starting_r (which will be non-0) to
    3.76 -   * libxl_confirm_device_model or libxl_detach_device_model. */
    3.77 -int libxl_confirm_device_model_startup(libxl_ctx *ctx,
    3.78 -                              libxl_device_model_starting *starting);
    3.79 -int libxl_detach_device_model(libxl_ctx *ctx,
    3.80 -                              libxl_device_model_starting *starting);
    3.81 -  /* DM is detached even if error is returned */
    3.82 -
    3.83  int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk);
    3.84  int libxl_device_disk_del(libxl_ctx *ctx, libxl_device_disk *disk, int wait);
    3.85  libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/libxl/libxl_create.c	Tue Jan 11 18:29:43 2011 +0000
     4.3 @@ -0,0 +1,482 @@
     4.4 +/*
     4.5 + * Copyright (C) 2010      Citrix Ltd.
     4.6 + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
     4.7 + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com>
     4.8 + * Author Gianni Tedesco <gianni.tedesco@citrix.com>
     4.9 + *
    4.10 + * This program is free software; you can redistribute it and/or modify
    4.11 + * it under the terms of the GNU Lesser General Public License as published
    4.12 + * by the Free Software Foundation; version 2.1 only. with the special
    4.13 + * exception on linking described in file LICENSE.
    4.14 + *
    4.15 + * This program is distributed in the hope that it will be useful,
    4.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.18 + * GNU Lesser General Public License for more details.
    4.19 + */
    4.20 +
    4.21 +#include "libxl_osdeps.h"
    4.22 +
    4.23 +#include <stdio.h>
    4.24 +#include <string.h>
    4.25 +#include <stdlib.h>
    4.26 +#include <unistd.h>
    4.27 +#include <fcntl.h>
    4.28 +#include "libxl.h"
    4.29 +#include "libxl_utils.h"
    4.30 +#include "libxl_internal.h"
    4.31 +#include "flexarray.h"
    4.32 +
    4.33 +void libxl_domain_config_destroy(libxl_domain_config *d_config)
    4.34 +{
    4.35 +    int i;
    4.36 +
    4.37 +    for (i=0; i<d_config->num_disks; i++)
    4.38 +        libxl_device_disk_destroy(&d_config->disks[i]);
    4.39 +    free(d_config->disks);
    4.40 +
    4.41 +    for (i=0; i<d_config->num_vifs; i++)
    4.42 +        libxl_device_nic_destroy(&d_config->vifs[i]);
    4.43 +    free(d_config->vifs);
    4.44 +
    4.45 +    for (i=0; i<d_config->num_vif2s; i++)
    4.46 +        libxl_device_net2_destroy(&d_config->vif2s[i]);
    4.47 +    free(d_config->vif2s);
    4.48 +
    4.49 +    for (i=0; i<d_config->num_pcidevs; i++)
    4.50 +        libxl_device_pci_destroy(&d_config->pcidevs[i]);
    4.51 +    free(d_config->pcidevs);
    4.52 +
    4.53 +    for (i=0; i<d_config->num_vfbs; i++)
    4.54 +        libxl_device_vfb_destroy(&d_config->vfbs[i]);
    4.55 +    free(d_config->vfbs);
    4.56 +
    4.57 +    for (i=0; i<d_config->num_vkbs; i++)
    4.58 +        libxl_device_vkb_destroy(&d_config->vkbs[i]);
    4.59 +    free(d_config->vkbs);
    4.60 +
    4.61 +    libxl_domain_create_info_destroy(&d_config->c_info);
    4.62 +    libxl_domain_build_info_destroy(&d_config->b_info);
    4.63 +    libxl_device_model_info_destroy(&d_config->dm_info);
    4.64 +}
    4.65 +
    4.66 +static int init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state)
    4.67 +{
    4.68 +    memset(console, 0x00, sizeof(libxl_device_console));
    4.69 +    console->devid = dev_num;
    4.70 +    console->consback = LIBXL_CONSBACK_XENCONSOLED;
    4.71 +    console->output = strdup("pty");
    4.72 +    if ( NULL == console->output )
    4.73 +        return ERROR_NOMEM;
    4.74 +    if (state)
    4.75 +        console->build_state = state;
    4.76 +    return 0;
    4.77 +}
    4.78 +
    4.79 +int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state)
    4.80 +{
    4.81 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
    4.82 +    char **vments = NULL, **localents = NULL;
    4.83 +    struct timeval start_time;
    4.84 +    int i, ret;
    4.85 +
    4.86 +    ret = libxl__build_pre(ctx, domid, info, state);
    4.87 +    if (ret)
    4.88 +        goto out;
    4.89 +
    4.90 +    gettimeofday(&start_time, NULL);
    4.91 +
    4.92 +    if (info->hvm) {
    4.93 +        ret = libxl__build_hvm(ctx, domid, info, state);
    4.94 +        if (ret)
    4.95 +            goto out;
    4.96 +
    4.97 +        vments = libxl__calloc(&gc, 7, sizeof(char *));
    4.98 +        vments[0] = "rtc/timeoffset";
    4.99 +        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
   4.100 +        vments[2] = "image/ostype";
   4.101 +        vments[3] = "hvm";
   4.102 +        vments[4] = "start_time";
   4.103 +        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   4.104 +    } else {
   4.105 +        ret = libxl__build_pv(ctx, domid, info, state);
   4.106 +        if (ret)
   4.107 +            goto out;
   4.108 +
   4.109 +        vments = libxl__calloc(&gc, 11, sizeof(char *));
   4.110 +        i = 0;
   4.111 +        vments[i++] = "image/ostype";
   4.112 +        vments[i++] = "linux";
   4.113 +        vments[i++] = "image/kernel";
   4.114 +        vments[i++] = (char*) info->kernel.path;
   4.115 +        vments[i++] = "start_time";
   4.116 +        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   4.117 +        if (info->u.pv.ramdisk.path) {
   4.118 +            vments[i++] = "image/ramdisk";
   4.119 +            vments[i++] = (char*) info->u.pv.ramdisk.path;
   4.120 +        }
   4.121 +        if (info->u.pv.cmdline) {
   4.122 +            vments[i++] = "image/cmdline";
   4.123 +            vments[i++] = (char*) info->u.pv.cmdline;
   4.124 +        }
   4.125 +    }
   4.126 +    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
   4.127 +out:
   4.128 +    libxl__file_reference_unmap(&info->kernel);
   4.129 +    if (!info->hvm)
   4.130 +	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
   4.131 +
   4.132 +    libxl__free_all(&gc);
   4.133 +    return ret;
   4.134 +}
   4.135 +
   4.136 +static int domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info,
   4.137 +                         uint32_t domid, int fd, libxl_domain_build_state *state,
   4.138 +                         libxl_device_model_info *dm_info)
   4.139 +{
   4.140 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   4.141 +    char **vments = NULL, **localents = NULL;
   4.142 +    struct timeval start_time;
   4.143 +    int i, ret, esave, flags;
   4.144 +
   4.145 +    ret = libxl__build_pre(ctx, domid, info, state);
   4.146 +    if (ret)
   4.147 +        goto out;
   4.148 +
   4.149 +    ret = libxl__domain_restore_common(ctx, domid, info, state, fd);
   4.150 +    if (ret)
   4.151 +        goto out;
   4.152 +
   4.153 +    gettimeofday(&start_time, NULL);
   4.154 +
   4.155 +    if (info->hvm) {
   4.156 +        vments = libxl__calloc(&gc, 7, sizeof(char *));
   4.157 +        vments[0] = "rtc/timeoffset";
   4.158 +        vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
   4.159 +        vments[2] = "image/ostype";
   4.160 +        vments[3] = "hvm";
   4.161 +        vments[4] = "start_time";
   4.162 +        vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   4.163 +    } else {
   4.164 +        vments = libxl__calloc(&gc, 11, sizeof(char *));
   4.165 +        i = 0;
   4.166 +        vments[i++] = "image/ostype";
   4.167 +        vments[i++] = "linux";
   4.168 +        vments[i++] = "image/kernel";
   4.169 +        vments[i++] = (char*) info->kernel.path;
   4.170 +        vments[i++] = "start_time";
   4.171 +        vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
   4.172 +        if (info->u.pv.ramdisk.path) {
   4.173 +            vments[i++] = "image/ramdisk";
   4.174 +            vments[i++] = (char*) info->u.pv.ramdisk.path;
   4.175 +        }
   4.176 +        if (info->u.pv.cmdline) {
   4.177 +            vments[i++] = "image/cmdline";
   4.178 +            vments[i++] = (char*) info->u.pv.cmdline;
   4.179 +        }
   4.180 +    }
   4.181 +    ret = libxl__build_post(ctx, domid, info, state, vments, localents);
   4.182 +    if (ret)
   4.183 +        goto out;
   4.184 +
   4.185 +    dm_info->saved_state = NULL;
   4.186 +    if (info->hvm) {
   4.187 +        ret = asprintf(&dm_info->saved_state,
   4.188 +                       "/var/lib/xen/qemu-save.%d", domid);
   4.189 +        ret = (ret < 0) ? ERROR_FAIL : 0;
   4.190 +    }
   4.191 +
   4.192 +out:
   4.193 +    libxl__file_reference_unmap(&info->kernel);
   4.194 +    if (!info->hvm)
   4.195 +	    libxl__file_reference_unmap(&info->u.pv.ramdisk);
   4.196 +
   4.197 +    esave = errno;
   4.198 +
   4.199 +    flags = fcntl(fd, F_GETFL);
   4.200 +    if (flags == -1) {
   4.201 +        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd");
   4.202 +    } else {
   4.203 +        flags &= ~O_NONBLOCK;
   4.204 +        if (fcntl(fd, F_SETFL, flags) == -1)
   4.205 +            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd"
   4.206 +                         " back to blocking mode");
   4.207 +    }
   4.208 +
   4.209 +    errno = esave;
   4.210 +    libxl__free_all(&gc);
   4.211 +    return ret;
   4.212 +}
   4.213 +
   4.214 +int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
   4.215 +                       uint32_t *domid)
   4.216 +{
   4.217 +    libxl__gc gc = LIBXL_INIT_GC(ctx);
   4.218 +    int flags, ret, i, rc;
   4.219 +    char *uuid_string;
   4.220 +    char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
   4.221 +    char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers",
   4.222 +                         "control", "attr", "messages" };
   4.223 +    char *dom_path, *vm_path;
   4.224 +    struct xs_permissions roperm[2];
   4.225 +    struct xs_permissions rwperm[1];
   4.226 +    xs_transaction_t t;
   4.227 +    xen_domain_handle_t handle;
   4.228 +
   4.229 +    uuid_string = libxl__uuid2string(&gc, info->uuid);
   4.230 +    if (!uuid_string) {
   4.231 +        libxl__free_all(&gc);
   4.232 +        return ERROR_NOMEM;
   4.233 +    }
   4.234 +
   4.235 +    flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
   4.236 +    flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
   4.237 +    flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off;
   4.238 +    *domid = -1;
   4.239 +
   4.240 +    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
   4.241 +    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);
   4.242 +
   4.243 +    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
   4.244 +    if (ret < 0) {
   4.245 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail");
   4.246 +        libxl__free_all(&gc);
   4.247 +        return ERROR_FAIL;
   4.248 +    }
   4.249 +
   4.250 +    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
   4.251 +    if (ret < 0) {
   4.252 +        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
   4.253 +        libxl__free_all(&gc);
   4.254 +        return ERROR_FAIL;
   4.255 +    }
   4.256 +
   4.257 +    dom_path = libxl__xs_get_dompath(&gc, *domid);
   4.258 +    if (!dom_path) {
   4.259 +        libxl__free_all(&gc);
   4.260 +        return ERROR_FAIL;
   4.261 +    }
   4.262 +
   4.263 +    vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string);
   4.264 +    if (!vm_path) {
   4.265 +        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
   4.266 +        libxl__free_all(&gc);
   4.267 +        return ERROR_FAIL;
   4.268 +    }
   4.269 +
   4.270 +    roperm[0].id = 0;
   4.271 +    roperm[0].perms = XS_PERM_NONE;
   4.272 +    roperm[1].id = *domid;
   4.273 +    roperm[1].perms = XS_PERM_READ;
   4.274 +    rwperm[0].id = *domid;
   4.275 +    rwperm[0].perms = XS_PERM_NONE;
   4.276 +
   4.277 +retry_transaction:
   4.278 +    t = xs_transaction_start(ctx->xsh);
   4.279 +    xs_rm(ctx->xsh, t, dom_path);
   4.280 +    xs_mkdir(ctx->xsh, t, dom_path);
   4.281 +    xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm));
   4.282 +
   4.283 +    xs_rm(ctx->xsh, t, vm_path);
   4.284 +    xs_mkdir(ctx->xsh, t, vm_path);
   4.285 +    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
   4.286 +
   4.287 +    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path));
   4.288 +    rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
   4.289 +    if (rc) {
   4.290 +        libxl__free_all(&gc);
   4.291 +        return rc;
   4.292 +    }
   4.293 +
   4.294 +    for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
   4.295 +        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
   4.296 +        xs_mkdir(ctx->xsh, t, path);
   4.297 +        xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
   4.298 +    }
   4.299 +    for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
   4.300 +        char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
   4.301 +        xs_mkdir(ctx->xsh, t, path);
   4.302 +        xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
   4.303 +    }
   4.304 +
   4.305 +    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
   4.306 +    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name));
   4.307 +    if (info->poolname)
   4.308 +        xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname));
   4.309 +
   4.310 +    libxl__xs_writev(&gc, t, dom_path, info->xsdata);
   4.311 +    libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata);
   4.312 +
   4.313 +    xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
   4.314 +    if (!xs_transaction_end(ctx->xsh, t, 0))
   4.315 +        if (errno == EAGAIN)
   4.316 +            goto retry_transaction;
   4.317 +
   4.318 +    libxl__free_all(&gc);
   4.319 +    return 0;
   4.320 +}
   4.321 +
   4.322 +static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config,
   4.323 +                            libxl_console_ready cb, void *priv,
   4.324 +                            uint32_t *domid_out, int restore_fd)
   4.325 +{
   4.326 +    libxl__device_model_starting *dm_starting = 0;
   4.327 +    libxl_device_model_info *dm_info = &d_config->dm_info;
   4.328 +    libxl_domain_build_state state;
   4.329 +    uint32_t domid;
   4.330 +    int i, ret;
   4.331 +
   4.332 +    domid = 0;
   4.333 +
   4.334 +    ret = libxl__domain_make(ctx, &d_config->c_info, &domid);
   4.335 +    if (ret) {
   4.336 +        fprintf(stderr, "cannot make domain: %d\n", ret);
   4.337 +        ret = ERROR_FAIL;
   4.338 +        goto error_out;
   4.339 +    }
   4.340 +
   4.341 +    if ( !d_config->c_info.hvm && cb ) {
   4.342 +        if ( (*cb)(ctx, domid, priv) )
   4.343 +            goto error_out;
   4.344 +    }
   4.345 +
   4.346 +    if ( restore_fd < 0 ) {
   4.347 +        ret = libxl_run_bootloader(ctx, &d_config->b_info, d_config->num_disks > 0 ? &d_config->disks[0] : NULL, domid);
   4.348 +        if (ret) {
   4.349 +            fprintf(stderr, "failed to run bootloader: %d\n", ret);
   4.350 +            goto error_out;
   4.351 +        }
   4.352 +    }
   4.353 +
   4.354 +    if ( restore_fd >= 0 ) {
   4.355 +        ret = domain_restore(ctx, &d_config->b_info, domid, restore_fd, &state, dm_info);
   4.356 +    } else {
   4.357 +        if (dm_info->saved_state) {
   4.358 +            free(dm_info->saved_state);
   4.359 +            dm_info->saved_state = NULL;
   4.360 +        }
   4.361 +        ret = libxl__domain_build(ctx, &d_config->b_info, domid, &state);
   4.362 +    }
   4.363 +
   4.364 +    if (ret) {
   4.365 +        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
   4.366 +        ret = ERROR_FAIL;
   4.367 +        goto error_out;
   4.368 +    }
   4.369 +
   4.370 +    for (i = 0; i < d_config->num_disks; i++) {
   4.371 +        d_config->disks[i].domid = domid;
   4.372 +        ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]);
   4.373 +        if (ret) {
   4.374 +            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
   4.375 +            ret = ERROR_FAIL;
   4.376 +            goto error_out;
   4.377 +        }
   4.378 +    }
   4.379 +    for (i = 0; i < d_config->num_vifs; i++) {
   4.380 +        d_config->vifs[i].domid = domid;
   4.381 +        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]);
   4.382 +        if (ret) {
   4.383 +            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
   4.384 +            ret = ERROR_FAIL;
   4.385 +            goto error_out;
   4.386 +        }
   4.387 +    }
   4.388 +    if (!d_config->c_info.hvm) {
   4.389 +        for (i = 0; i < d_config->num_vif2s; i++) {
   4.390 +            d_config->vif2s[i].domid = domid;
   4.391 +            ret = libxl_device_net2_add(ctx, domid, &d_config->vif2s[i]);
   4.392 +            if (ret) {
   4.393 +                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
   4.394 +                ret = ERROR_FAIL;
   4.395 +                goto error_out;
   4.396 +            }
   4.397 +        }
   4.398 +    }
   4.399 +    if (d_config->c_info.hvm) {
   4.400 +        libxl_device_console console;
   4.401 +
   4.402 +        ret = init_console_info(&console, 0, &state);
   4.403 +        if ( ret )
   4.404 +            goto error_out;
   4.405 +        console.domid = domid;
   4.406 +        libxl_device_console_add(ctx, domid, &console);
   4.407 +        libxl_device_console_destroy(&console);
   4.408 +
   4.409 +        dm_info->domid = domid;
   4.410 +        ret = libxl__create_device_model(ctx, dm_info,
   4.411 +                                        d_config->disks, d_config->num_disks,
   4.412 +                                        d_config->vifs, d_config->num_vifs,
   4.413 +                                        &dm_starting);
   4.414 +        if (ret < 0) {
   4.415 +            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__create_device_model\n",
   4.416 +                    __FILE__,__LINE__, ret);
   4.417 +            goto error_out;
   4.418 +        }
   4.419 +    } else {
   4.420 +        int need_qemu = 0;
   4.421 +        libxl_device_console console;
   4.422 +
   4.423 +        for (i = 0; i < d_config->num_vfbs; i++) {
   4.424 +            d_config->vfbs[i].domid = domid;
   4.425 +            libxl_device_vfb_add(ctx, domid, &d_config->vfbs[i]);
   4.426 +            d_config->vkbs[i].domid = domid;
   4.427 +            libxl_device_vkb_add(ctx, domid, &d_config->vkbs[i]);
   4.428 +        }
   4.429 +
   4.430 +        ret = init_console_info(&console, 0, &state);
   4.431 +        if ( ret )
   4.432 +            goto error_out;
   4.433 +        console.domid = domid;
   4.434 +
   4.435 +        need_qemu = libxl__need_xenpv_qemu(ctx, 1, &console,
   4.436 +                d_config->num_vfbs, d_config->vfbs,
   4.437 +                d_config->num_disks, &d_config->disks[0]);
   4.438 +
   4.439 +        if (need_qemu)
   4.440 +             console.consback = LIBXL_CONSBACK_IOEMU;
   4.441 +
   4.442 +        libxl_device_console_add(ctx, domid, &console);
   4.443 +        libxl_device_console_destroy(&console);
   4.444 +
   4.445 +        if (need_qemu)
   4.446 +            libxl__create_xenpv_qemu(ctx, domid, d_config->vfbs, &dm_starting);
   4.447 +    }
   4.448 +
   4.449 +    if (dm_starting) {
   4.450 +        ret = libxl__confirm_device_model_startup(ctx, dm_starting);
   4.451 +        if (ret < 0) {
   4.452 +            fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__confirm_device_model_startup\n",
   4.453 +                    __FILE__,__LINE__, ret);
   4.454 +            goto error_out;
   4.455 +        }
   4.456 +    }
   4.457 +
   4.458 +    for (i = 0; i < d_config->num_pcidevs; i++)
   4.459 +        libxl_device_pci_add(ctx, domid, &d_config->pcidevs[i]);
   4.460 +
   4.461 +    if ( d_config->c_info.hvm && cb ) {
   4.462 +        if ( (*cb)(ctx, domid, priv) )
   4.463 +            goto error_out;
   4.464 +    }
   4.465 +
   4.466 +    *domid_out = domid;
   4.467 +    return 0;
   4.468 +
   4.469 +error_out:
   4.470 +    if (domid)
   4.471 +        libxl_domain_destroy(ctx, domid, 0);
   4.472 +
   4.473 +    return ret;
   4.474 +}
   4.475 +int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config,
   4.476 +                            libxl_console_ready cb, void *priv, uint32_t *domid)
   4.477 +{
   4.478 +    return do_domain_create(ctx, d_config, cb, priv, domid, -1);
   4.479 +}
   4.480 +
   4.481 +int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
   4.482 +                                libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd)
   4.483 +{
   4.484 +    return do_domain_create(ctx, d_config, cb, priv, domid, restore_fd);
   4.485 +}
     5.1 --- a/tools/libxl/libxl_dm.c	Tue Jan 11 18:16:45 2011 +0000
     5.2 +++ b/tools/libxl/libxl_dm.c	Tue Jan 11 18:29:43 2011 +0000
     5.3 @@ -324,7 +324,7 @@ static char ** libxl_build_device_model_
     5.4  
     5.5  static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
     5.6  {
     5.7 -    libxl_device_model_starting *starting = for_spawn;
     5.8 +    libxl__device_model_starting *starting = for_spawn;
     5.9      struct xs_handle *xsh;
    5.10      char *path = NULL, *pid = NULL;
    5.11      int len;
    5.12 @@ -426,7 +426,7 @@ static int libxl_create_stubdom(libxl_ct
    5.13                                  libxl_device_nic *vifs, int num_vifs,
    5.14                                  libxl_device_vfb *vfb,
    5.15                                  libxl_device_vkb *vkb,
    5.16 -                                libxl_device_model_starting **starting_r)
    5.17 +                                libxl__device_model_starting **starting_r)
    5.18  {
    5.19      libxl__gc gc = LIBXL_INIT_GC(ctx);
    5.20      int i, num_console = 1, ret;
    5.21 @@ -438,7 +438,7 @@ static int libxl_create_stubdom(libxl_ct
    5.22      char **args;
    5.23      struct xs_permissions perm[2];
    5.24      xs_transaction_t t;
    5.25 -    libxl_device_model_starting *dm_starting = 0;
    5.26 +    libxl__device_model_starting *dm_starting = 0;
    5.27  
    5.28      args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
    5.29      if (!args) {
    5.30 @@ -462,10 +462,10 @@ static int libxl_create_stubdom(libxl_ct
    5.31      b_info.u.pv.features = "";
    5.32      b_info.hvm = 0;
    5.33  
    5.34 -    ret = libxl_domain_make(ctx, &c_info, &domid);
    5.35 +    ret = libxl__domain_make(ctx, &c_info, &domid);
    5.36      if (ret)
    5.37          goto out_free;
    5.38 -    ret = libxl_domain_build(ctx, &b_info, domid, &state);
    5.39 +    ret = libxl__domain_build(ctx, &b_info, domid, &state);
    5.40      if (ret)
    5.41          goto out_free;
    5.42  
    5.43 @@ -545,11 +545,11 @@ retry_transaction:
    5.44          if (ret)
    5.45              goto out_free;
    5.46      }
    5.47 -    if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
    5.48 +    if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
    5.49          ret = ERROR_FAIL;
    5.50          goto out_free;
    5.51      }
    5.52 -    if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) {
    5.53 +    if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) {
    5.54          ret = ERROR_FAIL;
    5.55          goto out_free;
    5.56      }
    5.57 @@ -557,7 +557,7 @@ retry_transaction:
    5.58      libxl_domain_unpause(ctx, domid);
    5.59  
    5.60      if (starting_r) {
    5.61 -        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
    5.62 +        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
    5.63          (*starting_r)->domid = info->domid;
    5.64          (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
    5.65          (*starting_r)->for_spawn = NULL;
    5.66 @@ -572,18 +572,18 @@ out:
    5.67      return ret;
    5.68  }
    5.69  
    5.70 -int libxl_create_device_model(libxl_ctx *ctx,
    5.71 +int libxl__create_device_model(libxl_ctx *ctx,
    5.72                                libxl_device_model_info *info,
    5.73                                libxl_device_disk *disks, int num_disks,
    5.74                                libxl_device_nic *vifs, int num_vifs,
    5.75 -                              libxl_device_model_starting **starting_r)
    5.76 +                              libxl__device_model_starting **starting_r)
    5.77  {
    5.78      libxl__gc gc = LIBXL_INIT_GC(ctx);
    5.79      char *path, *logfile;
    5.80      int logfile_w, null;
    5.81      int rc;
    5.82      char **args;
    5.83 -    libxl_device_model_starting buf_starting, *p;
    5.84 +    libxl__device_model_starting buf_starting, *p;
    5.85      xs_transaction_t t; 
    5.86      char *vm_path;
    5.87      char **pass_stuff;
    5.88 @@ -614,7 +614,7 @@ int libxl_create_device_model(libxl_ctx 
    5.89  
    5.90      if (starting_r) {
    5.91          rc = ERROR_NOMEM;
    5.92 -        *starting_r = calloc(sizeof(libxl_device_model_starting), 1);
    5.93 +        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
    5.94          if (!*starting_r)
    5.95              goto out_close;
    5.96          p = *starting_r;
    5.97 @@ -668,8 +668,8 @@ out:
    5.98      return rc;
    5.99  }
   5.100  
   5.101 -int libxl_detach_device_model(libxl_ctx *ctx,
   5.102 -                              libxl_device_model_starting *starting)
   5.103 +static int detach_device_model(libxl_ctx *ctx,
   5.104 +                              libxl__device_model_starting *starting)
   5.105  {
   5.106      int rc;
   5.107      rc = libxl__spawn_detach(ctx, starting->for_spawn);
   5.108 @@ -680,14 +680,14 @@ int libxl_detach_device_model(libxl_ctx 
   5.109  }
   5.110  
   5.111  
   5.112 -int libxl_confirm_device_model_startup(libxl_ctx *ctx,
   5.113 -                                       libxl_device_model_starting *starting)
   5.114 +int libxl__confirm_device_model_startup(libxl_ctx *ctx,
   5.115 +                                       libxl__device_model_starting *starting)
   5.116  {
   5.117      int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL);
   5.118      int detach;
   5.119      if ( !problem )
   5.120          problem = libxl__spawn_check(ctx, starting->for_spawn);
   5.121 -    detach = libxl_detach_device_model(ctx, starting);
   5.122 +    detach = detach_device_model(ctx, starting);
   5.123      return problem ? problem : detach;
   5.124  }
   5.125  
   5.126 @@ -760,7 +760,7 @@ static int libxl_build_xenpv_qemu_args(l
   5.127      return 0;
   5.128  }
   5.129  
   5.130 -int libxl_need_xenpv_qemu(libxl_ctx *ctx,
   5.131 +int libxl__need_xenpv_qemu(libxl_ctx *ctx,
   5.132          int nr_consoles, libxl_device_console *consoles,
   5.133          int nr_vfbs, libxl_device_vfb *vfbs,
   5.134          int nr_disks, libxl_device_disk *disks)
   5.135 @@ -793,14 +793,14 @@ out:
   5.136      return ret;
   5.137  }
   5.138  
   5.139 -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
   5.140 -                            libxl_device_model_starting **starting_r)
   5.141 +int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
   5.142 +                            libxl__device_model_starting **starting_r)
   5.143  {
   5.144      libxl__gc gc = LIBXL_INIT_GC(ctx);
   5.145      libxl_device_model_info info;
   5.146  
   5.147      libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info);
   5.148 -    libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
   5.149 +    libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
   5.150      libxl__free_all(&gc);
   5.151      return 0;
   5.152  }
     6.1 --- a/tools/libxl/libxl_exec.c	Tue Jan 11 18:16:45 2011 +0000
     6.2 +++ b/tools/libxl/libxl_exec.c	Tue Jan 11 18:29:43 2011 +0000
     6.3 @@ -90,7 +90,7 @@ void libxl_report_child_exitstatus(libxl
     6.4  }
     6.5  
     6.6  int libxl__spawn_spawn(libxl_ctx *ctx,
     6.7 -                      libxl_device_model_starting *starting,
     6.8 +                      libxl__device_model_starting *starting,
     6.9                        const char *what,
    6.10                        void (*intermediate_hook)(void *for_spawn,
    6.11                                                  pid_t innerchild))
     7.1 --- a/tools/libxl/libxl_internal.h	Tue Jan 11 18:16:45 2011 +0000
     7.2 +++ b/tools/libxl/libxl_internal.h	Tue Jan 11 18:29:43 2011 +0000
     7.3 @@ -194,14 +194,37 @@ typedef struct {
     7.4      char *what; /* malloc'd in spawn_spawn */
     7.5  } libxl__spawn_starting;
     7.6  
     7.7 -struct libxl__device_model_starting {
     7.8 +typedef struct {
     7.9      libxl__spawn_starting *for_spawn; /* first! */
    7.10      char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */
    7.11      int domid;
    7.12 -};
    7.13 +} libxl__device_model_starting;
    7.14 +
    7.15 +/* from xl_create */
    7.16 +_hidden int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid);
    7.17 +_hidden int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state);
    7.18 +
    7.19 +/* for device model creation */
    7.20 +_hidden int libxl__create_device_model(libxl_ctx *ctx,
    7.21 +                              libxl_device_model_info *info,
    7.22 +                              libxl_device_disk *disk, int num_disks,
    7.23 +                              libxl_device_nic *vifs, int num_vifs,
    7.24 +                              libxl__device_model_starting **starting_r);
    7.25 +_hidden int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
    7.26 +                            libxl__device_model_starting **starting_r);
    7.27 +_hidden int libxl__need_xenpv_qemu(libxl_ctx *ctx,
    7.28 +        int nr_consoles, libxl_device_console *consoles,
    7.29 +        int nr_vfbs, libxl_device_vfb *vfbs,
    7.30 +        int nr_disks, libxl_device_disk *disks);
    7.31 +
    7.32 +  /* Caller must either: pass starting_r==0, or on successful
    7.33 +   * return pass *starting_r (which will be non-0) to
    7.34 +   * libxl_confirm_device_model or libxl_detach_device_model. */
    7.35 +_hidden int libxl__confirm_device_model_startup(libxl_ctx *ctx,
    7.36 +                              libxl__device_model_starting *starting);
    7.37  
    7.38  _hidden int libxl__spawn_spawn(libxl_ctx *ctx,
    7.39 -                      libxl_device_model_starting *starting,
    7.40 +                      libxl__device_model_starting *starting,
    7.41                        const char *what,
    7.42                        void (*intermediate_hook)(void *for_spawn, pid_t innerchild));
    7.43  _hidden int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid);
     8.1 --- a/tools/libxl/xl_cmdimpl.c	Tue Jan 11 18:16:45 2011 +0000
     8.2 +++ b/tools/libxl/xl_cmdimpl.c	Tue Jan 11 18:29:43 2011 +0000
     8.3 @@ -100,81 +100,18 @@ struct save_file_header {
     8.4  };
     8.5  
     8.6  
     8.7 -enum action_on_shutdown {
     8.8 -    ACTION_DESTROY,
     8.9 -
    8.10 -    ACTION_RESTART,
    8.11 -    ACTION_RESTART_RENAME,
    8.12 -
    8.13 -    ACTION_PRESERVE,
    8.14 -
    8.15 -    ACTION_COREDUMP_DESTROY,
    8.16 -    ACTION_COREDUMP_RESTART,
    8.17 -};
    8.18 -
    8.19  static const char *action_on_shutdown_names[] = {
    8.20 -    [ACTION_DESTROY] = "destroy",
    8.21 -
    8.22 -    [ACTION_RESTART] = "restart",
    8.23 -    [ACTION_RESTART_RENAME] = "rename-restart",
    8.24 -
    8.25 -    [ACTION_PRESERVE] = "preserve",
    8.26 -
    8.27 -    [ACTION_COREDUMP_DESTROY] = "coredump-destroy",
    8.28 -    [ACTION_COREDUMP_RESTART] = "coredump-restart",
    8.29 +    [LIBXL_ACTION_DESTROY] = "destroy",
    8.30 +
    8.31 +    [LIBXL_ACTION_RESTART] = "restart",
    8.32 +    [LIBXL_ACTION_RESTART_RENAME] = "rename-restart",
    8.33 +
    8.34 +    [LIBXL_ACTION_PRESERVE] = "preserve",
    8.35 +
    8.36 +    [LIBXL_ACTION_COREDUMP_DESTROY] = "coredump-destroy",
    8.37 +    [LIBXL_ACTION_COREDUMP_RESTART] = "coredump-restart",
    8.38  };
    8.39  
    8.40 -struct domain_config {
    8.41 -    libxl_domain_create_info c_info;
    8.42 -    libxl_domain_build_info b_info;
    8.43 -
    8.44 -    int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs;
    8.45 -
    8.46 -    libxl_device_disk *disks;
    8.47 -    libxl_device_nic *vifs;
    8.48 -    libxl_device_net2 *vif2s;
    8.49 -    libxl_device_pci *pcidevs;
    8.50 -    libxl_device_vfb *vfbs;
    8.51 -    libxl_device_vkb *vkbs;
    8.52 -
    8.53 -    enum action_on_shutdown on_poweroff;
    8.54 -    enum action_on_shutdown on_reboot;
    8.55 -    enum action_on_shutdown on_watchdog;
    8.56 -    enum action_on_shutdown on_crash;
    8.57 -};
    8.58 -
    8.59 -static void free_domain_config(struct domain_config *d_config)
    8.60 -{
    8.61 -    int i;
    8.62 -
    8.63 -    for (i=0; i<d_config->num_disks; i++)
    8.64 -        libxl_device_disk_destroy(&d_config->disks[i]);
    8.65 -    free(d_config->disks);
    8.66 -
    8.67 -    for (i=0; i<d_config->num_vifs; i++)
    8.68 -        libxl_device_nic_destroy(&d_config->vifs[i]);
    8.69 -    free(d_config->vifs);
    8.70 -
    8.71 -    for (i=0; i<d_config->num_vif2s; i++)
    8.72 -        libxl_device_net2_destroy(&d_config->vif2s[i]);
    8.73 -    free(d_config->vif2s);
    8.74 -
    8.75 -    for (i=0; i<d_config->num_pcidevs; i++)
    8.76 -        libxl_device_pci_destroy(&d_config->pcidevs[i]);
    8.77 -    free(d_config->pcidevs);
    8.78 -
    8.79 -    for (i=0; i<d_config->num_vfbs; i++)
    8.80 -        libxl_device_vfb_destroy(&d_config->vfbs[i]);
    8.81 -    free(d_config->vfbs);
    8.82 -
    8.83 -    for (i=0; i<d_config->num_vkbs; i++)
    8.84 -        libxl_device_vkb_destroy(&d_config->vkbs[i]);
    8.85 -    free(d_config->vkbs);
    8.86 -
    8.87 -    libxl_domain_create_info_destroy(&d_config->c_info);
    8.88 -    libxl_domain_build_info_destroy(&d_config->b_info);
    8.89 -}
    8.90 -
    8.91  /* Optional data, in order:
    8.92   *   4 bytes uint32_t  config file size
    8.93   *   n bytes           config file in Unix text file format
    8.94 @@ -458,18 +395,8 @@ static void init_vkb_info(libxl_device_v
    8.95      vkb->devid = dev_num;
    8.96  }
    8.97  
    8.98 -static void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state)
    8.99 -{
   8.100 -    memset(console, 0x00, sizeof(libxl_device_console));
   8.101 -    console->devid = dev_num;
   8.102 -    console->consback = LIBXL_CONSBACK_XENCONSOLED;
   8.103 -    console->output = strdup("pty");
   8.104 -    if (state)
   8.105 -        console->build_state = state;
   8.106 -}
   8.107 -
   8.108  static void printf_info(int domid,
   8.109 -                        struct domain_config *d_config,
   8.110 +                        libxl_domain_config *d_config,
   8.111                          libxl_device_model_info *dm_info)
   8.112  {
   8.113      int i;
   8.114 @@ -627,7 +554,7 @@ static void printf_info(int domid,
   8.115         printf(")\n");
   8.116  }
   8.117  
   8.118 -static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a)
   8.119 +static int parse_action_on_shutdown(const char *buf, enum libxl_action_on_shutdown *a)
   8.120  {
   8.121      int i;
   8.122      const char *n;
   8.123 @@ -774,7 +701,7 @@ out:
   8.124  static void parse_config_data(const char *configfile_filename_report,
   8.125                                const char *configfile_data,
   8.126                                int configfile_len,
   8.127 -                              struct domain_config *d_config,
   8.128 +                              libxl_domain_config *d_config,
   8.129                                libxl_device_model_info *dm_info)
   8.130  {
   8.131      const char *buf;
   8.132 @@ -1319,32 +1246,12 @@ static void *xrealloc(void *ptr, size_t 
   8.133      return r;
   8.134  }
   8.135  
   8.136 -static pid_t autoconnect_console(void)
   8.137 -{
   8.138 -    pid_t pid;
   8.139 -
   8.140 -    pid = fork();
   8.141 -    if (pid < 0) {
   8.142 -        perror("unable to fork xenconsole");
   8.143 -        return ERROR_FAIL;
   8.144 -    } else if (pid > 0)
   8.145 -        return pid;
   8.146 -
   8.147 -    libxl_ctx_postfork(&ctx);
   8.148 -
   8.149 -    sleep(1);
   8.150 -    libxl_primary_console_exec(&ctx, domid);
   8.151 -    /* Do not return. xl continued in child process */
   8.152 -    fprintf(stderr, "Unable to attach console\n");
   8.153 -    _exit(1);
   8.154 -}
   8.155 -
   8.156  /* Returns 1 if domain should be restarted, 2 if domain should be renamed then restarted  */
   8.157  static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
   8.158 -                               struct domain_config *d_config, libxl_dominfo *info)
   8.159 +                               libxl_domain_config *d_config, libxl_dominfo *info)
   8.160  {
   8.161      int restart = 0;
   8.162 -    enum action_on_shutdown action;
   8.163 +    enum libxl_action_on_shutdown action;
   8.164  
   8.165      switch (info->shutdown_reason) {
   8.166      case SHUTDOWN_poweroff:
   8.167 @@ -1363,12 +1270,12 @@ static int handle_domain_death(libxl_ctx
   8.168          break;
   8.169      default:
   8.170          LOG("Unknown shutdown reason code %d. Destroying domain.", info->shutdown_reason);
   8.171 -        action = ACTION_DESTROY;
   8.172 +        action = LIBXL_ACTION_DESTROY;
   8.173      }
   8.174  
   8.175      LOG("Action for shutdown reason code %d is %s", info->shutdown_reason, action_on_shutdown_names[action]);
   8.176  
   8.177 -    if (action == ACTION_COREDUMP_DESTROY || action == ACTION_COREDUMP_RESTART) {
   8.178 +    if (action == LIBXL_ACTION_COREDUMP_DESTROY || action == LIBXL_ACTION_COREDUMP_RESTART) {
   8.179          char *corefile;
   8.180          int rc;
   8.181  
   8.182 @@ -1381,30 +1288,30 @@ static int handle_domain_death(libxl_ctx
   8.183          }
   8.184          /* No point crying over spilled milk, continue on failure. */
   8.185  
   8.186 -        if (action == ACTION_COREDUMP_DESTROY)
   8.187 -            action = ACTION_DESTROY;
   8.188 +        if (action == LIBXL_ACTION_COREDUMP_DESTROY)
   8.189 +            action = LIBXL_ACTION_DESTROY;
   8.190          else
   8.191 -            action = ACTION_RESTART;
   8.192 +            action = LIBXL_ACTION_RESTART;
   8.193      }
   8.194  
   8.195      switch (action) {
   8.196 -    case ACTION_PRESERVE:
   8.197 +    case LIBXL_ACTION_PRESERVE:
   8.198          break;
   8.199  
   8.200 -    case ACTION_RESTART_RENAME:
   8.201 +    case LIBXL_ACTION_RESTART_RENAME:
   8.202          restart = 2;
   8.203          break;
   8.204  
   8.205 -    case ACTION_RESTART:
   8.206 +    case LIBXL_ACTION_RESTART:
   8.207          restart = 1;
   8.208          /* fall-through */
   8.209 -    case ACTION_DESTROY:
   8.210 +    case LIBXL_ACTION_DESTROY:
   8.211          LOG("Domain %d needs to be cleaned up: destroying the domain", domid);
   8.212          libxl_domain_destroy(ctx, domid, 0);
   8.213          break;
   8.214  
   8.215 -    case ACTION_COREDUMP_DESTROY:
   8.216 -    case ACTION_COREDUMP_RESTART:
   8.217 +    case LIBXL_ACTION_COREDUMP_DESTROY:
   8.218 +    case LIBXL_ACTION_COREDUMP_RESTART:
   8.219          /* Already handled these above. */
   8.220          abort();
   8.221      }
   8.222 @@ -1413,7 +1320,7 @@ static int handle_domain_death(libxl_ctx
   8.223  }
   8.224  
   8.225  static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event,
   8.226 -                           struct domain_config *d_config, libxl_dominfo *info)
   8.227 +                           libxl_domain_config *d_config, libxl_dominfo *info)
   8.228  {
   8.229      time_t now;
   8.230      struct tm tm;
   8.231 @@ -1504,12 +1411,29 @@ static int freemem(libxl_domain_build_in
   8.232      return ERROR_NOMEM;
   8.233  }
   8.234  
   8.235 +static int autoconnect_console(libxl_ctx *ctx, uint32_t domid, void *priv)
   8.236 +{
   8.237 +    pid_t *pid = priv;
   8.238 +
   8.239 +    *pid = fork();
   8.240 +    if (*pid < 0) {
   8.241 +        perror("unable to fork xenconsole");
   8.242 +        return ERROR_FAIL;
   8.243 +    } else if (*pid > 0)
   8.244 +        return 0;
   8.245 +
   8.246 +    libxl_ctx_postfork(ctx);
   8.247 +
   8.248 +    sleep(1);
   8.249 +    libxl_primary_console_exec(ctx, domid);
   8.250 +    /* Do not return. xl continued in child process */
   8.251 +    fprintf(stderr, "Unable to attach console\n");
   8.252 +    _exit(1);
   8.253 +}
   8.254 +
   8.255  static int create_domain(struct domain_create *dom_info)
   8.256  {
   8.257 -    struct domain_config d_config;
   8.258 -
   8.259 -    libxl_domain_build_state state;
   8.260 -    libxl_device_model_info dm_info;
   8.261 +    libxl_domain_config d_config;
   8.262  
   8.263      int debug = dom_info->debug;
   8.264      int daemonize = dom_info->daemonize;
   8.265 @@ -1519,20 +1443,19 @@ static int create_domain(struct domain_c
   8.266      const char *restore_file = dom_info->restore_file;
   8.267      int migrate_fd = dom_info->migrate_fd;
   8.268  
   8.269 -    int i, fd;
   8.270 +    int fd;
   8.271      int need_daemon = 1;
   8.272      int ret, rc;
   8.273 -    libxl_device_model_starting *dm_starting = 0;
   8.274      libxl_waiter *w1 = NULL, *w2 = NULL;
   8.275      void *config_data = 0;
   8.276      int config_len = 0;
   8.277      int restore_fd = -1;
   8.278 -    struct save_file_header hdr;
   8.279 +    int status = 0;
   8.280 +    libxl_console_ready cb;
   8.281      pid_t child_console_pid = -1;
   8.282 -    int status = 0;
   8.283 +    struct save_file_header hdr;
   8.284  
   8.285      memset(&d_config, 0x00, sizeof(d_config));
   8.286 -    memset(&dm_info, 0x00, sizeof(dm_info));
   8.287  
   8.288      if (restore_file) {
   8.289          uint8_t *optdata_begin = 0;
   8.290 @@ -1632,7 +1555,7 @@ static int create_domain(struct domain_c
   8.291      if (!dom_info->quiet)
   8.292          printf("Parsing config file %s\n", config_file);
   8.293  
   8.294 -    parse_config_data(config_file, config_data, config_len, &d_config, &dm_info);
   8.295 +    parse_config_data(config_file, config_data, config_len, &d_config, &d_config.dm_info);
   8.296  
   8.297      ret = 0;
   8.298      if (dom_info->dryrun)
   8.299 @@ -1657,7 +1580,7 @@ static int create_domain(struct domain_c
   8.300      }
   8.301  
   8.302      if (debug)
   8.303 -        printf_info(-1, &d_config, &dm_info);
   8.304 +        printf_info(-1, &d_config, &d_config.dm_info);
   8.305  
   8.306  start:
   8.307      domid = 0;
   8.308 @@ -1666,20 +1589,13 @@ start:
   8.309      if (rc < 0)
   8.310          goto error_out;
   8.311  
   8.312 -    ret = freemem(&d_config.b_info, &dm_info);
   8.313 +    ret = freemem(&d_config.b_info, &d_config.dm_info);
   8.314      if (ret < 0) {
   8.315          fprintf(stderr, "failed to free memory for the domain\n");
   8.316          ret = ERROR_FAIL;
   8.317          goto error_out;
   8.318      }
   8.319  
   8.320 -    ret = libxl_domain_make(&ctx, &d_config.c_info, &domid);
   8.321 -    if (ret) {
   8.322 -        fprintf(stderr, "cannot make domain: %d\n", ret);
   8.323 -        ret = ERROR_FAIL;
   8.324 -        goto error_out;
   8.325 -    }
   8.326 -
   8.327      ret = libxl_userdata_store(&ctx, domid, "xl",
   8.328                                      config_data, config_len);
   8.329      if (ret) {
   8.330 @@ -1688,116 +1604,22 @@ start:
   8.331          goto error_out;
   8.332      }
   8.333  
   8.334 -    if (dom_info->console_autoconnect && !d_config.c_info.hvm) {
   8.335 -        child_console_pid = autoconnect_console();
   8.336 -        if (child_console_pid < 0)
   8.337 -            goto error_out;
   8.338 -    }
   8.339 -
   8.340 -    if (!restore_file) {
   8.341 -        ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks > 0 ? &d_config.disks[0] : NULL, domid);
   8.342 -        if (ret) {
   8.343 -            fprintf(stderr, "failed to run bootloader: %d\n", ret);
   8.344 -            goto error_out;
   8.345 -        }
   8.346 -    }
   8.347 -
   8.348 -    if (!restore_file || !need_daemon) {
   8.349 -        if (dm_info.saved_state) {
   8.350 -            free(dm_info.saved_state);
   8.351 -            dm_info.saved_state = NULL;
   8.352 -        }
   8.353 -        ret = libxl_domain_build(&ctx, &d_config.b_info, domid, &state);
   8.354 -    } else {
   8.355 -        ret = libxl_domain_restore(&ctx, &d_config.b_info, domid, restore_fd, &state, &dm_info);
   8.356 -    }
   8.357 -
   8.358 -    if (ret) {
   8.359 -        fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
   8.360 -        ret = ERROR_FAIL;
   8.361 +    if ( dom_info->console_autoconnect ) {
   8.362 +        cb = autoconnect_console;
   8.363 +    }else{
   8.364 +        cb = NULL;
   8.365 +    }
   8.366 +
   8.367 +    if ( restore_file ) {
   8.368 +        ret = libxl_domain_create_restore(&ctx, &d_config,
   8.369 +                                            cb, &child_console_pid,
   8.370 +                                            &domid, restore_fd);
   8.371 +    }else{
   8.372 +        ret = libxl_domain_create_new(&ctx, &d_config,
   8.373 +                                        cb, &child_console_pid, &domid);
   8.374 +    }
   8.375 +    if ( ret )
   8.376          goto error_out;
   8.377 -    }
   8.378 -
   8.379 -    for (i = 0; i < d_config.num_disks; i++) {
   8.380 -        d_config.disks[i].domid = domid;
   8.381 -        ret = libxl_device_disk_add(&ctx, domid, &d_config.disks[i]);
   8.382 -        if (ret) {
   8.383 -            fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret);
   8.384 -            ret = ERROR_FAIL;
   8.385 -            goto error_out;
   8.386 -        }
   8.387 -    }
   8.388 -    for (i = 0; i < d_config.num_vifs; i++) {
   8.389 -        d_config.vifs[i].domid = domid;
   8.390 -        ret = libxl_device_nic_add(&ctx, domid, &d_config.vifs[i]);
   8.391 -        if (ret) {
   8.392 -            fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret);
   8.393 -            ret = ERROR_FAIL;
   8.394 -            goto error_out;
   8.395 -        }
   8.396 -    }
   8.397 -    if (!d_config.c_info.hvm) {
   8.398 -        for (i = 0; i < d_config.num_vif2s; i++) {
   8.399 -            d_config.vif2s[i].domid = domid;
   8.400 -            ret = libxl_device_net2_add(&ctx, domid, &d_config.vif2s[i]);
   8.401 -            if (ret) {
   8.402 -                fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret);
   8.403 -                ret = ERROR_FAIL;
   8.404 -                goto error_out;
   8.405 -            }
   8.406 -        }
   8.407 -    }
   8.408 -    if (d_config.c_info.hvm) {
   8.409 -        libxl_device_console console;
   8.410 -
   8.411 -        init_console_info(&console, 0, &state);
   8.412 -        console.domid = domid;
   8.413 -        libxl_device_console_add(&ctx, domid, &console);
   8.414 -        libxl_device_console_destroy(&console);
   8.415 -
   8.416 -        dm_info.domid = domid;
   8.417 -        MUST( libxl_create_device_model(&ctx, &dm_info,
   8.418 -                                        d_config.disks, d_config.num_disks,
   8.419 -                                        d_config.vifs, d_config.num_vifs,
   8.420 -                                        &dm_starting) );
   8.421 -    } else {
   8.422 -        int need_qemu = 0;
   8.423 -        libxl_device_console console;
   8.424 -
   8.425 -        for (i = 0; i < d_config.num_vfbs; i++) {
   8.426 -            d_config.vfbs[i].domid = domid;
   8.427 -            libxl_device_vfb_add(&ctx, domid, &d_config.vfbs[i]);
   8.428 -            d_config.vkbs[i].domid = domid;
   8.429 -            libxl_device_vkb_add(&ctx, domid, &d_config.vkbs[i]);
   8.430 -        }
   8.431 -
   8.432 -        init_console_info(&console, 0, &state);
   8.433 -        console.domid = domid;
   8.434 -
   8.435 -        need_qemu = libxl_need_xenpv_qemu(&ctx, 1, &console,
   8.436 -                d_config.num_vfbs, d_config.vfbs,
   8.437 -                d_config.num_disks, &d_config.disks[0]);
   8.438 -
   8.439 -        if (need_qemu)
   8.440 -             console.consback = LIBXL_CONSBACK_IOEMU;
   8.441 -
   8.442 -        libxl_device_console_add(&ctx, domid, &console);
   8.443 -        libxl_device_console_destroy(&console);
   8.444 -
   8.445 -        if (need_qemu)
   8.446 -            libxl_create_xenpv_qemu(&ctx, domid, d_config.vfbs, &dm_starting);
   8.447 -    }
   8.448 -
   8.449 -    if (dm_starting)
   8.450 -        MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) );
   8.451 -    for (i = 0; i < d_config.num_pcidevs; i++)
   8.452 -        libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]);
   8.453 -
   8.454 -    if (dom_info->console_autoconnect && d_config.c_info.hvm) {
   8.455 -        child_console_pid = autoconnect_console();
   8.456 -        if (child_console_pid < 0)
   8.457 -            goto error_out;
   8.458 -    }
   8.459  
   8.460      release_lock();
   8.461  
   8.462 @@ -1815,6 +1637,8 @@ start:
   8.463  
   8.464          child1 = libxl_fork(&ctx);
   8.465          if (child1) {
   8.466 +            printf("Daemon running with PID %d\n", child1);
   8.467 +
   8.468              for (;;) {
   8.469                  got_child = waitpid(child1, &status, 0);
   8.470                  if (got_child == child1) break;
   8.471 @@ -1956,9 +1780,7 @@ out:
   8.472      if (logfile != 2)
   8.473          close(logfile);
   8.474  
   8.475 -    libxl_device_model_info_destroy(&dm_info);
   8.476 -
   8.477 -    free_domain_config(&d_config);
   8.478 +    libxl_domain_config_destroy(&d_config);
   8.479  
   8.480      free(config_data);
   8.481  
   8.482 @@ -2553,7 +2375,7 @@ static void reboot_domain(const char *p)
   8.483  
   8.484  static void list_domains_details(const libxl_dominfo *info, int nb_domain)
   8.485  {
   8.486 -    struct domain_config d_config;
   8.487 +    libxl_domain_config d_config;
   8.488  
   8.489      char *config_file;
   8.490      uint8_t *data;
   8.491 @@ -2571,7 +2393,7 @@ static void list_domains_details(const l
   8.492          memset(&d_config, 0x00, sizeof(d_config));
   8.493          parse_config_data(config_file, (char *)data, len, &d_config, &dm_info);
   8.494          printf_info(info[i].domid, &d_config, &dm_info);
   8.495 -        free_domain_config(&d_config);
   8.496 +        libxl_domain_config_destroy(&d_config);
   8.497          free(data);
   8.498          free(config_file);
   8.499      }
     9.1 --- a/tools/ocaml/libs/xl/xl_stubs.c	Tue Jan 11 18:16:45 2011 +0000
     9.2 +++ b/tools/ocaml/libs/xl/xl_stubs.c	Tue Jan 11 18:29:43 2011 +0000
     9.3 @@ -68,16 +68,6 @@ void log_destroy(struct xentoollog_logge
     9.4  	caml_leave_blocking_section(); \
     9.5  	libxl_ctx_free(&ctx)
     9.6  
     9.7 -static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size)
     9.8 -{
     9.9 -	void *ptr;
    9.10 -	ptr = calloc(nmemb, size);
    9.11 -	if (!ptr)
    9.12 -		caml_raise_out_of_memory();
    9.13 -	gc->ptrs[gc->offset++] = ptr;
    9.14 -	return ptr;
    9.15 -}
    9.16 -
    9.17  static char * dup_String_val(caml_gc *gc, value s)
    9.18  {
    9.19  	int len;
    9.20 @@ -106,6 +96,17 @@ void failwith_xl(char *fname, struct cam
    9.21  	caml_raise_with_string(*caml_named_value("xl.error"), s);
    9.22  }
    9.23  
    9.24 +#if 0 /* TODO: wrap libxl_domain_create(), these functions will be needed then */
    9.25 +static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size)
    9.26 +{
    9.27 +	void *ptr;
    9.28 +	ptr = calloc(nmemb, size);
    9.29 +	if (!ptr)
    9.30 +		caml_raise_out_of_memory();
    9.31 +	gc->ptrs[gc->offset++] = ptr;
    9.32 +	return ptr;
    9.33 +}
    9.34 +
    9.35  static int string_string_tuple_array_val (caml_gc *gc, char ***c_val, value v)
    9.36  {
    9.37  	CAMLparam1(v);
    9.38 @@ -163,7 +164,7 @@ static int domain_build_info_val (caml_g
    9.39  	c_val->video_memkb = Int64_val(Field(v, 4));
    9.40  	c_val->shadow_memkb = Int64_val(Field(v, 5));
    9.41  	c_val->kernel.path = dup_String_val(gc, Field(v, 6));
    9.42 -	c_val->hvm = Tag_val(Field(v, 7)) == 0;
    9.43 +	c_val->is_hvm = Tag_val(Field(v, 7)) == 0;
    9.44  	infopriv = Field(Field(v, 7), 0);
    9.45  	if (c_val->hvm) {
    9.46  		c_val->u.hvm.pae = Bool_val(Field(infopriv, 0));
    9.47 @@ -184,6 +185,7 @@ static int domain_build_info_val (caml_g
    9.48  
    9.49  	CAMLreturn(0);
    9.50  }
    9.51 +#endif
    9.52  
    9.53  static int device_disk_val(caml_gc *gc, libxl_device_disk *c_val, value v)
    9.54  {
    9.55 @@ -332,21 +334,6 @@ static value Val_sched_credit(libxl_sche
    9.56  	CAMLreturn(v);
    9.57  }
    9.58  
    9.59 -static value Val_domain_build_state(libxl_domain_build_state *c_val)
    9.60 -{
    9.61 -	CAMLparam0();
    9.62 -	CAMLlocal1(v);
    9.63 -
    9.64 -	v = caml_alloc_tuple(4);
    9.65 -
    9.66 -	Store_field(v, 0, Val_int(c_val->store_port));
    9.67 -	Store_field(v, 1, caml_copy_int64(c_val->store_mfn));
    9.68 -	Store_field(v, 2, Val_int(c_val->console_port));
    9.69 -	Store_field(v, 3, caml_copy_int64(c_val->console_mfn));
    9.70 -
    9.71 -	CAMLreturn(v);
    9.72 -}
    9.73 -
    9.74  static value Val_physinfo(libxl_physinfo *c_val)
    9.75  {
    9.76  	CAMLparam0();
    9.77 @@ -373,52 +360,6 @@ static value Val_physinfo(libxl_physinfo
    9.78  	CAMLreturn(v);
    9.79  }
    9.80  
    9.81 -value stub_xl_domain_make(value info)
    9.82 -{
    9.83 -	CAMLparam1(info);
    9.84 -	uint32_t domid;
    9.85 -	libxl_domain_create_info c_info;
    9.86 -	int ret;
    9.87 -	INIT_STRUCT();
    9.88 -
    9.89 -	domain_create_info_val (&gc, &c_info, info);
    9.90 -
    9.91 -	INIT_CTX();
    9.92 -
    9.93 -	ret = libxl_domain_make(&ctx, &c_info, &domid);
    9.94 -	if (ret != 0)
    9.95 -		failwith_xl("domain make", &lg);
    9.96 -
    9.97 -	FREE_CTX();
    9.98 -
    9.99 -	CAMLreturn(Val_int(domid));
   9.100 -}
   9.101 -
   9.102 -value stub_xl_domain_build(value info, value domid)
   9.103 -{
   9.104 -	CAMLparam2(info, domid);
   9.105 -	CAMLlocal1(result);
   9.106 -	libxl_domain_build_info c_info;
   9.107 -	libxl_domain_build_state c_state;
   9.108 -	int ret;
   9.109 -	int c_domid;
   9.110 -	INIT_STRUCT();
   9.111 -
   9.112 -	domain_build_info_val (&gc, &c_info, info);
   9.113 -	c_domid = Int_val(domid);
   9.114 -
   9.115 -	INIT_CTX();
   9.116 -
   9.117 -	ret = libxl_domain_build(&ctx, &c_info, c_domid, &c_state);
   9.118 -	if (ret != 0)
   9.119 -		failwith_xl("domain_build", &lg);
   9.120 -
   9.121 -	result = Val_domain_build_state(&c_state);
   9.122 -	FREE_CTX();
   9.123 -
   9.124 -	CAMLreturn(result);
   9.125 -}
   9.126 -
   9.127  value stub_xl_disk_add(value info, value domid)
   9.128  {
   9.129  	CAMLparam2(info, domid);