On Fri, 18 Feb 2011, Jim Fehlig wrote: > +static int > +libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config) > +{ > + virDomainDiskDefPtr *l_disks = def->disks; > + int ndisks = def->ndisks; > + libxl_device_disk *x_disks; > + int i; > + > + if (VIR_ALLOC_N(x_disks, ndisks) < 0) { > + virReportOOMError(); > + return -1; > + } > + > + for (i = 0; i < ndisks; i++) { > + if (l_disks[i]->src && > + (x_disks[i].physpath = strdup(l_disks[i]->src)) == NULL) { > + virReportOOMError(); > + goto error; > + } > + > + if (l_disks[i]->dst && > + (x_disks[i].virtpath = strdup(l_disks[i]->dst)) == NULL) { > + virReportOOMError(); > + goto error; > + } > + > + if (l_disks[i]->driverName) { > + if (STREQ(l_disks[i]->driverName, "tap") || > + STREQ(l_disks[i]->driverName, "tap2")) { > + if (l_disks[i]->driverType && > + STREQ(l_disks[i]->driverType, "qcow2")) > + x_disks[i].phystype = PHYSTYPE_QCOW2; > + else if (l_disks[i]->driverType && > + STREQ(l_disks[i]->driverType, "aio")) > + x_disks[i].phystype = PHYSTYPE_AIO; > + else if (l_disks[i]->driverType && > + STREQ(l_disks[i]->driverType, "vhd")) > + x_disks[i].phystype = PHYSTYPE_VHD; > + } else if (STREQ(l_disks[i]->driverName, "file")) { > + x_disks[i].phystype = PHYSTYPE_FILE; > + } else if (STREQ(l_disks[i]->driverName, "phy")) { > + x_disks[i].phystype = PHYSTYPE_PHY; > + } > + } else { > + /* Default to file?? */ > + x_disks[i].phystype = PHYSTYPE_FILE; > + } few days ago the patch that removes phystype and introduces backend and format has been applied, so this code needs an update ... > diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c > new file mode 100644 > index 0000000..d581e7b > --- /dev/null > +++ b/src/libxl/libxl_driver.c > @@ -0,0 +1,1280 @@ > +/*---------------------------------------------------------------------------*/ > +/* Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. > + * Copyright (C) 2011 Univention GmbH. > + * > + * This library 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; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * This library 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. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with this library; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > +/*---------------------------------------------------------------------------*/ > + > +#include <config.h> > + > +#include <sys/utsname.h> > +#include <libxl.h> > + > +#include "internal.h" > +#include "logging.h" > +#include "virterror_internal.h" > +#include "datatypes.h" > +#include "files.h" > +#include "memory.h" > +#include "event.h" > +#include "uuid.h" > +#include "libxl_driver.h" > +#include "libxl_conf.h" > + > + > +#define VIR_FROM_THIS VIR_FROM_LIBXL > + > +#define LIBXL_DOM_REQ_POWEROFF 0 > +#define LIBXL_DOM_REQ_REBOOT 1 > +#define LIBXL_DOM_REQ_SUSPEND 2 > +#define LIBXL_DOM_REQ_CRASH 3 > +#define LIBXL_DOM_REQ_HALT 4 > + > +static libxlDriverPrivatePtr libxl_driver = NULL; > + > + > +/* Function declarations */ > +static int > +libxlVmStart(virDomainObjPtr vm, bool start_paused); > + > + > +/* Function definitions */ > +static void > +libxlDriverLock(libxlDriverPrivatePtr driver) > +{ > + virMutexLock(&driver->lock); > +} > + > +static void > +libxlDriverUnlock(libxlDriverPrivatePtr driver) > +{ > + virMutexUnlock(&driver->lock); > +} > + > +static void *libxlDomainObjPrivateAlloc(void) > +{ > + libxlDomainObjPrivatePtr priv; > + > + if (VIR_ALLOC(priv) < 0) > + return NULL; > + > + libxl_ctx_init(&priv->ctx, LIBXL_VERSION, libxl_driver->logger); > + priv->waiterFD = -1; > + priv->eventHdl = -1; > + > + return priv; > +} > + > +static void libxlDomainObjPrivateFree(void *data) > +{ > + libxlDomainObjPrivatePtr priv = data; > + > + if (priv->dWaiter) { > + libxl_free_waiter(priv->dWaiter); > + VIR_FREE(priv->dWaiter); > + } > + libxl_ctx_free(&priv->ctx); > + VIR_FREE(priv); > +} > + > +static void libxlEventHandler(int watch, > + int fd, > + int events, > + void *data) > +{ > + libxlDriverPrivatePtr driver = libxl_driver; > + virDomainObjPtr vm = data; > + libxlDomainObjPrivatePtr priv; > + libxl_event event; > + libxl_dominfo info; > + > + libxlDriverLock(driver); > + virDomainObjLock(vm); > + libxlDriverUnlock(driver); > + > + priv = vm->privateData; > + > + memset(&event, 0, sizeof(event)); > + memset(&info, 0, sizeof(info)); > + > + if (priv->waiterFD != fd || priv->eventHdl != watch) { > + virEventRemoveHandle(watch); > + goto cleanup; > + } > + > + if (!(events & VIR_EVENT_HANDLE_READABLE)) { > + goto cleanup; > + } > + > + if (libxl_get_event(&priv->ctx, &event)) { > + goto cleanup; > + } > + > + if (event.type == LIBXL_EVENT_DOMAIN_DEATH) { > + /* libxl_event_get_domain_death_info returns 1 if death > + * event was for this domid */ > + if (libxl_event_get_domain_death_info(&priv->ctx, > + vm->def->id, > + &event, > + &info) != 1) { > + goto cleanup; > + } > + > + virEventRemoveHandle(watch); > + if (info.shutdown_reason == SHUTDOWN_poweroff) { > + libxl_domain_destroy(&priv->ctx, vm->def->id, 0); > + if (vm->persistent) { > + vm->def->id = -1; > + vm->state = VIR_DOMAIN_SHUTOFF; > + } else { > + libxl_free_waiter(priv->dWaiter); > + VIR_FREE(priv->dWaiter); > + virDomainRemoveInactive(&driver->domains, vm); > + vm = NULL; > + } > + } else if (info.shutdown_reason == SHUTDOWN_reboot) { > + libxl_domain_destroy(&priv->ctx, vm->def->id, 0); > + vm->def->id = -1; > + vm->state = VIR_DOMAIN_SHUTOFF; > + sleep(1); > + libxlVmStart(vm, 0); we need to handle at least SHUTDOWN_suspend and SHUTDOWN_crash too > + } else { > + VIR_INFO("Unhandled shutdown_reason %d", info.shutdown_reason); > + } > + } we should call libxl_free_event before returning, otherwise we leak two strings > + > +cleanup: > + if (vm) > + virDomainObjUnlock(vm); > +} > + > +static int > +libxlCreateDomEvents(virDomainObjPtr vm) > +{ > + libxlDomainObjPrivatePtr priv = vm->privateData; > + int fd; > + > + /* Do we already have a waiter for this domain? */ > + if (priv->dWaiter == NULL) { > + if (VIR_ALLOC(priv->dWaiter) < 0) { > + virReportOOMError(); > + return -1; > + } > + > + if (libxl_wait_for_domain_death(&priv->ctx, vm->def->id, priv->dWaiter)) { > + goto error; > + } > + } > + > + libxl_get_wait_fd(&priv->ctx, &fd); > + if (fd < 0) { > + goto error; > + } > + > + priv->waiterFD = fd; > + if ((priv->eventHdl = virEventAddHandle( > + fd, > + VIR_EVENT_HANDLE_READABLE | VIR_EVENT_HANDLE_ERROR, > + libxlEventHandler, > + vm, NULL)) < 0) { > + goto error; > + } > + > + return 0; > + > +error: > + libxl_free_waiter(priv->dWaiter); > + VIR_FREE(priv->dWaiter); > + return -1; > +} > + > +static int > +libxlVmStart(virDomainObjPtr vm, bool start_paused) > +{ > + libxl_domain_config d_config; > + virDomainDefPtr def = vm->def; > + int ret; > + uint32_t domid = 0; > + char *dom_xml = NULL; > + pid_t child_console_pid = -1; > + libxlDomainObjPrivatePtr priv = vm->privateData; > + > + memset(&d_config, 0, sizeof(d_config)); > + > + if (libxlBuildDomainConfig(def, &d_config) < 0 ) > + return -1; > + > + //TODO: Balloon dom0 ?? > + //ret = freemem(&d_config->b_info, &d_config->dm_info); > + > + ret = libxl_domain_create_new(&priv->ctx, &d_config, > + NULL, &child_console_pid, &domid); > + if (ret) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + _("libxenlight failed to create new domain '%s'"), > + d_config.c_info.name); > + goto error; > + } > + > + def->id = domid; > + if ((dom_xml = virDomainDefFormat(def, 0)) == NULL) > + goto error; > + > + if(libxl_userdata_store(&priv->ctx, domid, "libvirt-xml", > + (uint8_t *)dom_xml, strlen(dom_xml) + 1)) { > + libxlError(VIR_ERR_INTERNAL_ERROR, > + _("libxenlight failed to store userdata")); > + goto error; > + } > + > + if (libxlCreateDomEvents(vm) < 0) > + goto error; > + > + if (!start_paused) { > + libxl_domain_unpause(&priv->ctx, domid); > + vm->state = VIR_DOMAIN_RUNNING; > + } else { > + vm->state = VIR_DOMAIN_PAUSED; > + } > + > + libxl_domain_config_destroy(&d_config); > + VIR_FREE(dom_xml); > + return 0; > + > +error: > + if (domid > 0) { > + libxl_domain_destroy(&priv->ctx, domid, 0); > + def->id = -1; > + } > + libxl_domain_config_destroy(&d_config); > + VIR_FREE(dom_xml); > + return -1; > +} > + > +static int > +libxlShutdown(void) > +{ > + if (!libxl_driver) > + return -1; > + > + libxlDriverLock(libxl_driver); > + virCapabilitiesFree(libxl_driver->caps); > + libxl_ctx_free(&libxl_driver->ctx); > + xtl_logger_destroy(libxl_driver->logger); > + if (libxl_driver->logger_file) > + VIR_FORCE_FCLOSE(libxl_driver->logger_file); > + > + virDomainObjListDeinit(&libxl_driver->domains); > + > + VIR_FREE(libxl_driver->configDir); > + VIR_FREE(libxl_driver->autostartDir); > + VIR_FREE(libxl_driver->logDir); > + VIR_FREE(libxl_driver->stateDir); > + VIR_FREE(libxl_driver->libDir); > + VIR_FREE(libxl_driver->saveDir); > + > + libxlDriverUnlock(libxl_driver); > + virMutexDestroy(&libxl_driver->lock); > + VIR_FREE(libxl_driver); > + > + return 0; > +} > + > +static int > +libxlStartup(int privileged) { > + const libxl_version_info *ver_info; > + char *log_file = NULL; > + > + /* Check that the user is root, silently disable if not */ > + if (!privileged) { > + VIR_INFO0("Not running privileged, disabling libxenlight driver"); > + return 0; > + } > + > + if (VIR_ALLOC(libxl_driver) < 0) > + return -1; > + > + if (virMutexInit(&libxl_driver->lock) < 0) { > + VIR_ERROR0(_("cannot initialize mutex")); > + VIR_FREE(libxl_driver); > + return -1; > + } > + libxlDriverLock(libxl_driver); > + > + if (virDomainObjListInit(&libxl_driver->domains) < 0) > + goto out_of_memory; > + > + if (virAsprintf(&libxl_driver->configDir, > + "%s", LIBXL_CONFIG_DIR) == -1) > + goto out_of_memory; > + > + if (virAsprintf(&libxl_driver->autostartDir, > + "%s", LIBXL_AUTOSTART_DIR) == -1) > + goto out_of_memory; > + > + if (virAsprintf(&libxl_driver->logDir, > + "%s", LIBXL_LOG_DIR) == -1) > + goto out_of_memory; > + > + if (virAsprintf(&libxl_driver->stateDir, > + "%s", LIBXL_STATE_DIR) == -1) > + goto out_of_memory; > + > + if (virAsprintf(&libxl_driver->libDir, > + "%s", LIBXL_LIB_DIR) == -1) > + goto out_of_memory; > + > + if (virAsprintf(&libxl_driver->saveDir, > + "%s", LIBXL_SAVE_DIR) == -1) > + goto out_of_memory; > + > + if (virFileMakePath(libxl_driver->logDir) != 0) { > + char ebuf[1024]; > + VIR_ERROR(_("Failed to create log dir '%s': %s"), > + libxl_driver->logDir, virStrerror(errno, ebuf, sizeof ebuf)); > + goto error; > + } > + if (virFileMakePath(libxl_driver->stateDir) != 0) { > + char ebuf[1024]; > + VIR_ERROR(_("Failed to create state dir '%s': %s"), > + libxl_driver->stateDir, virStrerror(errno, ebuf, sizeof ebuf)); > + goto error; > + } > + if (virFileMakePath(libxl_driver->libDir) != 0) { > + char ebuf[1024]; > + VIR_ERROR(_("Failed to create lib dir '%s': %s"), > + libxl_driver->libDir, virStrerror(errno, ebuf, sizeof ebuf)); > + goto error; > + } > + if (virFileMakePath(libxl_driver->saveDir) != 0) { > + char ebuf[1024]; > + VIR_ERROR(_("Failed to create save dir '%s': %s"), > + libxl_driver->saveDir, virStrerror(errno, ebuf, sizeof ebuf)); > + goto error; > + } > + > + if (virAsprintf(&log_file, "%s/libxl.log", libxl_driver->logDir) < 0) { > + goto out_of_memory; > + } > + > + if ((libxl_driver->logger_file = fopen(log_file, "a")) == NULL) { > + virReportSystemError(errno, > + _("failed to create logfile %s"), > + log_file); > + goto error; > + } > + VIR_FREE(log_file); > + > + libxl_driver->logger = > + (xentoollog_logger*)xtl_createlogger_stdiostream(libxl_driver->logger_file, XTL_DEBUG, 0); > + if (!libxl_driver->logger) { > + VIR_ERROR0(_("cannot create logger for libxenlight")); > + goto error; > + } > + > + if (libxl_ctx_init(&libxl_driver->ctx, > + LIBXL_VERSION, > + libxl_driver->logger)) { > + VIR_ERROR0(_("cannot initialize libxenlight context")); > + goto error; > + } > + > + if ((ver_info = libxl_get_version_info(&libxl_driver->ctx)) == NULL) { > + VIR_ERROR0(_("cannot version information from libxenlight")); > + goto error; > + } > + libxl_driver->version = (ver_info->xen_version_major * 1000000) + > + (ver_info->xen_version_minor * 1000); > + > + if ((libxl_driver->caps = > + libxlMakeCapabilities(&libxl_driver->ctx)) == NULL) { > + VIR_ERROR0(_("cannot create capabilities for libxenlight")); > + goto error; > + } > + > + libxl_driver->caps->privateDataAllocFunc = libxlDomainObjPrivateAlloc; > + libxl_driver->caps->privateDataFreeFunc = libxlDomainObjPrivateFree; If I understand correctly privateDataAllocFunc is called at each domain creation -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list