aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGianni Tedesco <gianni.tedesco@citrix.com>2011-01-11 18:29:43 +0000
committerGianni Tedesco <gianni.tedesco@citrix.com>2011-01-11 18:29:43 +0000
commit760b359388cf4bc948ff6cbf96ab5f629ac45fe5 (patch)
treedd94f75650657c37a6a521560505eda6588576b4
parent64bc47d9a1055404b8c91467d6484ad3434bdde0 (diff)
downloadxen-760b359388cf4bc948ff6cbf96ab5f629ac45fe5.tar.gz
xen-760b359388cf4bc948ff6cbf96ab5f629ac45fe5.tar.bz2
xen-760b359388cf4bc948ff6cbf96ab5f629ac45fe5.zip
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>
-rw-r--r--tools/libxl/Makefile6
-rw-r--r--tools/libxl/libxl.c243
-rw-r--r--tools/libxl/libxl.h62
-rw-r--r--tools/libxl/libxl_create.c482
-rw-r--r--tools/libxl/libxl_dm.c42
-rw-r--r--tools/libxl/libxl_exec.c2
-rw-r--r--tools/libxl/libxl_internal.h29
-rw-r--r--tools/libxl/xl_cmdimpl.c314
-rw-r--r--tools/ocaml/libs/xl/xl_stubs.c85
9 files changed, 651 insertions, 614 deletions
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 4502cb69d2..a139f54b52 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -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 --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index e4e6b54472..08d1bcb6e4 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -104,114 +104,6 @@ void libxl_key_value_list_destroy(libxl_key_value_list *pkvl)
/******************************************************************************/
-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, uint32_t domid,
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 --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 6e141a779e..ea1ed36aee 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -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, xentoollog_logger*);
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_ctx*, int *nb_domain);
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 --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
new file mode 100644
index 0000000000..43fa6691f5
--- /dev/null
+++ b/tools/libxl/libxl_create.c
@@ -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 --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 86994eae15..cffec4b515 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -324,7 +324,7 @@ static char ** libxl_build_device_model_args(libxl__gc *gc,
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_ctx *ctx,
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_ctx *ctx,
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_ctx *ctx,
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 *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 *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(libxl__gc *gc,
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 --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c
index 31980fb1ba..6c212209f3 100644
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -90,7 +90,7 @@ void libxl_report_child_exitstatus(libxl_ctx *ctx,
}
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 --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 8b07224b88..44b7e25d26 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -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 --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 446078d5ba..dbe9000a06 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -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[] = {
- [ACTION_DESTROY] = "destroy",
+ [LIBXL_ACTION_DESTROY] = "destroy",
- [ACTION_RESTART] = "restart",
- [ACTION_RESTART_RENAME] = "rename-restart",
+ [LIBXL_ACTION_RESTART] = "restart",
+ [LIBXL_ACTION_RESTART_RENAME] = "rename-restart",
- [ACTION_PRESERVE] = "preserve",
+ [LIBXL_ACTION_PRESERVE] = "preserve",
- [ACTION_COREDUMP_DESTROY] = "coredump-destroy",
- [ACTION_COREDUMP_RESTART] = "coredump-restart",
+ [LIBXL_ACTION_COREDUMP_DESTROY] = "coredump-destroy",
+ [LIBXL_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_vkb *vkb, int dev_num)
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;
@@ -627,7 +554,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;
@@ -774,7 +701,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;
@@ -1319,32 +1246,12 @@ static void *xrealloc(void *ptr, size_t sz) {
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:
@@ -1363,12 +1270,12 @@ static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *even
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;
@@ -1381,30 +1288,30 @@ static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *even
}
/* 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();
}
@@ -1413,7 +1320,7 @@ static int handle_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_event *even
}
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;
@@ -1504,12 +1411,29 @@ static int freemem(libxl_domain_build_info *b_info, libxl_device_model_info *dm_
return ERROR_NOMEM;
}
-static int create_domain(struct domain_create *dom_info)
+static int autoconnect_console(libxl_ctx *ctx, uint32_t domid, void *priv)
{
- struct domain_config d_config;
+ pid_t *pid = priv;
- libxl_domain_build_state state;
- libxl_device_model_info dm_info;
+ *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)
+{
+ libxl_domain_config d_config;
int debug = dom_info->debug;
int daemonize = dom_info->daemonize;
@@ -1519,20 +1443,19 @@ static int create_domain(struct domain_create *dom_info)
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;
- struct save_file_header hdr;
- pid_t child_console_pid = -1;
int status = 0;
+ libxl_console_ready cb;
+ pid_t child_console_pid = -1;
+ struct save_file_header hdr;
memset(&d_config, 0x00, sizeof(d_config));
- memset(&dm_info, 0x00, sizeof(dm_info));
if (restore_file) {
uint8_t *optdata_begin = 0;
@@ -1632,7 +1555,7 @@ static int create_domain(struct domain_create *dom_info)
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)
@@ -1657,7 +1580,7 @@ static int create_domain(struct domain_create *dom_info)
}
if (debug)
- printf_info(-1, &d_config, &dm_info);
+ printf_info(-1, &d_config, &d_config.dm_info);
start:
domid = 0;
@@ -1666,20 +1589,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) {
@@ -1688,116 +1604,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 ( dom_info->console_autoconnect ) {
+ cb = autoconnect_console;
+ }else{
+ cb = NULL;
}
- 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 ( 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) {
- fprintf(stderr, "cannot (re-)build domain: %d\n", ret);
- ret = ERROR_FAIL;
+ 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();
@@ -1815,6 +1637,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;
@@ -1956,9 +1780,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);
@@ -2553,7 +2375,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;
@@ -2571,7 +2393,7 @@ static void list_domains_details(const libxl_dominfo *info, int nb_domain)
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 --git a/tools/ocaml/libs/xl/xl_stubs.c b/tools/ocaml/libs/xl/xl_stubs.c
index 3f7420f1bb..8a78844f12 100644
--- a/tools/ocaml/libs/xl/xl_stubs.c
+++ b/tools/ocaml/libs/xl/xl_stubs.c
@@ -68,16 +68,6 @@ void log_destroy(struct xentoollog_logger *logger)
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 caml_logger *lg)
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_gc *gc, libxl_domain_build_info *c_val, v
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_gc *gc, libxl_domain_build_info *c_val, v
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_sched_credit *c_val)
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 *c_val)
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);