Skip to contentSkip to conversation

libxenlight driver

PATCH Superseded Jim Fehlig 3 participants 4 messages Feb 18, 2011 – Feb 23, 2011

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Jim Fehlig

author
#0 lore raw

PATCH 1/1 libxenlight driver

Here's the latest version of a libxenlight driver for libvirt.

I've added a per-domain libxl_ctx in addition to the driver wide context. The former is stored in virDomainObject privateData and used for operations on the domain. The latter is stored in driver private data and is used for non-domain related libxl calls, e.g. getVersion, getNodeInfo, etc. This approach was suggested by Ian Jackson and Stefano Stabellini and appears to be working much better than a single, driver wide libxl_ctx. I no longer have the restart issues described in the first patch posting [1].

Your review and comments are much appreciated!

Thanks,
Jim

[1] https://www.redhat.com/archives/libvir-list/2011-February/msg00409.html

Quoted 1 line

From e573c87e23943e365cf309a881f158dc8754e9fb Mon Sep 17 00:00:00 2001

From: Jim Fehlig <[email protected]>
Date: Thu, 10 Feb 2011 15:42:34 -0700
Subject: [PATCH] Add libxenlight driver

Add a new xen driver based on libxenlight [1], which is the primary toolstack starting with Xen 4.1.0. The driver is stateful, runs privileged only, and is accessed with libxl:/// URI.

[1] http://lists.xensource.com/archives/html/xen-devel/2009-11/msg00436.html

---
 cfg.mk                      |    1 +
 configure.ac                |   48 ++
 daemon/Makefile.am          |    4 +
 daemon/libvirtd.c           |    6 +
 docs/drivers.html.in        |    3 +-
 docs/drvxen.html.in         |    6 +-
 docs/drvxenlight.html.in    |   53 ++
 docs/sitemap.html.in        |    6 +-
 include/libvirt/virterror.h |    1 +
 po/POTFILES.in              |    2 +
 src/Makefile.am             |   32 ++
 src/driver.h                |    3 +-
 src/libvirt.c               |    4 +
 src/libxl/libxl_conf.c      |  783 ++++++++++++++++++++++++++
 src/libxl/libxl_conf.h      |   88 +++
 src/libxl/libxl_driver.c    | 1280 +++++++++++++++++++++++++++++++++++++++++++
 src/libxl/libxl_driver.h    |   27 +
 src/util/virterror.c        |    3 +
 18 files changed, 2346 insertions(+), 4 deletions(-)
 create mode 100644 docs/drvxenlight.html.in
 create mode 100644 src/libxl/libxl_conf.c
 create mode 100644 src/libxl/libxl_conf.h
 create mode 100644 src/libxl/libxl_driver.c
 create mode 100644 src/libxl/libxl_driver.h
cfg.mk +1 -0
index 4bbeb96..6ec11b4 100644
@@ -400,6 +400,7 @@ msg_gen_function += virXenStoreError
 msg_gen_function += virXendError
 msg_gen_function += vmwareError
 msg_gen_function += xenapiSessionErrorHandler
+msg_gen_function += libxlError
 msg_gen_function += xenUnifiedError
 msg_gen_function += xenXMError
 msg_gen_function += VIR_ERROR
configure.ac +48 -0

72 lines not on this page · raw message

daemon/Makefile.am +4 -0
index cdf0f75..c732827 100644
@@ -111,6 +111,10 @@ if WITH_LXC
     libvirtd_LDADD += ../src/libvirt_driver_lxc.la
 endif
 
+if WITH_LIBXL
+    libvirtd_LDADD += ../src/libvirt_driver_libxl.la
+endif
+
 if WITH_UML
     libvirtd_LDADD += ../src/libvirt_driver_uml.la
 endif
daemon/libvirtd.c +6 -0
index f4b3327..962f1fa 100644
@@ -80,6 +80,9 @@
 # ifdef WITH_LXC
 #  include "lxc/lxc_driver.h"
 # endif
+# ifdef WITH_LIBXL
+#  include "libxl/libxl_driver.h"
+# endif
 # ifdef WITH_UML
 #  include "uml/uml_driver.h"
 # endif
@@ -928,6 +931,9 @@ static struct qemud_server *qemudInitialize(void) {
 # ifdef WITH_LXC
     lxcRegister();
 # endif
+# ifdef WITH_LIBXL
+    libxlRegister();
+# endif
 # ifdef WITH_UML
     umlRegister();
 # endif
docs/drivers.html.in +2 -1
index ecad03a..368664e 100644
@@ -28,7 +28,8 @@
       <li><strong><a href="drvvbox.html">VirtualBox</a></strong></li>
       <li><strong><a href="drvesx.html">VMware ESX</a></strong></li>
       <li><strong><a href="drvvmware.html">VMware Workstation/Player</a></strong></li>
-      <li><strong><a href="drvxen.html">Xen</a></strong></li>
+      <li><strong><a href="drvxen.html">Xen 3.0.1 - 4.0.x</a></strong></li>
+      <li><strong><a href="drvxenlight.html">Xen 4.1.0 onwards</a></strong></li>
     </ul>
 
     <h2><a name="stroage">Storage drivers</a></h2>
docs/drvxen.html.in +5 -1
index 4e35afa..4b88a7d 100644
@@ -6,7 +6,11 @@
 
     <p>
       The libvirt Xen driver provides the ability to manage virtual machines
-      on any Xen release from 3.0.1 onwards.
+      on any Xen release from 3.0.1 to 4.0.x.  Starting with Xen 4.1.0,
+      the traditional xm/xend toolstack is replaced with a new toolstack
+      based on libxenlight.  Consult the
+      <a href="drvxenlight.html">libxenlight driver</a> if your Xen host is 
+      configured to use the new toolstack.
     </p>
 
     <h2><a name="prereq">Deployment pre-requisites</a></h2>
docs/drvxenlight.html.in new file +53 -0

53 lines not on this page · raw message

docs/sitemap.html.in +5 -1
index ac0af71..538f227 100644
@@ -156,7 +156,11 @@
             <ul>
               <li>
                 <a href="drvxen.html">Xen</a>
-                <span>Driver the Xen hypervisor</span>
+                <span>Driver the Xen hypervisor, versions 3.0.1 - 4.0.x</span>
+              </li>
+              <li>
+                <a href="drvxenlight.html">libxenlight</a>
+                <span>Driver the Xen hypervisor, version 4.1.0 onwards</span>
               </li>
               <li>
                 <a href="drvqemu.html">QEMU / KVM</a>
include/libvirt/virterror.h +1 -0
index 5962dbf..9f263d2 100644
@@ -79,6 +79,7 @@ typedef enum {
     VIR_FROM_SYSINFO = 37,	/* Error from sysinfo/SMBIOS */
     VIR_FROM_STREAMS = 38,	/* Error from I/O streams */
     VIR_FROM_VMWARE = 39,	/* Error from VMware driver */
+    VIR_FROM_LIBXL = 40,	/* Error from libxenlight driver */
 } virErrorDomain;
 
 
po/POTFILES.in +2 -0
index 2256cb2..8a47ab6 100644
@@ -34,6 +34,8 @@ src/lxc/lxc_conf.c
 src/lxc/lxc_controller.c
 src/lxc/lxc_driver.c
 src/lxc/veth.c
+src/libxl/libxl_driver.c
+src/libxl/libxl_conf.c
 src/network/bridge_driver.c
 src/node_device/node_device_driver.c
 src/node_device/node_device_hal.c
src/Makefile.am +32 -0
index 02d5250..f5fc35c 100644
@@ -297,6 +297,10 @@ XENAPI_DRIVER_SOURCES =								\
 		xenapi/xenapi_driver_private.h					\
 		xenapi/xenapi_utils.c xenapi/xenapi_utils.h
 
+LIBXL_DRIVER_SOURCES =						\
+		libxl/libxl_conf.c libxl/libxl_conf.h		\
+		libxl/libxl_driver.c libxl/libxl_driver.h
+
 UML_DRIVER_SOURCES =						\
 		uml/uml_conf.c uml/uml_conf.h			\
 		uml/uml_driver.c uml/uml_driver.h
@@ -677,6 +681,25 @@ endif
 libvirt_driver_xenapi_la_SOURCES = $(XENAPI_DRIVER_SOURCES)
 endif
 
+if WITH_LIBXL
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_libxl.la
+else
+noinst_LTLIBRARIES += libvirt_driver_libxl.la
+# Stateful, so linked to daemon instead
+#libvirt_la_BUILT_LIBADD += libvirt_driver_libxl.la
+endif
+libvirt_driver_libxl_la_CFLAGS = $(LIBXL_CFLAGS) \
+		-I@top_srcdir@/src/conf $(AM_CFLAGS)
+libvirt_driver_libxl_la_LDFLAGS = $(AM_LDFLAGS)
+libvirt_driver_libxl_la_LIBADD = $(LIBXL_LIBS)
+if WITH_DRIVER_MODULES
+libvirt_driver_libxl_la_LIBADD += ../gnulib/lib/libgnu.la
+libvirt_driver_libxl_la_LDFLAGS += -module -avoid-version
+endif
+libvirt_driver_libxl_la_SOURCES = $(LIBXL_DRIVER_SOURCES)
+endif
+
 if WITH_QEMU
 if WITH_DRIVER_MODULES
 mod_LTLIBRARIES += libvirt_driver_qemu.la
@@ -976,6 +999,7 @@ EXTRA_DIST +=							\
 		$(PHYP_DRIVER_SOURCES)				\
 		$(VBOX_DRIVER_SOURCES)				\
 		$(XENAPI_DRIVER_SOURCES)			\
+		$(LIBXL_DRIVER_SOURCES)			\
 		$(ESX_DRIVER_SOURCES)				\
 		$(ESX_DRIVER_EXTRA_DIST)			\
 		$(NETWORK_DRIVER_SOURCES)			\
@@ -1228,6 +1252,10 @@ if WITH_LXC
 	$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/lxc"
 	$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/lxc"
 endif
+if WITH_LIBXL
+	$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/libxl"
+	$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/libxl"
+endif
 if WITH_UML
 	$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/uml"
 	$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/uml"
@@ -1265,6 +1293,10 @@ if WITH_LXC
 	rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/lxc" ||:
 	rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/lxc" ||:
 endif
+if WITH_LIBXL
+	rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/libxl" ||:
+	rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/libxl" ||:
+endif
 if WITH_UML
 	rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/uml" ||:
 	rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/uml" ||:
src/driver.h +2 -1
index 7451004..b2d9814 100644
@@ -28,7 +28,8 @@ typedef enum {
     VIR_DRV_ESX = 10,
     VIR_DRV_PHYP = 11,
     VIR_DRV_XENAPI = 12,
-    VIR_DRV_VMWARE = 13
+    VIR_DRV_VMWARE = 13,
+    VIR_DRV_LIBXL = 14,
 } virDrvNo;
 
 
src/libvirt.c +4 -0
index f65cc24..75d07e6 100644
@@ -912,6 +912,10 @@ virGetVersion(unsigned long *libVer, const char *type,
         if (STRCASEEQ(type, "LXC"))
             *typeVer = LIBVIR_VERSION_NUMBER;
 # endif
+# if WITH_LIBXL
+        if (STRCASEEQ(type, "libxl"))
+            *typeVer = LIBVIR_VERSION_NUMBER;
+# endif
 # if WITH_PHYP
         if (STRCASEEQ(type, "phyp"))
             *typeVer = LIBVIR_VERSION_NUMBER;
src/libxl/libxl_conf.c new file +783 -0

783 lines not on this page · raw message

src/libxl/libxl_conf.h new file +88 -0

88 lines not on this page · raw message

src/libxl/libxl_driver.c new file +1280 -0

1,280 lines not on this page · raw message

src/libxl/libxl_driver.h new file +27 -0
new file mode 100644
index 0000000..e047552
@@ -0,0 +1,27 @@
+/*---------------------------------------------------------------------------*/
+/*  Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * 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
+ */
+/*---------------------------------------------------------------------------*/
+
+#ifndef LIBXL_DRIVER_H
+# define LIBXL_DRIVER_H
+
+# include <config.h>
+
+int libxlRegister(void);
+
+#endif /* LIBXL_DRIVER_H */
src/util/virterror.c +3 -0
index e45b582..c763d92 100644
@@ -89,6 +89,9 @@ static const char *virErrorDomainName(virErrorDomain domain) {
         case VIR_FROM_XENAPI:
             dom = "XenAPI ";
             break;
+        case VIR_FROM_LIBXL:
+            dom = "libxenlight ";
+            break;
         case VIR_FROM_XML:
             dom = "XML ";
             break;
Signature · 1 line
1.7.3.1

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#1 lore raw
Quoted 37 lines · Jim Fehlig
src/libxl/libxl_conf.c new file +37 -0
+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"))

src/libxl/libxl_conf.c line 429

Quoted 10 lines
src/libxl/libxl_conf.c new file +10 -0
+                    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

...

Quoted 149 lines
src/libxl/libxl_driver.c new file +143 -0
new file mode 100644
index 0000000..d581e7b
@@ -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);

src/libxl/libxl_driver.c line 153

Quoted 10 lines
src/libxl/libxl_driver.c new file +10 -0
+                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

src/libxl/libxl_driver.c line 157

Quoted 4 lines
src/libxl/libxl_driver.c new file +4 -0
+        } else {
+            VIR_INFO("Unhandled shutdown_reason %d", info.shutdown_reason);
+        }
+    }

