Gianni Tedesco
2011-Jan-10 16:11 UTC
[Xen-devel] [PATCH, v3]: xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
Changes since v2: - rebased for previous two patches - more thorough testing Not changed: - not moved init_*_info in to libxl, I think it''s a good idea but I will try to send a follow-up patch that does that. --- 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> # HG changeset patch # Parent 02773e0763a0bb0936548e7676d7a866babdffe3 diff -r 02773e0763a0 tools/libxl/Makefile --- a/tools/libxl/Makefile Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/Makefile Fri Jan 07 15:26:59 2011 +0000 @@ -20,7 +20,7 @@ ifeq ($(CONFIG_Linux),y) LIBS += -luuid endif -LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o +LIBXL_OBJS-y = osdeps.o libxl_paths.o libxl_bootloader.o flexarray.o ifeq ($(LIBXL_BLKTAP),y) LIBXL_OBJS-y += libxl_blktap2.o else @@ -29,7 +29,9 @@ endif LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o LIBXL_OBJS-$(CONFIG_IA64) += libxl_nocpuid.o -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) +LIBXL_OBJS = flexarray.o libxl.o libxl_create.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) LIBXL_OBJS += _libxl_types.o AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h diff -r 02773e0763a0 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/libxl.c Fri Jan 07 15:26:59 2011 +0000 @@ -104,114 +104,6 @@ void libxl_key_value_list_destroy(libxl_ /******************************************************************************/ -int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, - uint32_t *domid) -{ - libxl__gc gc = LIBXL_INIT_GC(ctx); - int flags, ret, i, rc; - char *uuid_string; - char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; - char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", - "control", "attr", "messages" }; - char *dom_path, *vm_path; - struct xs_permissions roperm[2]; - struct xs_permissions rwperm[1]; - xs_transaction_t t; - xen_domain_handle_t handle; - - uuid_string = libxl__uuid2string(&gc, info->uuid); - if (!uuid_string) { - libxl__free_all(&gc); - return ERROR_NOMEM; - } - - flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; - flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; - flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off; - *domid = -1; - - /* Ultimately, handle is an array of 16 uint8_t, same as uuid */ - libxl_uuid_copy((libxl_uuid *)handle, &info->uuid); - - ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); - if (ret < 0) { - LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail"); - libxl__free_all(&gc); - return ERROR_FAIL; - } - - ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); - if (ret < 0) { - LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail"); - libxl__free_all(&gc); - return ERROR_FAIL; - } - - dom_path = libxl__xs_get_dompath(&gc, *domid); - if (!dom_path) { - libxl__free_all(&gc); - return ERROR_FAIL; - } - - vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string); - if (!vm_path) { - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths"); - libxl__free_all(&gc); - return ERROR_FAIL; - } - - roperm[0].id = 0; - roperm[0].perms = XS_PERM_NONE; - roperm[1].id = *domid; - roperm[1].perms = XS_PERM_READ; - rwperm[0].id = *domid; - rwperm[0].perms = XS_PERM_NONE; - -retry_transaction: - t = xs_transaction_start(ctx->xsh); - xs_rm(ctx->xsh, t, dom_path); - xs_mkdir(ctx->xsh, t, dom_path); - xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); - - xs_rm(ctx->xsh, t, vm_path); - xs_mkdir(ctx->xsh, t, vm_path); - xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); - - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); - rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); - if (rc) { - libxl__free_all(&gc); - return rc; - } - - for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { - char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); - xs_mkdir(ctx->xsh, t, path); - xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); - } - for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { - char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); - xs_mkdir(ctx->xsh, t, path); - xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); - } - - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); - if (info->poolname) - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); - - libxl__xs_writev(&gc, t, dom_path, info->xsdata); - libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata); - - xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); - - if (!xs_transaction_end(ctx->xsh, t, 0)) - if (errno == EAGAIN) - goto retry_transaction; - - libxl__free_all(&gc); - return 0; -} int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, const char *old_name, const char *new_name, @@ -293,141 +185,6 @@ int libxl_domain_rename(libxl_ctx *ctx, x_nomem: rc = ERROR_NOMEM; goto x_rc; } -int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) -{ - libxl__gc gc = LIBXL_INIT_GC(ctx); - char **vments = NULL, **localents = NULL; - struct timeval start_time; - int i, ret; - - ret = libxl__build_pre(ctx, domid, info, state); - if (ret) - goto out; - - gettimeofday(&start_time, NULL); - - if (info->hvm) { - ret = libxl__build_hvm(ctx, domid, info, state); - if (ret) - goto out; - - vments = libxl__calloc(&gc, 7, sizeof(char *)); - vments[0] = "rtc/timeoffset"; - vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; - vments[2] = "image/ostype"; - vments[3] = "hvm"; - vments[4] = "start_time"; - vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); - } else { - ret = libxl__build_pv(ctx, domid, info, state); - if (ret) - goto out; - - vments = libxl__calloc(&gc, 11, sizeof(char *)); - i = 0; - vments[i++] = "image/ostype"; - vments[i++] = "linux"; - vments[i++] = "image/kernel"; - vments[i++] = (char*) info->kernel.path; - vments[i++] = "start_time"; - vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); - if (info->u.pv.ramdisk.path) { - vments[i++] = "image/ramdisk"; - vments[i++] = (char*) info->u.pv.ramdisk.path; - } - if (info->u.pv.cmdline) { - vments[i++] = "image/cmdline"; - vments[i++] = (char*) info->u.pv.cmdline; - } - } - ret = libxl__build_post(ctx, domid, info, state, vments, localents); -out: - libxl__file_reference_unmap(&info->kernel); - if (!info->hvm) - libxl__file_reference_unmap(&info->u.pv.ramdisk); - - libxl__free_all(&gc); - return ret; -} - -int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, - uint32_t domid, int fd, libxl_domain_build_state *state, - libxl_device_model_info *dm_info) -{ - libxl__gc gc = LIBXL_INIT_GC(ctx); - char **vments = NULL, **localents = NULL; - struct timeval start_time; - int i, ret, esave, flags; - - ret = libxl__build_pre(ctx, domid, info, state); - if (ret) - goto out; - - ret = libxl__domain_restore_common(ctx, domid, info, state, fd); - if (ret) - goto out; - - gettimeofday(&start_time, NULL); - - if (info->hvm) { - vments = libxl__calloc(&gc, 7, sizeof(char *)); - vments[0] = "rtc/timeoffset"; - vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; - vments[2] = "image/ostype"; - vments[3] = "hvm"; - vments[4] = "start_time"; - vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); - } else { - vments = libxl__calloc(&gc, 11, sizeof(char *)); - i = 0; - vments[i++] = "image/ostype"; - vments[i++] = "linux"; - vments[i++] = "image/kernel"; - vments[i++] = (char*) info->kernel.path; - vments[i++] = "start_time"; - vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); - if (info->u.pv.ramdisk.path) { - vments[i++] = "image/ramdisk"; - vments[i++] = (char*) info->u.pv.ramdisk.path; - } - if (info->u.pv.cmdline) { - vments[i++] = "image/cmdline"; - vments[i++] = (char*) info->u.pv.cmdline; - } - } - ret = libxl__build_post(ctx, domid, info, state, vments, localents); - if (ret) - goto out; - - dm_info->saved_state = NULL; - if (info->hvm) { - ret = asprintf(&dm_info->saved_state, - "/var/lib/xen/qemu-save.%d", domid); - ret = (ret < 0) ? ERROR_FAIL : 0; - } - -out: - libxl__file_reference_unmap(&info->kernel); - if (!info->hvm) - libxl__file_reference_unmap(&info->u.pv.ramdisk); - - esave = errno; - - flags = fcntl(fd, F_GETFL); - if (flags == -1) { - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd"); - } else { - flags &= ~O_NONBLOCK; - if (fcntl(fd, F_SETFL, flags) == -1) - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd" - " back to blocking mode"); - } - - errno = esave; - libxl__free_all(&gc); - return ret; -} - int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid) { libxl__gc gc = LIBXL_INIT_GC(ctx); diff -r 02773e0763a0 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/libxl.h Fri Jan 07 15:26:59 2011 +0000 @@ -241,6 +241,38 @@ enum { #define LIBXL_VERSION 0 +enum libxl_action_on_shutdown { + LIBXL_ACTION_DESTROY, + + LIBXL_ACTION_RESTART, + LIBXL_ACTION_RESTART_RENAME, + + LIBXL_ACTION_PRESERVE, + + LIBXL_ACTION_COREDUMP_DESTROY, + LIBXL_ACTION_COREDUMP_RESTART, +}; + +typedef struct { + libxl_domain_create_info c_info; + libxl_domain_build_info b_info; + libxl_device_model_info dm_info; + + int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs; + + libxl_device_disk *disks; + libxl_device_nic *vifs; + libxl_device_net2 *vif2s; + libxl_device_pci *pcidevs; + libxl_device_vfb *vfbs; + libxl_device_vkb *vkbs; + + enum libxl_action_on_shutdown on_poweroff; + enum libxl_action_on_shutdown on_reboot; + enum libxl_action_on_shutdown on_watchdog; + enum libxl_action_on_shutdown on_crash; +} libxl_domain_config; + /* context functions */ int libxl_ctx_init(libxl_ctx *ctx, int version, xentoollog_logger*); int libxl_ctx_free(libxl_ctx *ctx); @@ -248,11 +280,10 @@ int libxl_ctx_set_log(libxl_ctx *ctx, xe int libxl_ctx_postfork(libxl_ctx *ctx); /* domain related functions */ -int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid); -int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state); -int libxl_domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, - uint32_t domid, int fd, libxl_domain_build_state *state, - libxl_device_model_info *dm_info); +typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv); +int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid); +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); +void libxl_domain_config_destroy(libxl_domain_config *d_config); int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, uint32_t domid, int fd); int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid); @@ -375,27 +406,6 @@ libxl_dominfo * libxl_list_domain(libxl_ libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool); libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm); -typedef struct libxl__device_model_starting libxl_device_model_starting; -int libxl_create_device_model(libxl_ctx *ctx, - libxl_device_model_info *info, - libxl_device_disk *disk, int num_disks, - libxl_device_nic *vifs, int num_vifs, - libxl_device_model_starting **starting_r); -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, - libxl_device_model_starting **starting_r); -int libxl_need_xenpv_qemu(libxl_ctx *ctx, - int nr_consoles, libxl_device_console *consoles, - int nr_vfbs, libxl_device_vfb *vfbs, - int nr_disks, libxl_device_disk *disks); - /* Caller must either: pass starting_r==0, or on successful - * return pass *starting_r (which will be non-0) to - * libxl_confirm_device_model or libxl_detach_device_model. */ -int libxl_confirm_device_model_startup(libxl_ctx *ctx, - libxl_device_model_starting *starting); -int libxl_detach_device_model(libxl_ctx *ctx, - libxl_device_model_starting *starting); - /* DM is detached even if error is returned */ - int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk); int libxl_device_disk_del(libxl_ctx *ctx, libxl_device_disk *disk, int wait); libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int *num); diff -r 02773e0763a0 tools/libxl/libxl_create.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxl/libxl_create.c Fri Jan 07 15:26:59 2011 +0000 @@ -0,0 +1,482 @@ +/* + * Copyright (C) 2010 Citrix Ltd. + * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com> + * Author Stefano Stabellini <stefano.stabellini@eu.citrix.com> + * Author Gianni Tedesco <gianni.tedesco@citrix.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_osdeps.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include "libxl.h" +#include "libxl_utils.h" +#include "libxl_internal.h" +#include "flexarray.h" + +void libxl_domain_config_destroy(libxl_domain_config *d_config) +{ + int i; + + for (i=0; i<d_config->num_disks; i++) + libxl_device_disk_destroy(&d_config->disks[i]); + free(d_config->disks); + + for (i=0; i<d_config->num_vifs; i++) + libxl_device_nic_destroy(&d_config->vifs[i]); + free(d_config->vifs); + + for (i=0; i<d_config->num_vif2s; i++) + libxl_device_net2_destroy(&d_config->vif2s[i]); + free(d_config->vif2s); + + for (i=0; i<d_config->num_pcidevs; i++) + libxl_device_pci_destroy(&d_config->pcidevs[i]); + free(d_config->pcidevs); + + for (i=0; i<d_config->num_vfbs; i++) + libxl_device_vfb_destroy(&d_config->vfbs[i]); + free(d_config->vfbs); + + for (i=0; i<d_config->num_vkbs; i++) + libxl_device_vkb_destroy(&d_config->vkbs[i]); + free(d_config->vkbs); + + libxl_domain_create_info_destroy(&d_config->c_info); + libxl_domain_build_info_destroy(&d_config->b_info); + libxl_device_model_info_destroy(&d_config->dm_info); +} + +static int init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state) +{ + memset(console, 0x00, sizeof(libxl_device_console)); + console->devid = dev_num; + console->consback = LIBXL_CONSBACK_XENCONSOLED; + console->output = strdup("pty"); + if ( NULL == console->output ) + return ERROR_NOMEM; + if (state) + console->build_state = state; + return 0; +} + +int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, libxl_domain_build_state *state) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + char **vments = NULL, **localents = NULL; + struct timeval start_time; + int i, ret; + + ret = libxl__build_pre(ctx, domid, info, state); + if (ret) + goto out; + + gettimeofday(&start_time, NULL); + + if (info->hvm) { + ret = libxl__build_hvm(ctx, domid, info, state); + if (ret) + goto out; + + vments = libxl__calloc(&gc, 7, sizeof(char *)); + vments[0] = "rtc/timeoffset"; + vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; + vments[2] = "image/ostype"; + vments[3] = "hvm"; + vments[4] = "start_time"; + vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + } else { + ret = libxl__build_pv(ctx, domid, info, state); + if (ret) + goto out; + + vments = libxl__calloc(&gc, 11, sizeof(char *)); + i = 0; + vments[i++] = "image/ostype"; + vments[i++] = "linux"; + vments[i++] = "image/kernel"; + vments[i++] = (char*) info->kernel.path; + vments[i++] = "start_time"; + vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + if (info->u.pv.ramdisk.path) { + vments[i++] = "image/ramdisk"; + vments[i++] = (char*) info->u.pv.ramdisk.path; + } + if (info->u.pv.cmdline) { + vments[i++] = "image/cmdline"; + vments[i++] = (char*) info->u.pv.cmdline; + } + } + ret = libxl__build_post(ctx, domid, info, state, vments, localents); +out: + libxl__file_reference_unmap(&info->kernel); + if (!info->hvm) + libxl__file_reference_unmap(&info->u.pv.ramdisk); + + libxl__free_all(&gc); + return ret; +} + +static int domain_restore(libxl_ctx *ctx, libxl_domain_build_info *info, + uint32_t domid, int fd, libxl_domain_build_state *state, + libxl_device_model_info *dm_info) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + char **vments = NULL, **localents = NULL; + struct timeval start_time; + int i, ret, esave, flags; + + ret = libxl__build_pre(ctx, domid, info, state); + if (ret) + goto out; + + ret = libxl__domain_restore_common(ctx, domid, info, state, fd); + if (ret) + goto out; + + gettimeofday(&start_time, NULL); + + if (info->hvm) { + vments = libxl__calloc(&gc, 7, sizeof(char *)); + vments[0] = "rtc/timeoffset"; + vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : ""; + vments[2] = "image/ostype"; + vments[3] = "hvm"; + vments[4] = "start_time"; + vments[5] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + } else { + vments = libxl__calloc(&gc, 11, sizeof(char *)); + i = 0; + vments[i++] = "image/ostype"; + vments[i++] = "linux"; + vments[i++] = "image/kernel"; + vments[i++] = (char*) info->kernel.path; + vments[i++] = "start_time"; + vments[i++] = libxl__sprintf(&gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000); + if (info->u.pv.ramdisk.path) { + vments[i++] = "image/ramdisk"; + vments[i++] = (char*) info->u.pv.ramdisk.path; + } + if (info->u.pv.cmdline) { + vments[i++] = "image/cmdline"; + vments[i++] = (char*) info->u.pv.cmdline; + } + } + ret = libxl__build_post(ctx, domid, info, state, vments, localents); + if (ret) + goto out; + + dm_info->saved_state = NULL; + if (info->hvm) { + ret = asprintf(&dm_info->saved_state, + "/var/lib/xen/qemu-save.%d", domid); + ret = (ret < 0) ? ERROR_FAIL : 0; + } + +out: + libxl__file_reference_unmap(&info->kernel); + if (!info->hvm) + libxl__file_reference_unmap(&info->u.pv.ramdisk); + + esave = errno; + + flags = fcntl(fd, F_GETFL); + if (flags == -1) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to get flags on restore fd"); + } else { + flags &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, flags) == -1) + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unable to put restore fd" + " back to blocking mode"); + } + + errno = esave; + libxl__free_all(&gc); + return ret; +} + +int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, + uint32_t *domid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int flags, ret, i, rc; + char *uuid_string; + char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"}; + char *ro_paths[] = { "cpu", "memory", "device", "error", "drivers", + "control", "attr", "messages" }; + char *dom_path, *vm_path; + struct xs_permissions roperm[2]; + struct xs_permissions rwperm[1]; + xs_transaction_t t; + xen_domain_handle_t handle; + + uuid_string = libxl__uuid2string(&gc, info->uuid); + if (!uuid_string) { + libxl__free_all(&gc); + return ERROR_NOMEM; + } + + flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0; + flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0; + flags |= info->oos ? 0 : XEN_DOMCTL_CDF_oos_off; + *domid = -1; + + /* Ultimately, handle is an array of 16 uint8_t, same as uuid */ + libxl_uuid_copy((libxl_uuid *)handle, &info->uuid); + + ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid); + if (ret < 0) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail"); + libxl__free_all(&gc); + return ERROR_FAIL; + } + + ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid); + if (ret < 0) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail"); + libxl__free_all(&gc); + return ERROR_FAIL; + } + + dom_path = libxl__xs_get_dompath(&gc, *domid); + if (!dom_path) { + libxl__free_all(&gc); + return ERROR_FAIL; + } + + vm_path = libxl__sprintf(&gc, "/vm/%s", uuid_string); + if (!vm_path) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths"); + libxl__free_all(&gc); + return ERROR_FAIL; + } + + roperm[0].id = 0; + roperm[0].perms = XS_PERM_NONE; + roperm[1].id = *domid; + roperm[1].perms = XS_PERM_READ; + rwperm[0].id = *domid; + rwperm[0].perms = XS_PERM_NONE; + +retry_transaction: + t = xs_transaction_start(ctx->xsh); + xs_rm(ctx->xsh, t, dom_path); + xs_mkdir(ctx->xsh, t, dom_path); + xs_set_permissions(ctx->xsh, t, dom_path, roperm, ARRAY_SIZE(roperm)); + + xs_rm(ctx->xsh, t, vm_path); + xs_mkdir(ctx->xsh, t, vm_path); + xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm)); + + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/vm", dom_path), vm_path, strlen(vm_path)); + rc = libxl_domain_rename(ctx, *domid, 0, info->name, t); + if (rc) { + libxl__free_all(&gc); + return rc; + } + + for (i = 0; i < ARRAY_SIZE(rw_paths); i++) { + char *path = libxl__sprintf(&gc, "%s/%s", dom_path, rw_paths[i]); + xs_mkdir(ctx->xsh, t, path); + xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm)); + } + for (i = 0; i < ARRAY_SIZE(ro_paths); i++) { + char *path = libxl__sprintf(&gc, "%s/%s", dom_path, ro_paths[i]); + xs_mkdir(ctx->xsh, t, path); + xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm)); + } + + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string)); + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/name", vm_path), info->name, strlen(info->name)); + if (info->poolname) + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), info->poolname, strlen(info->poolname)); + + libxl__xs_writev(&gc, t, dom_path, info->xsdata); + libxl__xs_writev(&gc, t, libxl__sprintf(&gc, "%s/platform", dom_path), info->platformdata); + + xs_write(ctx->xsh, t, libxl__sprintf(&gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1); + if (!xs_transaction_end(ctx->xsh, t, 0)) + if (errno == EAGAIN) + goto retry_transaction; + + libxl__free_all(&gc); + return 0; +} + +static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config, + libxl_console_ready cb, void *priv, + uint32_t *domid_out, int restore_fd) +{ + libxl__device_model_starting *dm_starting = 0; + libxl_device_model_info *dm_info = &d_config->dm_info; + libxl_domain_build_state state; + uint32_t domid; + int i, ret; + + domid = 0; + + ret = libxl__domain_make(ctx, &d_config->c_info, &domid); + if (ret) { + fprintf(stderr, "cannot make domain: %d\n", ret); + ret = ERROR_FAIL; + goto error_out; + } + + if ( !d_config->c_info.hvm && cb ) { + if ( (*cb)(ctx, domid, priv) ) + goto error_out; + } + + if ( restore_fd < 0 ) { + ret = libxl_run_bootloader(ctx, &d_config->b_info, d_config->num_disks > 0 ? &d_config->disks[0] : NULL, domid); + if (ret) { + fprintf(stderr, "failed to run bootloader: %d\n", ret); + goto error_out; + } + } + + if ( restore_fd >= 0 ) { + ret = domain_restore(ctx, &d_config->b_info, domid, restore_fd, &state, dm_info); + } else { + if (dm_info->saved_state) { + free(dm_info->saved_state); + dm_info->saved_state = NULL; + } + ret = libxl__domain_build(ctx, &d_config->b_info, domid, &state); + } + + if (ret) { + fprintf(stderr, "cannot (re-)build domain: %d\n", ret); + ret = ERROR_FAIL; + goto error_out; + } + + for (i = 0; i < d_config->num_disks; i++) { + d_config->disks[i].domid = domid; + ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]); + if (ret) { + fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret); + ret = ERROR_FAIL; + goto error_out; + } + } + for (i = 0; i < d_config->num_vifs; i++) { + d_config->vifs[i].domid = domid; + ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]); + if (ret) { + fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret); + ret = ERROR_FAIL; + goto error_out; + } + } + if (!d_config->c_info.hvm) { + for (i = 0; i < d_config->num_vif2s; i++) { + d_config->vif2s[i].domid = domid; + ret = libxl_device_net2_add(ctx, domid, &d_config->vif2s[i]); + if (ret) { + fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret); + ret = ERROR_FAIL; + goto error_out; + } + } + } + if (d_config->c_info.hvm) { + libxl_device_console console; + + ret = init_console_info(&console, 0, &state); + if ( ret ) + goto error_out; + console.domid = domid; + libxl_device_console_add(ctx, domid, &console); + libxl_device_console_destroy(&console); + + dm_info->domid = domid; + ret = libxl__create_device_model(ctx, dm_info, + d_config->disks, d_config->num_disks, + d_config->vifs, d_config->num_vifs, + &dm_starting); + if (ret < 0) { + fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__create_device_model\n", + __FILE__,__LINE__, ret); + goto error_out; + } + } else { + int need_qemu = 0; + libxl_device_console console; + + for (i = 0; i < d_config->num_vfbs; i++) { + d_config->vfbs[i].domid = domid; + libxl_device_vfb_add(ctx, domid, &d_config->vfbs[i]); + d_config->vkbs[i].domid = domid; + libxl_device_vkb_add(ctx, domid, &d_config->vkbs[i]); + } + + ret = init_console_info(&console, 0, &state); + if ( ret ) + goto error_out; + console.domid = domid; + + need_qemu = libxl__need_xenpv_qemu(ctx, 1, &console, + d_config->num_vfbs, d_config->vfbs, + d_config->num_disks, &d_config->disks[0]); + + if (need_qemu) + console.consback = LIBXL_CONSBACK_IOEMU; + + libxl_device_console_add(ctx, domid, &console); + libxl_device_console_destroy(&console); + + if (need_qemu) + libxl__create_xenpv_qemu(ctx, domid, d_config->vfbs, &dm_starting); + } + + if (dm_starting) { + ret = libxl__confirm_device_model_startup(ctx, dm_starting); + if (ret < 0) { + fprintf(stderr,"xl: fatal error: %s:%d, rc=%d: libxl__confirm_device_model_startup\n", + __FILE__,__LINE__, ret); + goto error_out; + } + } + + for (i = 0; i < d_config->num_pcidevs; i++) + libxl_device_pci_add(ctx, domid, &d_config->pcidevs[i]); + + if ( d_config->c_info.hvm && cb ) { + if ( (*cb)(ctx, domid, priv) ) + goto error_out; + } + + *domid_out = domid; + return 0; + +error_out: + if (domid) + libxl_domain_destroy(ctx, domid, 0); + + return ret; +} +int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, + libxl_console_ready cb, void *priv, uint32_t *domid) +{ + return do_domain_create(ctx, d_config, cb, priv, domid, -1); +} + +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) +{ + return do_domain_create(ctx, d_config, cb, priv, domid, restore_fd); +} diff -r 02773e0763a0 tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/libxl_dm.c Fri Jan 07 15:26:59 2011 +0000 @@ -324,7 +324,7 @@ static char ** libxl_build_device_model_ static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild) { - libxl_device_model_starting *starting = for_spawn; + libxl__device_model_starting *starting = for_spawn; struct xs_handle *xsh; char *path = NULL, *pid = NULL; int len; @@ -426,7 +426,7 @@ static int libxl_create_stubdom(libxl_ct libxl_device_nic *vifs, int num_vifs, libxl_device_vfb *vfb, libxl_device_vkb *vkb, - libxl_device_model_starting **starting_r) + libxl__device_model_starting **starting_r) { libxl__gc gc = LIBXL_INIT_GC(ctx); int i, num_console = 1, ret; @@ -438,7 +438,7 @@ static int libxl_create_stubdom(libxl_ct char **args; struct xs_permissions perm[2]; xs_transaction_t t; - libxl_device_model_starting *dm_starting = 0; + libxl__device_model_starting *dm_starting = 0; args = libxl_build_device_model_args(&gc, info, vifs, num_vifs); if (!args) { @@ -462,10 +462,10 @@ static int libxl_create_stubdom(libxl_ct b_info.u.pv.features = ""; b_info.hvm = 0; - ret = libxl_domain_make(ctx, &c_info, &domid); + ret = libxl__domain_make(ctx, &c_info, &domid); if (ret) goto out_free; - ret = libxl_domain_build(ctx, &b_info, domid, &state); + ret = libxl__domain_build(ctx, &b_info, domid, &state); if (ret) goto out_free; @@ -545,11 +545,11 @@ retry_transaction: if (ret) goto out_free; } - if (libxl_create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) { + if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) { ret = ERROR_FAIL; goto out_free; } - if (libxl_confirm_device_model_startup(ctx, dm_starting) < 0) { + if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) { ret = ERROR_FAIL; goto out_free; } @@ -557,7 +557,7 @@ retry_transaction: libxl_domain_unpause(ctx, domid); if (starting_r) { - *starting_r = calloc(sizeof(libxl_device_model_starting), 1); + *starting_r = calloc(sizeof(libxl__device_model_starting), 1); (*starting_r)->domid = info->domid; (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid); (*starting_r)->for_spawn = NULL; @@ -572,18 +572,18 @@ out: return ret; } -int libxl_create_device_model(libxl_ctx *ctx, +int libxl__create_device_model(libxl_ctx *ctx, libxl_device_model_info *info, libxl_device_disk *disks, int num_disks, libxl_device_nic *vifs, int num_vifs, - libxl_device_model_starting **starting_r) + libxl__device_model_starting **starting_r) { libxl__gc gc = LIBXL_INIT_GC(ctx); char *path, *logfile; int logfile_w, null; int rc; char **args; - libxl_device_model_starting buf_starting, *p; + libxl__device_model_starting buf_starting, *p; xs_transaction_t t; char *vm_path; char **pass_stuff; @@ -614,7 +614,7 @@ int libxl_create_device_model(libxl_ctx if (starting_r) { rc = ERROR_NOMEM; - *starting_r = calloc(sizeof(libxl_device_model_starting), 1); + *starting_r = calloc(sizeof(libxl__device_model_starting), 1); if (!*starting_r) goto out_close; p = *starting_r; @@ -668,8 +668,8 @@ out: return rc; } -int libxl_detach_device_model(libxl_ctx *ctx, - libxl_device_model_starting *starting) +static int detach_device_model(libxl_ctx *ctx, + libxl__device_model_starting *starting) { int rc; rc = libxl__spawn_detach(ctx, starting->for_spawn); @@ -680,14 +680,14 @@ int libxl_detach_device_model(libxl_ctx } -int libxl_confirm_device_model_startup(libxl_ctx *ctx, - libxl_device_model_starting *starting) +int libxl__confirm_device_model_startup(libxl_ctx *ctx, + libxl__device_model_starting *starting) { int problem = libxl__wait_for_device_model(ctx, starting->domid, "running", NULL, NULL); int detach; if ( !problem ) problem = libxl__spawn_check(ctx, starting->for_spawn); - detach = libxl_detach_device_model(ctx, starting); + detach = detach_device_model(ctx, starting); return problem ? problem : detach; } @@ -760,7 +760,7 @@ static int libxl_build_xenpv_qemu_args(l return 0; } -int libxl_need_xenpv_qemu(libxl_ctx *ctx, +int libxl__need_xenpv_qemu(libxl_ctx *ctx, int nr_consoles, libxl_device_console *consoles, int nr_vfbs, libxl_device_vfb *vfbs, int nr_disks, libxl_device_disk *disks) @@ -793,14 +793,14 @@ out: return ret; } -int libxl_create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, - libxl_device_model_starting **starting_r) +int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, + libxl__device_model_starting **starting_r) { libxl__gc gc = LIBXL_INIT_GC(ctx); libxl_device_model_info info; libxl_build_xenpv_qemu_args(&gc, domid, vfb, &info); - libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); + libxl__create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r); libxl__free_all(&gc); return 0; } diff -r 02773e0763a0 tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/libxl_exec.c Fri Jan 07 15:26:59 2011 +0000 @@ -90,7 +90,7 @@ void libxl_report_child_exitstatus(libxl } int libxl__spawn_spawn(libxl_ctx *ctx, - libxl_device_model_starting *starting, + libxl__device_model_starting *starting, const char *what, void (*intermediate_hook)(void *for_spawn, pid_t innerchild)) diff -r 02773e0763a0 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/libxl_internal.h Fri Jan 07 15:26:59 2011 +0000 @@ -194,14 +194,37 @@ typedef struct { char *what; /* malloc''d in spawn_spawn */ } libxl__spawn_starting; -struct libxl__device_model_starting { +typedef struct { libxl__spawn_starting *for_spawn; /* first! */ char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */ int domid; -}; +} libxl__device_model_starting; + +/* from xl_create */ +_hidden int libxl__domain_make(libxl_ctx *ctx, libxl_domain_create_info *info, uint32_t *domid); +_hidden int libxl__domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state); + +/* for device model creation */ +_hidden int libxl__create_device_model(libxl_ctx *ctx, + libxl_device_model_info *info, + libxl_device_disk *disk, int num_disks, + libxl_device_nic *vifs, int num_vifs, + libxl__device_model_starting **starting_r); +_hidden int libxl__create_xenpv_qemu(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb, + libxl__device_model_starting **starting_r); +_hidden int libxl__need_xenpv_qemu(libxl_ctx *ctx, + int nr_consoles, libxl_device_console *consoles, + int nr_vfbs, libxl_device_vfb *vfbs, + int nr_disks, libxl_device_disk *disks); + + /* Caller must either: pass starting_r==0, or on successful + * return pass *starting_r (which will be non-0) to + * libxl_confirm_device_model or libxl_detach_device_model. */ +_hidden int libxl__confirm_device_model_startup(libxl_ctx *ctx, + libxl__device_model_starting *starting); _hidden int libxl__spawn_spawn(libxl_ctx *ctx, - libxl_device_model_starting *starting, + libxl__device_model_starting *starting, const char *what, void (*intermediate_hook)(void *for_spawn, pid_t innerchild)); _hidden int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid); diff -r 02773e0763a0 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/libxl/xl_cmdimpl.c Fri Jan 07 15:26:59 2011 +0000 @@ -100,81 +100,18 @@ struct save_file_header { }; -enum action_on_shutdown { - ACTION_DESTROY, - - ACTION_RESTART, - ACTION_RESTART_RENAME, - - ACTION_PRESERVE, - - ACTION_COREDUMP_DESTROY, - ACTION_COREDUMP_RESTART, +static const char *action_on_shutdown_names[] = { + [LIBXL_ACTION_DESTROY] = "destroy", + + [LIBXL_ACTION_RESTART] = "restart", + [LIBXL_ACTION_RESTART_RENAME] = "rename-restart", + + [LIBXL_ACTION_PRESERVE] = "preserve", + + [LIBXL_ACTION_COREDUMP_DESTROY] = "coredump-destroy", + [LIBXL_ACTION_COREDUMP_RESTART] = "coredump-restart", }; -static const char *action_on_shutdown_names[] = { - [ACTION_DESTROY] = "destroy", - - [ACTION_RESTART] = "restart", - [ACTION_RESTART_RENAME] = "rename-restart", - - [ACTION_PRESERVE] = "preserve", - - [ACTION_COREDUMP_DESTROY] = "coredump-destroy", - [ACTION_COREDUMP_RESTART] = "coredump-restart", -}; - -struct domain_config { - libxl_domain_create_info c_info; - libxl_domain_build_info b_info; - - int num_disks, num_vifs, num_vif2s, num_pcidevs, num_vfbs, num_vkbs; - - libxl_device_disk *disks; - libxl_device_nic *vifs; - libxl_device_net2 *vif2s; - libxl_device_pci *pcidevs; - libxl_device_vfb *vfbs; - libxl_device_vkb *vkbs; - - enum action_on_shutdown on_poweroff; - enum action_on_shutdown on_reboot; - enum action_on_shutdown on_watchdog; - enum action_on_shutdown on_crash; -}; - -static void free_domain_config(struct domain_config *d_config) -{ - int i; - - for (i=0; i<d_config->num_disks; i++) - libxl_device_disk_destroy(&d_config->disks[i]); - free(d_config->disks); - - for (i=0; i<d_config->num_vifs; i++) - libxl_device_nic_destroy(&d_config->vifs[i]); - free(d_config->vifs); - - for (i=0; i<d_config->num_vif2s; i++) - libxl_device_net2_destroy(&d_config->vif2s[i]); - free(d_config->vif2s); - - for (i=0; i<d_config->num_pcidevs; i++) - libxl_device_pci_destroy(&d_config->pcidevs[i]); - free(d_config->pcidevs); - - for (i=0; i<d_config->num_vfbs; i++) - libxl_device_vfb_destroy(&d_config->vfbs[i]); - free(d_config->vfbs); - - for (i=0; i<d_config->num_vkbs; i++) - libxl_device_vkb_destroy(&d_config->vkbs[i]); - free(d_config->vkbs); - - libxl_domain_create_info_destroy(&d_config->c_info); - libxl_domain_build_info_destroy(&d_config->b_info); -} - /* Optional data, in order: * 4 bytes uint32_t config file size * n bytes config file in Unix text file format @@ -458,18 +395,8 @@ static void init_vkb_info(libxl_device_v vkb->devid = dev_num; } -static void init_console_info(libxl_device_console *console, int dev_num, libxl_domain_build_state *state) -{ - memset(console, 0x00, sizeof(libxl_device_console)); - console->devid = dev_num; - console->consback = LIBXL_CONSBACK_XENCONSOLED; - console->output = strdup("pty"); - if (state) - console->build_state = state; -} - static void printf_info(int domid, - struct domain_config *d_config, + libxl_domain_config *d_config, libxl_device_model_info *dm_info) { int i; @@ -626,7 +553,7 @@ static void printf_info(int domid, printf(")\n"); } -static int parse_action_on_shutdown(const char *buf, enum action_on_shutdown *a) +static int parse_action_on_shutdown(const char *buf, enum libxl_action_on_shutdown *a) { int i; const char *n; @@ -773,7 +700,7 @@ out: static void parse_config_data(const char *configfile_filename_report, const char *configfile_data, int configfile_len, - struct domain_config *d_config, + libxl_domain_config *d_config, libxl_device_model_info *dm_info) { const char *buf; @@ -1316,32 +1243,12 @@ static void *xrealloc(void *ptr, size_t return r; } -static pid_t autoconnect_console(void) -{ - pid_t pid; - - pid = fork(); - if (pid < 0) { - perror("unable to fork xenconsole"); - return ERROR_FAIL; - } else if (pid > 0) - return pid; - - libxl_ctx_postfork(&ctx); - - sleep(1); - libxl_primary_console_exec(&ctx, domid); - /* Do not return. xl continued in child process */ - fprintf(stderr, "Unable to attach console\n"); - _exit(1); -} - /* Returns 1 if domain should be restarted, 2 if domain should be renamed then restarted */ static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *event, - struct domain_config *d_config, libxl_dominfo *info) + libxl_domain_config *d_config, libxl_dominfo *info) { int restart = 0; - enum action_on_shutdown action; + enum libxl_action_on_shutdown action; switch (info->shutdown_reason) { case SHUTDOWN_poweroff: @@ -1360,12 +1267,12 @@ static int handle_domain_death(libxl_ctx break; default: LOG("Unknown shutdown reason code %d. Destroying domain.", info->shutdown_reason); - action = ACTION_DESTROY; + action = LIBXL_ACTION_DESTROY; } LOG("Action for shutdown reason code %d is %s", info->shutdown_reason, action_on_shutdown_names[action]); - if (action == ACTION_COREDUMP_DESTROY || action == ACTION_COREDUMP_RESTART) { + if (action == LIBXL_ACTION_COREDUMP_DESTROY || action == LIBXL_ACTION_COREDUMP_RESTART) { char *corefile; int rc; @@ -1378,30 +1285,30 @@ static int handle_domain_death(libxl_ctx } /* No point crying over spilled milk, continue on failure. */ - if (action == ACTION_COREDUMP_DESTROY) - action = ACTION_DESTROY; + if (action == LIBXL_ACTION_COREDUMP_DESTROY) + action = LIBXL_ACTION_DESTROY; else - action = ACTION_RESTART; + action = LIBXL_ACTION_RESTART; } switch (action) { - case ACTION_PRESERVE: + case LIBXL_ACTION_PRESERVE: break; - case ACTION_RESTART_RENAME: + case LIBXL_ACTION_RESTART_RENAME: restart = 2; break; - case ACTION_RESTART: + case LIBXL_ACTION_RESTART: restart = 1; /* fall-through */ - case ACTION_DESTROY: + case LIBXL_ACTION_DESTROY: LOG("Domain %d needs to be cleaned up: destroying the domain", domid); libxl_domain_destroy(ctx, domid, 0); break; - case ACTION_COREDUMP_DESTROY: - case ACTION_COREDUMP_RESTART: + case LIBXL_ACTION_COREDUMP_DESTROY: + case LIBXL_ACTION_COREDUMP_RESTART: /* Already handled these above. */ abort(); } @@ -1410,7 +1317,7 @@ static int handle_domain_death(libxl_ctx } static int preserve_domain(libxl_ctx *ctx, uint32_t domid, libxl_event *event, - struct domain_config *d_config, libxl_dominfo *info) + libxl_domain_config *d_config, libxl_dominfo *info) { time_t now; struct tm tm; @@ -1501,12 +1408,29 @@ static int freemem(libxl_domain_build_in return ERROR_NOMEM; } +static int autoconnect_console(libxl_ctx *ctx, uint32_t domid, void *priv) +{ + pid_t *pid = priv; + + *pid = fork(); + if (*pid < 0) { + perror("unable to fork xenconsole"); + return ERROR_FAIL; + } else if (*pid > 0) + return 0; + + libxl_ctx_postfork(ctx); + + sleep(1); + libxl_primary_console_exec(ctx, domid); + /* Do not return. xl continued in child process */ + fprintf(stderr, "Unable to attach console\n"); + _exit(1); +} + static int create_domain(struct domain_create *dom_info) { - struct domain_config d_config; - - libxl_domain_build_state state; - libxl_device_model_info dm_info; + libxl_domain_config d_config; int debug = dom_info->debug; int daemonize = dom_info->daemonize; @@ -1516,20 +1440,19 @@ static int create_domain(struct domain_c const char *restore_file = dom_info->restore_file; int migrate_fd = dom_info->migrate_fd; - int i, fd; + int fd; int need_daemon = 1; int ret, rc; - libxl_device_model_starting *dm_starting = 0; libxl_waiter *w1 = NULL, *w2 = NULL; void *config_data = 0; int config_len = 0; int restore_fd = -1; + int status = 0; + libxl_console_ready cb; + pid_t child_console_pid = -1; struct save_file_header hdr; - pid_t child_console_pid = -1; - int status = 0; memset(&d_config, 0x00, sizeof(d_config)); - memset(&dm_info, 0x00, sizeof(dm_info)); if (restore_file) { uint8_t *optdata_begin = 0; @@ -1629,7 +1552,7 @@ static int create_domain(struct domain_c if (!dom_info->quiet) printf("Parsing config file %s\n", config_file); - parse_config_data(config_file, config_data, config_len, &d_config, &dm_info); + parse_config_data(config_file, config_data, config_len, &d_config, &d_config.dm_info); ret = 0; if (dom_info->dryrun) @@ -1654,7 +1577,7 @@ static int create_domain(struct domain_c } if (debug) - printf_info(-1, &d_config, &dm_info); + printf_info(-1, &d_config, &d_config.dm_info); start: domid = 0; @@ -1663,20 +1586,13 @@ start: if (rc < 0) goto error_out; - ret = freemem(&d_config.b_info, &dm_info); + ret = freemem(&d_config.b_info, &d_config.dm_info); if (ret < 0) { fprintf(stderr, "failed to free memory for the domain\n"); ret = ERROR_FAIL; goto error_out; } - ret = libxl_domain_make(&ctx, &d_config.c_info, &domid); - if (ret) { - fprintf(stderr, "cannot make domain: %d\n", ret); - ret = ERROR_FAIL; - goto error_out; - } - ret = libxl_userdata_store(&ctx, domid, "xl", config_data, config_len); if (ret) { @@ -1685,116 +1601,22 @@ start: goto error_out; } - if (dom_info->console_autoconnect && !d_config.c_info.hvm) { - child_console_pid = autoconnect_console(); - if (child_console_pid < 0) - goto error_out; - } - - if (!restore_file) { - ret = libxl_run_bootloader(&ctx, &d_config.b_info, d_config.num_disks > 0 ? &d_config.disks[0] : NULL, domid); - if (ret) { - fprintf(stderr, "failed to run bootloader: %d\n", ret); - goto error_out; - } - } - - if (!restore_file || !need_daemon) { - if (dm_info.saved_state) { - free(dm_info.saved_state); - dm_info.saved_state = NULL; - } - ret = libxl_domain_build(&ctx, &d_config.b_info, domid, &state); - } else { - ret = libxl_domain_restore(&ctx, &d_config.b_info, domid, restore_fd, &state, &dm_info); - } - - if (ret) { - fprintf(stderr, "cannot (re-)build domain: %d\n", ret); - ret = ERROR_FAIL; + if ( dom_info->console_autoconnect ) { + cb = autoconnect_console; + }else{ + cb = NULL; + } + + if ( restore_file ) { + ret = libxl_domain_create_restore(&ctx, &d_config, + cb, &child_console_pid, + &domid, restore_fd); + }else{ + ret = libxl_domain_create_new(&ctx, &d_config, + cb, &child_console_pid, &domid); + } + if ( ret ) goto error_out; - } - - for (i = 0; i < d_config.num_disks; i++) { - d_config.disks[i].domid = domid; - ret = libxl_device_disk_add(&ctx, domid, &d_config.disks[i]); - if (ret) { - fprintf(stderr, "cannot add disk %d to domain: %d\n", i, ret); - ret = ERROR_FAIL; - goto error_out; - } - } - for (i = 0; i < d_config.num_vifs; i++) { - d_config.vifs[i].domid = domid; - ret = libxl_device_nic_add(&ctx, domid, &d_config.vifs[i]); - if (ret) { - fprintf(stderr, "cannot add nic %d to domain: %d\n", i, ret); - ret = ERROR_FAIL; - goto error_out; - } - } - if (!d_config.c_info.hvm) { - for (i = 0; i < d_config.num_vif2s; i++) { - d_config.vif2s[i].domid = domid; - ret = libxl_device_net2_add(&ctx, domid, &d_config.vif2s[i]); - if (ret) { - fprintf(stderr, "cannot add net2 %d to domain: %d\n", i, ret); - ret = ERROR_FAIL; - goto error_out; - } - } - } - if (d_config.c_info.hvm) { - libxl_device_console console; - - init_console_info(&console, 0, &state); - console.domid = domid; - libxl_device_console_add(&ctx, domid, &console); - libxl_device_console_destroy(&console); - - dm_info.domid = domid; - MUST( libxl_create_device_model(&ctx, &dm_info, - d_config.disks, d_config.num_disks, - d_config.vifs, d_config.num_vifs, - &dm_starting) ); - } else { - int need_qemu = 0; - libxl_device_console console; - - for (i = 0; i < d_config.num_vfbs; i++) { - d_config.vfbs[i].domid = domid; - libxl_device_vfb_add(&ctx, domid, &d_config.vfbs[i]); - d_config.vkbs[i].domid = domid; - libxl_device_vkb_add(&ctx, domid, &d_config.vkbs[i]); - } - - init_console_info(&console, 0, &state); - console.domid = domid; - - need_qemu = libxl_need_xenpv_qemu(&ctx, 1, &console, - d_config.num_vfbs, d_config.vfbs, - d_config.num_disks, &d_config.disks[0]); - - if (need_qemu) - console.consback = LIBXL_CONSBACK_IOEMU; - - libxl_device_console_add(&ctx, domid, &console); - libxl_device_console_destroy(&console); - - if (need_qemu) - libxl_create_xenpv_qemu(&ctx, domid, d_config.vfbs, &dm_starting); - } - - if (dm_starting) - MUST( libxl_confirm_device_model_startup(&ctx, dm_starting) ); - for (i = 0; i < d_config.num_pcidevs; i++) - libxl_device_pci_add(&ctx, domid, &d_config.pcidevs[i]); - - if (dom_info->console_autoconnect && d_config.c_info.hvm) { - child_console_pid = autoconnect_console(); - if (child_console_pid < 0) - goto error_out; - } release_lock(); @@ -1812,6 +1634,8 @@ start: child1 = libxl_fork(&ctx); if (child1) { + printf("Daemon running with PID %d\n", child1); + for (;;) { got_child = waitpid(child1, &status, 0); if (got_child == child1) break; @@ -1953,9 +1777,7 @@ out: if (logfile != 2) close(logfile); - libxl_device_model_info_destroy(&dm_info); - - free_domain_config(&d_config); + libxl_domain_config_destroy(&d_config); free(config_data); @@ -2550,7 +2372,7 @@ static void reboot_domain(const char *p) static void list_domains_details(const libxl_dominfo *info, int nb_domain) { - struct domain_config d_config; + libxl_domain_config d_config; char *config_file; uint8_t *data; @@ -2568,7 +2390,7 @@ static void list_domains_details(const l memset(&d_config, 0x00, sizeof(d_config)); parse_config_data(config_file, (char *)data, len, &d_config, &dm_info); printf_info(info[i].domid, &d_config, &dm_info); - free_domain_config(&d_config); + libxl_domain_config_destroy(&d_config); free(data); free(config_file); } diff -r 02773e0763a0 tools/ocaml/libs/xl/xl_stubs.c --- a/tools/ocaml/libs/xl/xl_stubs.c Fri Jan 07 15:26:04 2011 +0000 +++ b/tools/ocaml/libs/xl/xl_stubs.c Fri Jan 07 15:26:59 2011 +0000 @@ -68,16 +68,6 @@ void log_destroy(struct xentoollog_logge caml_leave_blocking_section(); \ libxl_ctx_free(&ctx) -static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size) -{ - void *ptr; - ptr = calloc(nmemb, size); - if (!ptr) - caml_raise_out_of_memory(); - gc->ptrs[gc->offset++] = ptr; - return ptr; -} - static char * dup_String_val(caml_gc *gc, value s) { int len; @@ -106,6 +96,17 @@ void failwith_xl(char *fname, struct cam caml_raise_with_string(*caml_named_value("xl.error"), s); } +#if 0 /* TODO: wrap libxl_domain_create(), these functions will be needed then */ +static void * gc_calloc(caml_gc *gc, size_t nmemb, size_t size) +{ + void *ptr; + ptr = calloc(nmemb, size); + if (!ptr) + caml_raise_out_of_memory(); + gc->ptrs[gc->offset++] = ptr; + return ptr; +} + static int string_string_tuple_array_val (caml_gc *gc, char ***c_val, value v) { CAMLparam1(v); @@ -163,7 +164,7 @@ static int domain_build_info_val (caml_g c_val->video_memkb = Int64_val(Field(v, 4)); c_val->shadow_memkb = Int64_val(Field(v, 5)); c_val->kernel.path = dup_String_val(gc, Field(v, 6)); - c_val->hvm = Tag_val(Field(v, 7)) == 0; + c_val->is_hvm = Tag_val(Field(v, 7)) == 0; infopriv = Field(Field(v, 7), 0); if (c_val->hvm) { c_val->u.hvm.pae = Bool_val(Field(infopriv, 0)); @@ -184,6 +185,7 @@ static int domain_build_info_val (caml_g CAMLreturn(0); } +#endif static int device_disk_val(caml_gc *gc, libxl_device_disk *c_val, value v) { @@ -332,21 +334,6 @@ static value Val_sched_credit(libxl_sche CAMLreturn(v); } -static value Val_domain_build_state(libxl_domain_build_state *c_val) -{ - CAMLparam0(); - CAMLlocal1(v); - - v = caml_alloc_tuple(4); - - Store_field(v, 0, Val_int(c_val->store_port)); - Store_field(v, 1, caml_copy_int64(c_val->store_mfn)); - Store_field(v, 2, Val_int(c_val->console_port)); - Store_field(v, 3, caml_copy_int64(c_val->console_mfn)); - - CAMLreturn(v); -} - static value Val_physinfo(libxl_physinfo *c_val) { CAMLparam0(); @@ -373,52 +360,6 @@ static value Val_physinfo(libxl_physinfo CAMLreturn(v); } -value stub_xl_domain_make(value info) -{ - CAMLparam1(info); - uint32_t domid; - libxl_domain_create_info c_info; - int ret; - INIT_STRUCT(); - - domain_create_info_val (&gc, &c_info, info); - - INIT_CTX(); - - ret = libxl_domain_make(&ctx, &c_info, &domid); - if (ret != 0) - failwith_xl("domain make", &lg); - - FREE_CTX(); - - CAMLreturn(Val_int(domid)); -} - -value stub_xl_domain_build(value info, value domid) -{ - CAMLparam2(info, domid); - CAMLlocal1(result); - libxl_domain_build_info c_info; - libxl_domain_build_state c_state; - int ret; - int c_domid; - INIT_STRUCT(); - - domain_build_info_val (&gc, &c_info, info); - c_domid = Int_val(domid); - - INIT_CTX(); - - ret = libxl_domain_build(&ctx, &c_info, c_domid, &c_state); - if (ret != 0) - failwith_xl("domain_build", &lg); - - result = Val_domain_build_state(&c_state); - FREE_CTX(); - - CAMLreturn(result); -} - value stub_xl_disk_add(value info, value domid) { CAMLparam2(info, domid); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Jan-11 18:30 UTC
Re: [Xen-devel] [PATCH, v3]: xl: Introduce libxl_domain_create_new() and libxl_domain_create_restore()
Gianni Tedesco writes ("[Xen-devel] [PATCH, v3]: xl: 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:Thanks, I have applied this. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel