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
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
/******************************************************************************/
-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,
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);
#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);
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);
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);
--- /dev/null
+/*
+ * 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);
+}
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;
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;
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) {
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;
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;
}
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;
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;
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;
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);
}
-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;
}
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)
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;
}
}
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))
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);
};
-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
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;
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;
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;
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:
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;
}
/* 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();
}
}
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;
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;
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;
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)
}
if (debug)
- printf_info(-1, &d_config, &dm_info);
+ printf_info(-1, &d_config, &d_config.dm_info);
start:
domid = 0;
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) {
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();
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;
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);
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;
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);
}
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;
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);
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));
CAMLreturn(0);
}
+#endif
static int device_disk_val(caml_gc *gc, libxl_device_disk *c_val, value v)
{
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();
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);