we should call libxl_free_event before returning, otherwise we leak two strings

Quoted 242 lines
src/libxl/libxl_driver.c new file +242 -0
+
+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) +

src/libxl/libxl_driver.c line 409

Quoted 10 lines
src/libxl/libxl_driver.c new file +10 -0
+            (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

author
#2 lore raw
Quoted 45 lines · Stefano Stabellini
Quoted 43 lines · Jim Fehlig
src/libxl/libxl_conf.c new file +43 -0
+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;
+            }
Quoted 9 lines

src/libxl/libxl_conf.c line 429

Quoted 5 lines
src/libxl/libxl_conf.c new file +4 -0
+        } 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

Thanks for the review and comments. I've posted a new version based on xen-unstable c/s 22940.

Quoted 56 lines
Quoted 56 lines
src/libxl/libxl_driver.c new file +56 -0
+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) {
Quoted 9 lines

src/libxl/libxl_driver.c line 153

Quoted 6 lines
src/libxl/libxl_driver.c new file +5 -0
+            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

The updated patch handles SHUTDOWN_crash similar to SHUTDOWN_poweroff. I've ignored SHUTDOWN_suspend since the driver does not yet implement domainSave function. Also notice I've ignored any user-specified actions on these events, e.g. coredump and restart. But IMO, these type of improvements can be added incrementally. I'd like to get a basic driver upstream so others can easily contribute.

Quoted 10 lines

src/libxl/libxl_driver.c line 157

Quoted 6 lines
src/libxl/libxl_driver.c new file +4 -0
+        } else {
+            VIR_INFO("Unhandled shutdown_reason %d", info.shutdown_reason);
+        }
+    }

