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
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|