we should call libxl_free_event before returning, otherwise we leak two strings

Fixed in updated patch.

[...]

Quoted 7 lines

src/libxl/libxl_driver.c line 409

Quoted 4 lines
src/libxl/libxl_driver.c new file +3 -0
+
+    libxl_driver->caps->privateDataAllocFunc = libxlDomainObjPrivateAlloc;
+    libxl_driver->caps->privateDataFreeFunc = libxlDomainObjPrivateFree;

If I understand correctly privateDataAllocFunc is called at each domain creation

It is called when a domain is introduced to libvirt, either by defining a persistent domain (e.g. virsh define dom.xml) or creating a transient domain (e.g. virsh create dom.xml). The free func is called when a domain is removed from libvirt, either by undefining a persistent domain (e.g. virsh undefine dom-name) or poweroff of a transient domain. Starting/stopping a persistent domain does not invoke these functions.

Regards,
Jim

#3 lore raw
In reply to Jim Fehlig
Quoted 11 lines · Jim Fehlig

Here's the latest version of a libxenlight driver for libvirt.

I've added a per-domain libxl_ctx in addition to the driver wide context. The former is stored in virDomainObject privateData and used for operations on the domain. The latter is stored in driver private data and is used for non-domain related libxl calls, e.g. getVersion, getNodeInfo, etc. This approach was suggested by Ian Jackson and Stefano Stabellini and appears to be working much better than a single, driver wide libxl_ctx. I no longer have the restart issues described in the first patch posting [1].

Quoted 1 line

Your review and comments are much appreciated!

I've not had a chance todo a proper review yet, but after skimming the patch I think your impl / architecture looks pretty good.

Daniel

Signature · 4 lines
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|