[PATCH 00/10] A bunch of extensions to libxl driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This are some additional features to libxl driver. Some of them require change
in domain config structures/syntax. Details described with each patch.

Actually this is next iteration of a few years old patch series...

Marek Marczykowski-Górecki (10):
  libxl: update dom->id in libxlDomainCreateWithFlags
  conf: support backend domain name in disk and network devices
  libxl: support backend domain setting for disk and net devices
  libxl: fill HVM SDL and VNC settings based on <graphics/> entries
  libxl: pass ipaddr to libxl toolstack
  libxl: add tablet/mouse input device support
  libxl: prevent attaching multiple netdevs with the same MAC
  libxl: support domain config modification in virDomainRestoreFlags
  libxl: stubdom emulator type
  tests: add some simple libxl XML->XML tests

 docs/formatdomain.html.in                          |  43 ++++-
 docs/schemas/domaincommon.rng                      |  43 ++++-
 src/conf/domain_conf.c                             |  69 +++++++-
 src/conf/domain_conf.h                             |  10 ++
 src/libxl/libxl_conf.c                             | 194 ++++++++++++++++++---
 src/libxl/libxl_domain.c                           |  11 ++
 src/libxl/libxl_driver.c                           |  61 ++++++-
 src/util/virstoragefile.c                          |   4 +-
 src/util/virstoragefile.h                          |   1 +
 tests/Makefile.am                                  |   9 +-
 tests/domainschematest                             |   2 +-
 tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml      |  41 +++++
 tests/xlxml2xmldata/xlxml2xml-hvm.xml              |  40 +++++
 tests/xlxml2xmldata/xlxml2xml-network-bridged.xml  |  38 ++++
 .../xlxml2xml-network-driver-domain.xml            |  38 ++++
 tests/xlxml2xmldata/xlxml2xml-network-routed.xml   |  39 +++++
 tests/xlxml2xmldata/xlxml2xml-pv.xml               |  38 ++++
 tests/xlxml2xmltest.c                              | 189 ++++++++++++++++++++
 18 files changed, 824 insertions(+), 46 deletions(-)
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-hvm.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-network-bridged.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-network-driver-domain.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-network-routed.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-pv.xml
 create mode 100644 tests/xlxml2xmltest.c

-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 01/10] libxl: update dom->id in libxlDomainCreateWithFlags
Date: Thu,  5 Feb 2015 06:17:07 +0100
Message-Id: <1423113436-18213-2-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Otherwise domainCreateWithFlags via remote returns -1 as domid.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
 src/libxl/libxl_driver.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index c95b387..ce3a99b 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2375,6 +2375,9 @@ libxlDomainCreateWithFlags(virDomainPtr dom,
     }
 
     ret = libxlDomainStart(driver, vm, (flags & VIR_DOMAIN_START_PAUSED) != 0, -1);
+    if (ret < 0)
+        goto cleanup;
+    dom->id = vm->def->id;
 
  cleanup:
     if (vm)
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 02/10] conf: support backend domain name in disk and network devices
Date: Thu,  5 Feb 2015 06:17:08 +0100
Message-Id: <1423113436-18213-3-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

At least Xen supports backend drivers in another domain (aka "driver
domain"). This patch introduces XML config option for such setting as
'domain' attribute of 'source' element. Verification its content is left
for the driver.

In the future same option will be needed for USB devices (hostdev
objects), but for now libxl doesn't have support for PVUSB.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
Changes in v2:
 - describe in docs/formatdomain.html.in
 - enforce empty domain tag (only 'name' attribute allowed)

Changes in v3:
 - change <domain name='xx'/> element to domain='' attribute of source
   element - this is more logical place
 - grammar of docs

 docs/formatdomain.html.in     | 29 +++++++++++++++++++++++++++--
 docs/schemas/domaincommon.rng | 20 ++++++++++++++++++++
 src/conf/domain_conf.c        | 33 +++++++++++++++++++++++++++++----
 src/conf/domain_conf.h        |  1 +
 src/util/virstoragefile.c     |  4 +++-
 src/util/virstoragefile.h     |  1 +
 6 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index c5ad6f4..38c42d5 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1907,13 +1907,17 @@
             <span class="since">since 0.0.3</span></dt>
               <dd>
               The <code>file</code> attribute specifies the fully-qualified
-              path to the file holding the disk.
+              path to the file holding the disk. The optional
+              <code>domain</code> attribute allows specifying a backend domain
+              (aka driver domain) where the file is stored.
               </dd>
             <dt><code>type='block'</code>
             <span class="since">since 0.0.3</span></dt>
               <dd>
               The <code>dev</code> attribute specifies the path to the
-              host device to serve as the disk.
+              host device to serve as the disk. The optional
+              <code>domain</code> attribute allows specifying a backend domain
+              (aka driver domain) for the device.
               </dd>
             <dt><code>type='dir'</code>
             <span class="since">since 0.7.5</span></dt>
@@ -4336,6 +4340,27 @@ qemu-kvm -net nic,model=? /dev/null
       element is unspecified is to have the link state <code>up</code>.
       <span class="since">Since 0.9.5</span>
     </p>
+    <h5><a name="elementDomain">Setting up a network backend in a driver domain</a></h5>
+<pre>
+  ...
+  &lt;devices&gt;
+    ...
+    &lt;interface type='bridge'&gt;
+      &lt;source bridge='br0' <b>domain='netvm'</b>/&gt;
+    &lt;/interface&gt;
+    ...
+  &lt;/devices&gt;
+  ...</pre>
+
+    <p>
+      The optional <code>domain</code> attribute allows specifying a backend
+      domain (aka driver domain) for the device. Use the <code>name</code> attribute
+      to specify its name. You can use it to create a direct network link between
+      domains (so data will not go through host system). Use with type 'ethernet'
+      to create plain network link, or with 'bridge' to connect to some bridge
+      inside the driver domain.
+      <span class="since">Since 1.0.7 (Xen only)</span>
+    </p>
 
     <h5><a name="ipconfig">IP configuration</a></h5>
 <pre>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d467dce..a4321f1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1340,6 +1340,11 @@
             <attribute name="file">
               <ref name="absFilePath"/>
             </attribute>
+            <optional>
+              <attribute name="domain">
+                <ref name="domainName"/>
+              </attribute>
+            </optional>
           </optional>
           <optional>
             <ref name="storageStartupPolicy"/>
@@ -1365,6 +1370,11 @@
             </attribute>
           </optional>
           <optional>
+            <attribute name="domain">
+              <ref name="domainName"/>
+            </attribute>
+          </optional>
+          <optional>
             <ref name="storageStartupPolicy"/>
           </optional>
           <optional>
@@ -2040,6 +2050,11 @@
                 <attribute name="bridge">
                   <ref name="deviceName"/>
                 </attribute>
+                <optional>
+                  <attribute name="domain">
+                    <ref name="domainName"/>
+                  </attribute>
+                </optional>
                 <empty/>
               </element>
             </optional>
@@ -2059,6 +2074,11 @@
                 <attribute name="dev">
                   <ref name="deviceName"/>
                 </attribute>
+                <optional>
+                  <attribute name="domain">
+                    <ref name="domainName"/>
+                  </attribute>
+                </optional>
                 <empty/>
               </element>
             </optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4251b13..17b699a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1442,6 +1442,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
     VIR_FREE(def->backend.vhost);
     VIR_FREE(def->virtPortProfile);
     VIR_FREE(def->script);
+    VIR_FREE(def->domain_name);
     VIR_FREE(def->ifname);
     VIR_FREE(def->ifname_guest);
     VIR_FREE(def->ifname_guest_actual);
@@ -5520,9 +5521,11 @@ virDomainDiskSourceParse(xmlNodePtr node,
     switch ((virStorageType)src->type) {
     case VIR_STORAGE_TYPE_FILE:
         src->path = virXMLPropString(node, "file");
+        src->domain_name = virXMLPropString(node, "domain");
         break;
     case VIR_STORAGE_TYPE_BLOCK:
         src->path = virXMLPropString(node, "dev");
+        src->domain_name = virXMLPropString(node, "domain");
         break;
     case VIR_STORAGE_TYPE_DIR:
         src->path = virXMLPropString(node, "dir");
@@ -7369,6 +7372,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     char *vhostuser_path = NULL;
     char *vhostuser_type = NULL;
     char *trustGuestRxFilters = NULL;
+    char *domain_name = NULL;
     virNWFilterHashTablePtr filterparams = NULL;
     virDomainActualNetDefPtr actual = NULL;
     xmlNodePtr oldnode = ctxt->node;
@@ -7423,12 +7427,14 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                        def->type == VIR_DOMAIN_NET_TYPE_BRIDGE &&
                        xmlStrEqual(cur->name, BAD_CAST "source")) {
                 bridge = virXMLPropString(cur, "bridge");
+                domain_name = virXMLPropString(cur, "domain");
             } else if (!dev &&
                        (def->type == VIR_DOMAIN_NET_TYPE_ETHERNET ||
                         def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
                        xmlStrEqual(cur->name, BAD_CAST "source")) {
                 dev  = virXMLPropString(cur, "dev");
                 mode = virXMLPropString(cur, "mode");
+                domain_name = virXMLPropString(cur, "domain");
             } else if (!vhostuser_path && !vhostuser_mode && !vhostuser_type
                        && def->type == VIR_DOMAIN_NET_TYPE_VHOSTUSER &&
                        xmlStrEqual(cur->name, BAD_CAST "source")) {
@@ -7802,6 +7808,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
         def->script = script;
         script = NULL;
     }
+    if (domain_name != NULL) {
+        def->domain_name = domain_name;
+        domain_name = NULL;
+    }
     if (ifname != NULL) {
         def->ifname = ifname;
         ifname = NULL;
@@ -8061,6 +8071,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(addrtype);
     VIR_FREE(trustGuestRxFilters);
     VIR_FREE(ips);
+    VIR_FREE(domain_name);
     virNWFilterHashTableFree(filterparams);
 
     return def;
@@ -16544,6 +16555,7 @@ virDomainDiskSourceFormatInternal(virBufferPtr buf,
             virBufferAddLit(buf, "<source");
             virBufferEscapeString(buf, " file='%s'", src->path);
             virBufferEscapeString(buf, " startupPolicy='%s'", startupPolicy);
+            virBufferEscapeString(buf, " domain='%s'", src->domain_name);
 
             virDomainDiskSourceDefFormatSeclabel(buf, src->nseclabels,
                                                  src->seclabels, flags,
@@ -16554,6 +16566,7 @@ virDomainDiskSourceFormatInternal(virBufferPtr buf,
             virBufferAddLit(buf, "<source");
             virBufferEscapeString(buf, " dev='%s'", src->path);
             virBufferEscapeString(buf, " startupPolicy='%s'", startupPolicy);
+            virBufferEscapeString(buf, " domain='%s'", src->domain_name);
 
             virDomainDiskSourceDefFormatSeclabel(buf, src->nseclabels,
                                                  src->seclabels, flags,
@@ -17713,8 +17726,14 @@ virDomainNetDefFormat(virBufferPtr buf,
             break;
 
         case VIR_DOMAIN_NET_TYPE_ETHERNET:
-            virBufferEscapeString(buf, "<source dev='%s'/>\n",
-                                  def->data.ethernet.dev);
+            if (def->data.ethernet.dev || def->domain_name) {
+                virBufferAddLit(buf, "<source");
+                virBufferEscapeString(buf, " dev='%s'",
+                                      def->data.ethernet.dev);
+                virBufferEscapeString(buf, " domain='%s'",
+                                      def->domain_name);
+                virBufferAddLit(buf, "/>\n");
+            }
             break;
 
         case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
@@ -17730,8 +17749,14 @@ virDomainNetDefFormat(virBufferPtr buf,
             break;
 
         case VIR_DOMAIN_NET_TYPE_BRIDGE:
-            virBufferEscapeString(buf, "<source bridge='%s'/>\n",
-                                  def->data.bridge.brname);
+            if (def->data.bridge.brname || def->domain_name) {
+                virBufferAddLit(buf, "<source");
+                virBufferEscapeString(buf, " bridge='%s'",
+                                      def->data.bridge.brname);
+                virBufferEscapeString(buf, " domain='%s'",
+                                      def->domain_name);
+                virBufferAddLit(buf, "/>\n");
+            }
             break;
 
         case VIR_DOMAIN_NET_TYPE_SERVER:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 93f2314..28c6920 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -995,6 +995,7 @@ struct _virDomainNetDef {
         unsigned long sndbuf;
     } tune;
     char *script;
+    char *domain_name; /* backend domain name */
     char *ifname;
     char *ifname_guest;
     char *ifname_guest_actual;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 8d3d1f5..c2703b7 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1835,7 +1835,8 @@ virStorageSourceCopy(const virStorageSource *src,
         VIR_STRDUP(ret->backingStoreRaw, src->backingStoreRaw) < 0 ||
         VIR_STRDUP(ret->snapshot, src->snapshot) < 0 ||
         VIR_STRDUP(ret->configFile, src->configFile) < 0 ||
-        VIR_STRDUP(ret->compat, src->compat) < 0)
+        VIR_STRDUP(ret->compat, src->compat) < 0 ||
+        VIR_STRDUP(ret->domain_name, src->domain_name))
         goto error;
 
     if (src->nhosts) {
@@ -2023,6 +2024,7 @@ virStorageSourceClear(virStorageSourcePtr def)
 
     VIR_FREE(def->path);
     VIR_FREE(def->volume);
+    VIR_FREE(def->domain_name);
     virStorageSourcePoolDefFree(def->srcpool);
     VIR_FREE(def->driverName);
     virBitmapFree(def->features);
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index b4c3808..a3c7e1e 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -241,6 +241,7 @@ struct _virStorageSource {
     char *snapshot; /* for storage systems supporting internal snapshots */
     char *configFile; /* some storage systems use config file as part of
                          the source definition */
+    char *domain_name; /* name of domain holding backing storage file/dev */
     size_t nhosts;
     virStorageNetHostDefPtr hosts;
     virStorageSourcePoolDefPtr srcpool;
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 03/10] libxl: support backend domain setting for disk and net devices
Date: Thu,  5 Feb 2015 06:17:09 +0100
Message-Id: <1423113436-18213-4-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

This implement handling of <source domain=''/>  parameter introduced in
previous patch.

Lookup on domain name (to get domain ID) requires libxlDriverPrivate
object, so it must be passed down to libxlMakeDisk and libxlMakeNet from
top level callers.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
Changes in v2:
 - rebase on 1.0.6+
 - fix indentation
 - make libxl_name_to_domid switch more defensive

Changes in v3:
 - rebase on 1.2.12+
 - leave name->XID resolution to libxl itself, which greatly simplify
   the code (but requires Xen at least 4.3)

 src/libxl/libxl_conf.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 0555b91..1811a83 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -971,6 +971,18 @@ libxlMakeDisk(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk)
         return -1;
     }
 
+    if (l_disk->src->domain_name) {
+#ifdef LIBXL_HAVE_DEVICE_BACKEND_DOMNAME
+        if (VIR_STRDUP(x_disk->backend_domname, l_disk->src->domain_name) < 0)
+            return -1;
+#else
+        virReportError(VIR_ERR_XML_DETAIL, "%s",
+                _("this version of libxenlight does not "
+                  "support backend domain name"));
+        return -1;
+#endif
+    }
+
     return 0;
 }
 
@@ -1098,6 +1110,18 @@ libxlMakeNic(virDomainDefPtr def,
             return -1;
     }
 
+    if (l_nic->domain_name) {
+#ifdef LIBXL_HAVE_DEVICE_BACKEND_DOMNAME
+        if (VIR_STRDUP(x_nic->backend_domname, l_nic->domain_name) < 0)
+            return -1;
+#else
+        virReportError(VIR_ERR_XML_DETAIL, "%s",
+                _("this version of libxenlight does not "
+                  "support backend domain name"));
+        return -1;
+#endif
+    }
+
     return 0;
 }
 
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 04/10] libxl: fill HVM SDL and VNC settings based on <graphics/> entries
Date: Thu,  5 Feb 2015 06:17:10 +0100
Message-Id: <1423113436-18213-5-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Vfb entries in domain config are used only by PV drivers. Qemu
parameters are build based on b_info struct. So fill it with the same
data as vfb entries (actually the first one).
This will additionally allow graphic-less domain, when no <graphics/>
entries are present in domain XML (previously VNC was always enabled).

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
 src/libxl/libxl_conf.c | 100 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 74 insertions(+), 26 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 1811a83..c9f8ad5 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -618,12 +618,53 @@ libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
                        _("unsupported chardev '%s'"), type);
         return -1;
     }
+    return 0;
+}
+
+static int
+libxlMakeVNCInfo(virPortAllocatorPtr graphicsports,
+                 virDomainGraphicsDefPtr l_vfb,
+                 libxl_vnc_info *x_vnc)
+{
+    unsigned short port;
+    const char *listenAddr;
+
+    libxl_defbool_set(&x_vnc->enable, 1);
+    /* driver handles selection of free port */
+    libxl_defbool_set(&x_vnc->findunused, 0);
+    if (l_vfb->data.vnc.autoport) {
+
+        if (virPortAllocatorAcquire(graphicsports, &port) < 0)
+            return -1;
+        l_vfb->data.vnc.port = port;
+    }
+    x_vnc->display = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN;
 
+    listenAddr = virDomainGraphicsListenGetAddress(l_vfb, 0);
+    if (listenAddr) {
+        /* libxl_device_vfb_init() does VIR_STRDUP("127.0.0.1") */
+        VIR_FREE(x_vnc->listen);
+        if (VIR_STRDUP(x_vnc->listen, listenAddr) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+static int
+libxlMakeSDLInfo(virDomainGraphicsDefPtr l_vfb,
+                 libxl_sdl_info *x_sdl)
+{
+    libxl_defbool_set(&x_sdl->enable, 1);
+    if (VIR_STRDUP(x_sdl->display, l_vfb->data.sdl.display) < 0)
+        return -1;
+    if (VIR_STRDUP(x_sdl->xauthority, l_vfb->data.sdl.xauth) < 0)
+        return -1;
     return 0;
 }
 
 static int
 libxlMakeDomBuildInfo(virDomainDefPtr def,
+                      virPortAllocatorPtr graphicsports,
                       libxl_ctx *ctx,
                       libxl_domain_config *d_config)
 {
@@ -745,6 +786,35 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
             return -1;
         }
 
+        /* Disable VNC and SDL until explicitly enabled */
+        libxl_defbool_set(&b_info->u.hvm.vnc.enable, 0);
+        libxl_defbool_set(&b_info->u.hvm.sdl.enable, 0);
+
+        for (i = 0; i < def->ngraphics; i++) {
+            switch (def->graphics[i]->type) {
+                case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
+                    if (libxl_defbool_val(b_info->u.hvm.vnc.enable))
+                        continue;
+                    if (libxlMakeVNCInfo(graphicsports,
+                                def->graphics[i],
+                                &b_info->u.hvm.vnc) < 0)
+                        return -1;
+                    if (def->graphics[i]->data.vnc.keymap &&
+                            VIR_STRDUP(b_info->u.hvm.keymap,
+                                       def->graphics[i]->data.vnc.keymap) < 0) {
+                        virReportOOMError();
+                        return -1;
+                    }
+                    break;
+                case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
+                    if (libxl_defbool_val(b_info->u.hvm.sdl.enable))
+                        continue;
+                    if (libxlMakeSDLInfo(def->graphics[i], &b_info->u.hvm.sdl) < 0)
+                        return -1;
+                    break;
+            }
+        }
+
         /*
          * The following comment and calculation were taken directly from
          * libxenlight's internal function libxl_get_required_shadow_memory():
@@ -1171,38 +1241,16 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports,
              virDomainGraphicsDefPtr l_vfb,
              libxl_device_vfb *x_vfb)
 {
-    unsigned short port;
-    const char *listenAddr;
-
     libxl_device_vfb_init(x_vfb);
 
     switch (l_vfb->type) {
         case VIR_DOMAIN_GRAPHICS_TYPE_SDL:
-            libxl_defbool_set(&x_vfb->sdl.enable, 1);
-            if (VIR_STRDUP(x_vfb->sdl.display, l_vfb->data.sdl.display) < 0)
-                return -1;
-            if (VIR_STRDUP(x_vfb->sdl.xauthority, l_vfb->data.sdl.xauth) < 0)
+            if (libxlMakeSDLInfo(l_vfb, &x_vfb->sdl) < 0)
                 return -1;
             break;
         case  VIR_DOMAIN_GRAPHICS_TYPE_VNC:
-            libxl_defbool_set(&x_vfb->vnc.enable, 1);
-            /* driver handles selection of free port */
-            libxl_defbool_set(&x_vfb->vnc.findunused, 0);
-            if (l_vfb->data.vnc.autoport) {
-
-                if (virPortAllocatorAcquire(graphicsports, &port) < 0)
-                    return -1;
-                l_vfb->data.vnc.port = port;
-            }
-            x_vfb->vnc.display = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN;
-
-            listenAddr = virDomainGraphicsListenGetAddress(l_vfb, 0);
-            if (listenAddr) {
-                /* libxl_device_vfb_init() does VIR_STRDUP("127.0.0.1") */
-                VIR_FREE(x_vfb->vnc.listen);
-                if (VIR_STRDUP(x_vfb->vnc.listen, listenAddr) < 0)
-                    return -1;
-            }
+            if (libxlMakeVNCInfo(graphicsports, l_vfb, &x_vfb->vnc) < 0)
+                return -1;
             if (VIR_STRDUP(x_vfb->keymap, l_vfb->data.vnc.keymap) < 0)
                 return -1;
             break;
@@ -1611,7 +1659,7 @@ libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
     if (libxlMakeDomCreateInfo(ctx, def, &d_config->c_info) < 0)
         return -1;
 
-    if (libxlMakeDomBuildInfo(def, ctx, d_config) < 0)
+    if (libxlMakeDomBuildInfo(def, graphicsports, ctx, d_config) < 0)
         return -1;
 
     if (libxlMakeDiskList(def, d_config) < 0)
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 05/10] libxl: pass ipaddr to libxl toolstack
Date: Thu,  5 Feb 2015 06:17:11 +0100
Message-Id: <1423113436-18213-6-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Do not silently ignore its value. LibXL support only one address, so
refuse multiple IPs.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
 src/libxl/libxl_conf.c   |  5 +++++
 src/libxl/libxl_domain.c | 11 +++++++++++
 2 files changed, 16 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index c9f8ad5..4730585 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1133,6 +1133,11 @@ libxlMakeNic(virDomainDefPtr def,
         case VIR_DOMAIN_NET_TYPE_ETHERNET:
             if (VIR_STRDUP(x_nic->script, l_nic->script) < 0)
                 return -1;
+            if (l_nic->nips > 0) {
+                x_nic->ip = virSocketAddrFormat(&l_nic->ips[0]->address);
+                if (!x_nic->ip)
+                    return -1;
+            }
             break;
         case VIR_DOMAIN_NET_TYPE_NETWORK:
         {
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 856cfb4..afb0b15 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -482,6 +482,17 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
         STRNEQ(def->os.type, "hvm"))
         dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
 
+    if (dev->type == VIR_DOMAIN_DEVICE_NET &&
+            (dev->data.net->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+             dev->data.net->type == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
+        if (dev->data.net->nips > 1) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                    _("multiple IP addresses not supported on device type %s"),
+                    virDomainNetTypeToString(dev->data.net->type));
+            return -1;
+        }
+    }
+
     if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV ||
         (dev->type == VIR_DOMAIN_DEVICE_NET &&
          dev->data.net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 06/10] libxl: add tablet/mouse input device support
Date: Thu,  5 Feb 2015 06:17:12 +0100
Message-Id: <1423113436-18213-7-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
Changes in v2:
 - rebase on 1.2.12+
 - multiple devices support

 src/libxl/libxl_conf.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4730585..b1131ea 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -815,6 +815,54 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
             }
         }
 
+        if (def->ninputs) {
+#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
+            if (VIR_ALLOC_N(b_info->u.hvm.usbdevice_list, def->ninputs+1) < 0)
+                return -1;
+#else
+            if (def->ninputs > 1) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("libxenlight supports only one input device"));
+                return -1;
+            }
+#endif
+            for (i = 0; i < def->ninputs; i++) {
+                if (def->inputs[i]->bus != VIR_DOMAIN_INPUT_BUS_USB) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                            _("libxenlight supports only USB input"));
+                    return -1;
+                }
+            }
+            for (i = 0; i < def->ninputs; i++) {
+                switch (def->inputs[i]->type) {
+                    case VIR_DOMAIN_INPUT_TYPE_MOUSE:
+#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
+                        if (VIR_STRDUP(b_info->u.hvm.usbdevice_list[i], "mouse") < 0)
+                            return -1;
+#else
+                        VIR_FREE(b_info->u.hvm.usbdevice);
+                        if (VIR_STRDUP(b_info->u.hvm.usbdevice, "mouse") < 0)
+                            return -1;
+#endif
+                        break;
+                    case VIR_DOMAIN_INPUT_TYPE_TABLET:
+#ifdef LIBXL_HAVE_BUILDINFO_USBDEVICE_LIST
+                        if (VIR_STRDUP(b_info->u.hvm.usbdevice_list[i], "tablet") < 0)
+                            return -1;
+#else
+                        VIR_FREE(b_info->u.hvm.usbdevice);
+                        if (VIR_STRDUP(b_info->u.hvm.usbdevice, "tablet") < 0)
+                            return -1;
+#endif
+                        break;
+                    default:
+                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                _("Unknown input device type"));
+                        return -1;
+                }
+            }
+        }
+
         /*
          * The following comment and calculation were taken directly from
          * libxenlight's internal function libxl_get_required_shadow_memory():
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 07/10] libxl: prevent attaching multiple netdevs with the same MAC
Date: Thu,  5 Feb 2015 06:17:13 +0100
Message-Id: <1423113436-18213-8-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

It will not be possible to detach such device later. Also improve
logging in such cases.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
 src/libxl/libxl_driver.c | 41 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index ce3a99b..005cc96 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2787,6 +2787,7 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
     int actualType;
     libxl_device_nic nic;
     int ret = -1;
+    char mac[VIR_MAC_STRING_BUFLEN];
 
     /* preallocate new slot for device */
     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -2801,6 +2802,14 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
 
     actualType = virDomainNetGetActualType(net);
 
+    /* -2 means "multiple matches" so then fail also */
+    if (virDomainNetFindIdx(vm->def, net) != -1) {
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                _("device matching mac address %s already exists"),
+                virMacAddrFormat(&net->mac, mac));
+        return -1;
+    }
+
     if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
         /* This is really a "smart hostdev", so it should be attached
          * as a hostdev (the hostdev code will reach over into the
@@ -2879,6 +2888,7 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
     virDomainHostdevDefPtr hostdev;
     virDomainHostdevDefPtr found;
     virDomainHostdevSubsysPCIPtr pcisrc;
+    char mac[VIR_MAC_STRING_BUFLEN];
 
     switch (dev->type) {
         case VIR_DOMAIN_DEVICE_DISK:
@@ -2896,6 +2906,12 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 
         case VIR_DOMAIN_DEVICE_NET:
             net = dev->data.net;
+            if (virDomainNetFindIdx(vmdef, net) >= 0) {
+                virReportError(VIR_ERR_INVALID_ARG,
+                               _("network device with mac %s already exists."),
+                               virMacAddrFormat(&net->mac, mac));
+                return -1;
+            }
             if (virDomainNetInsert(vmdef, net))
                 return -1;
             dev->data.net = NULL;
@@ -3060,8 +3076,18 @@ libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
     char mac[VIR_MAC_STRING_BUFLEN];
     int ret = -1;
 
-    if ((detachidx = virDomainNetFindIdx(vm->def, net)) < 0)
+    if ((detachidx = virDomainNetFindIdx(vm->def, net)) < 0) {
+        if (detachidx == -2) {
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                    _("multiple devices matching mac address %s found"),
+                    virMacAddrFormat(&net->mac, mac));
+        } else {
+            virReportError(VIR_ERR_OPERATION_FAILED,
+                    _("network device %s not found"),
+                    virMacAddrFormat(&net->mac, mac));
+        }
         return -1;
+    }
 
     detach = vm->def->nets[detachidx];
 
@@ -3136,6 +3162,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
     virDomainHostdevDefPtr hostdev, det_hostdev;
     virDomainNetDefPtr net;
     int idx;
+    char mac[VIR_MAC_STRING_BUFLEN];
 
     switch (dev->type) {
         case VIR_DOMAIN_DEVICE_DISK:
@@ -3150,8 +3177,18 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 
         case VIR_DOMAIN_DEVICE_NET:
             net = dev->data.net;
-            if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
+            if ((idx = virDomainNetFindIdx(vmdef, net)) < 0) {
+                if (idx == -2) {
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                            _("multiple devices matching mac address %s found"),
+                            virMacAddrFormat(&dev->data.net->mac, mac));
+                } else {
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                            _("network device %s not found"),
+                            virMacAddrFormat(&dev->data.net->mac, mac));
+                }
                 return -1;
+            }
 
             /* this is guaranteed to succeed */
             virDomainNetDefFree(virDomainNetRemove(vmdef, idx));
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 08/10] libxl: support domain config modification in virDomainRestoreFlags
Date: Thu,  5 Feb 2015 06:17:14 +0100
Message-Id: <1423113436-18213-9-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---

There was a discussion about calling virDomainDefCheckABIStability. The use
case I have for this is to start multiple domains from the same savefile. This
require changing:
 - UUID
 - name
 - IP address

Those are exactly type of changes blocked by virDomainDefCheckABIStability.
Perhaps some "permissive" mode should be introduced to the
virDomainDefCheckABIStability function?

 src/libxl/libxl_driver.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 005cc96..7539d33 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1456,11 +1456,6 @@ libxlDomainRestoreFlags(virConnectPtr conn, const char *from,
 #endif
 
     virCheckFlags(VIR_DOMAIN_SAVE_PAUSED, -1);
-    if (dxml) {
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-                       _("xml modification unsupported"));
-        return -1;
-    }
 
     fd = libxlDomainSaveImageOpen(driver, cfg, from, &def, &hdr);
     if (fd < 0)
@@ -1469,6 +1464,18 @@ libxlDomainRestoreFlags(virConnectPtr conn, const char *from,
     if (virDomainRestoreFlagsEnsureACL(conn, def) < 0)
         goto cleanup_unlock;
 
+    if (dxml) {
+        virDomainDefPtr def2 = NULL;
+
+        if (!(def2 = virDomainDefParseString(dxml, cfg->caps, driver->xmlopt,
+                                        1 << VIR_DOMAIN_VIRT_XEN,
+                                        VIR_DOMAIN_XML_INACTIVE))) {
+            goto cleanup;
+        }
+        virDomainDefFree(def);
+        def = def2;
+    }
+
     if (!(vm = virDomainObjListAdd(driver->domains, def,
                                    driver->xmlopt,
                                    VIR_DOMAIN_OBJ_LIST_ADD_LIVE |
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 09/10] libxl: Stubdom emulator type
Date: Thu,  5 Feb 2015 06:17:15 +0100
Message-Id: <1423113436-18213-10-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Xen have feature of having device model in separate domain (called stub
domain). Add a 'type' attribute to 'emulator' element to allow selecting
such a configuration. Emulator path is still used for qemu running in dom0 (if
any). Libxl currently do not allow to select stubdomain path.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---

I think it would be good idea to introduce the same change to capabilities XML.
The problem is I can't include domain_conf.h from capabilities.h, so probably
that enum declaration needs to be moved to capabilities.h. Is it the right way?
Or it should be done somehow different?

 docs/formatdomain.html.in     | 14 ++++++++++++++
 docs/schemas/domaincommon.rng | 23 ++++++++++++++++++++++-
 src/conf/domain_conf.c        | 36 ++++++++++++++++++++++++++++++++++--
 src/conf/domain_conf.h        |  9 +++++++++
 src/libxl/libxl_conf.c        | 17 +++++++++++++++++
 5 files changed, 96 insertions(+), 3 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 38c42d5..4f539e2 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1652,6 +1652,20 @@
         The <a href="formatcaps.html">capabilities XML</a> specifies
         the recommended default emulator to use for each particular
         domain type / architecture combination.
+
+        <span class="since">Since 1.2.13</span>, the <code>emulator</code>
+        element may contain <code>type</code> attribute. Possible values are:
+        <dl>
+          <dt><code>type='default'</code></dt>
+          <dd>Equivalent to not setting <code>type</code> attribute at all.
+          </dd>
+
+          <dt><code>type='stubdom'</code></dt>
+          <dd>Launch emulator in stub domain (Xen only). The emulator path
+          still indicate which binary is used in dom0 - there is no control
+          which binary is used as a stub domain.
+          </dd>
+        </dl>
       </dd>
     </dl>
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index a4321f1..2a12073 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2519,7 +2519,28 @@
     -->
   <define name="emulator">
     <element name="emulator">
-      <ref name="absFilePath"/>
+      <choice>
+        <group>
+          <optional>
+            <attribute name="type">
+              <choice>
+                <value>qemu</value>
+                <value>stubdom</value>
+              </choice>
+            </attribute>
+          </optional>
+          <ref name="absFilePath"/>
+        </group>
+        <group>
+          <attribute name="type">
+            <choice>
+              <value>qemu</value>
+              <value>stubdom</value>
+            </choice>
+          </attribute>
+          <empty/>
+        </group>
+      </choice>
     </element>
   </define>
   <!--
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 17b699a..c268091 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -741,6 +741,10 @@ VIR_ENUM_IMPL(virDomainDiskTray, VIR_DOMAIN_DISK_TRAY_LAST,
               "closed",
               "open");
 
+VIR_ENUM_IMPL(virDomainEmulatorType, VIR_DOMAIN_EMULATOR_TYPE_LAST,
+              "qemu",
+              "stubdom");
+
 VIR_ENUM_IMPL(virDomainRNGModel,
               VIR_DOMAIN_RNG_MODEL_LAST,
               "virtio");
@@ -13712,6 +13716,14 @@ virDomainDefParseXML(xmlDocPtr xml,
     }
 
     def->emulator = virXPathString("string(./devices/emulator[1])", ctxt);
+    if ((tmp = virXPathString("string(./devices/emulator/@type)", ctxt))) {
+        def->emulator_type = virDomainEmulatorTypeTypeFromString(tmp);
+        VIR_FREE(tmp);
+        if (def->emulator_type < 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Unknown emulator type '%s'"), tmp);
+        }
+    }
 
     /* analysis of the disk devices */
     if ((n = virXPathNodeSet("./devices/disk", ctxt, &nodes)) < 0)
@@ -15690,6 +15702,14 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
         goto error;
     }
 
+    if (src->emulator_type != dst->emulator_type) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                _("Target domain emulator type %s does not match source %s"),
+                virDomainEmulatorTypeTypeToString(dst->emulator_type),
+                virDomainEmulatorTypeTypeToString(src->emulator_type));
+        goto error;
+    }
+
     if (!virDomainDefFeaturesCheckABIStability(src, dst))
         goto error;
 
@@ -19893,8 +19913,20 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     virBufferAddLit(buf, "<devices>\n");
     virBufferAdjustIndent(buf, 2);
 
-    virBufferEscapeString(buf, "<emulator>%s</emulator>\n",
-                          def->emulator);
+    if (def->emulator ||
+            def->emulator_type != VIR_DOMAIN_EMULATOR_TYPE_DEFAULT) {
+        virBufferAddLit(buf, "<emulator");
+        if (def->emulator_type != VIR_DOMAIN_EMULATOR_TYPE_DEFAULT) {
+            virBufferAsprintf(buf, " type='%s'",
+                              virDomainEmulatorTypeTypeToString(def->emulator_type));
+        }
+        if (!def->emulator) {
+            virBufferAddLit(buf, "/>\n");
+        } else {
+            virBufferEscapeString(buf, ">%s</emulator>\n",
+                                  def->emulator);
+        }
+    }
 
     for (n = 0; n < def->ndisks; n++)
         if (virDomainDiskDefFormat(buf, def->disks[n], flags) < 0)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 28c6920..38b9037 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1918,6 +1918,13 @@ struct _virBlkioDevice {
 };
 
 typedef enum {
+    VIR_DOMAIN_EMULATOR_TYPE_DEFAULT,
+    VIR_DOMAIN_EMULATOR_TYPE_STUBDOM,
+
+    VIR_DOMAIN_EMULATOR_TYPE_LAST
+} virDomainEmulatorType;
+
+typedef enum {
     VIR_DOMAIN_RNG_MODEL_VIRTIO,
 
     VIR_DOMAIN_RNG_MODEL_LAST
@@ -2083,6 +2090,7 @@ struct _virDomainDef {
 
     virDomainOSDef os;
     char *emulator;
+    virDomainEmulatorType emulator_type;
     /* These three options are of type virTristateSwitch,
      * except VIR_DOMAIN_FEATURE_CAPABILITIES that is of type
      * virDomainCapabilitiesPolicy */
@@ -2841,6 +2849,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
 VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy)
 VIR_ENUM_DECL(virDomainHyperv)
 VIR_ENUM_DECL(virDomainKVM)
+VIR_ENUM_DECL(virDomainEmulatorType)
 VIR_ENUM_DECL(virDomainRNGModel)
 VIR_ENUM_DECL(virDomainRNGBackend)
 VIR_ENUM_DECL(virDomainTPMModel)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index b1131ea..a84ce09 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -768,6 +768,23 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
             b_info->device_model_version = libxlDomainGetEmulatorType(def);
         }
 
+        /* In case of stubdom there will be two qemu instances:
+         *  - in stubdom (libxl uses hardcoded path for this one),
+         *  - in dom0 as a backend for stubdom (if needed).
+         * Emulator path control only the second one. It makes a perfect sense
+         * to use <emulator type='stubdom'/> (yes, without emulator path).
+         */
+        if (def->emulator_type == VIR_DOMAIN_EMULATOR_TYPE_STUBDOM)
+            libxl_defbool_set(&b_info->device_model_stubdomain, 1);
+
+        if (def->os.cmdline && def->os.cmdline[0]) {
+            b_info->extra_hvm = virStringSplit(def->os.cmdline, " ", 0);
+            if (b_info->extra_hvm == NULL) {
+                virReportOOMError();
+                return -1;
+            }
+        }
+
         if (def->nserials) {
             if (def->nserials > 1) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-- 
1.8.3.1

From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
To: libvirt-list@xxxxxxxxxx
Cc: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 10/10] tests: add some simple libxl XML->XML tests
Date: Thu,  5 Feb 2015 06:17:16 +0100
Message-Id: <1423113436-18213-11-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
X-Mailer: git-send-email 1.8.3.1
In-Reply-To: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
References: <1423113436-18213-1-git-send-email-marmarek@xxxxxxxxxxxxxxxxxxxxxx>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Invisible Things Lab

Handle features supported only on xen: driver domains, qemu in
stubdomain.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
---
 tests/Makefile.am                                  |   9 +-
 tests/domainschematest                             |   2 +-
 tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml      |  41 +++++
 tests/xlxml2xmldata/xlxml2xml-hvm.xml              |  40 +++++
 tests/xlxml2xmldata/xlxml2xml-network-bridged.xml  |  38 +++++
 .../xlxml2xml-network-driver-domain.xml            |  38 +++++
 tests/xlxml2xmldata/xlxml2xml-network-routed.xml   |  39 +++++
 tests/xlxml2xmldata/xlxml2xml-pv.xml               |  38 +++++
 tests/xlxml2xmltest.c                              | 189 +++++++++++++++++++++
 9 files changed, 431 insertions(+), 3 deletions(-)
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-hvm.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-network-bridged.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-network-driver-domain.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-network-routed.xml
 create mode 100644 tests/xlxml2xmldata/xlxml2xml-pv.xml
 create mode 100644 tests/xlxml2xmltest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 938270c..48648b9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -85,6 +85,7 @@ EXTRA_DIST =		\
 	domainsnapshotxml2xmlout \
 	fchostdata \
 	interfaceschemadata \
+	xlxml2xmldata \
 	lxcconf2xmldata \
 	lxcxml2xmldata \
 	lxcxml2xmloutdata \
@@ -230,7 +231,7 @@ test_programs += xml2sexprtest sexpr2xmltest \
 endif WITH_XEN
 
 if WITH_LIBXL
-test_programs += xlconfigtest
+test_programs += xlconfigtest xlxml2xmltest
 endif WITH_LIBXL
 
 if WITH_QEMU
@@ -515,8 +516,12 @@ xlconfigtest_SOURCES = \
 	xlconfigtest.c testutilsxen.c testutilsxen.h \
 	testutils.c testutils.h
 xlconfigtest_LDADD =$(libxl_LDADDS)
+xlxml2xmltest_SOURCES = \
+	xlxml2xmltest.c testutilsxen.c testutilsxen.h \
+	testutils.c testutils.h
+xlxml2xmltest_LDADD =$(libxl_LDADDS)
 else ! WITH_LIBXL
-EXTRA_DIST += xlconfigtest.c
+EXTRA_DIST += xlconfigtest.c xlxml2xmltest.c
 endif ! WITH_LIBXL
 
 QEMUMONITORTESTUTILS_SOURCES = \
diff --git a/tests/domainschematest b/tests/domainschematest
index ba90180..18b442b 100755
--- a/tests/domainschematest
+++ b/tests/domainschematest
@@ -8,7 +8,7 @@ DIRS=""
 DIRS="$DIRS domainschemadata qemuxml2argvdata sexpr2xmldata"
 DIRS="$DIRS xmconfigdata xml2sexprdata qemuxml2xmloutdata"
 DIRS="$DIRS lxcxml2xmldata lxcxml2xmloutdata"
-DIRS="$DIRS bhyvexml2argvdata"
+DIRS="$DIRS bhyvexml2argvdata xlxml2xmldata"
 SCHEMA="domain.rng"
 
 check_schema "$DIRS" "$SCHEMA"
diff --git a/tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml b/tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml
new file mode 100644
index 0000000..ed6440c
--- /dev/null
+++ b/tests/xlxml2xmldata/xlxml2xml-hvm-stubdom.xml
@@ -0,0 +1,41 @@
+<domain type='xen'>
+  <name>testhvm</name>
+  <uuid>a3d3fa04-dc23-4136-9eab-b579d2930817</uuid>
+  <memory unit='KiB'>524288</memory>
+  <currentMemory unit='KiB'>524288</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenfv'>hvm</type>
+    <loader type='rom'>/usr/lib/xen/boot/hvmloader</loader>
+    <boot dev='cdrom'/>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+    <viridian/>
+  </features>
+  <clock offset='variable' adjustment='0' basis='localtime'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>destroy</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator type='stubdom'>/usr/lib/xen/bin/qemu-dm</emulator>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testhvm/root.img'/>
+      <target dev='xvda' bus='xen'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testhvm/private.img'/>
+      <target dev='xvdb' bus='xen'/>
+    </disk>
+    <interface type='network'>
+      <mac address='00:16:3e:5e:6c:09'/>
+      <source network='default'/>
+    </interface>
+    <input type='tablet' bus='usb'/>
+  </devices>
+</domain>
diff --git a/tests/xlxml2xmldata/xlxml2xml-hvm.xml b/tests/xlxml2xmldata/xlxml2xml-hvm.xml
new file mode 100644
index 0000000..95d9b84
--- /dev/null
+++ b/tests/xlxml2xmldata/xlxml2xml-hvm.xml
@@ -0,0 +1,40 @@
+<domain type='xen'>
+  <name>testhvm</name>
+  <uuid>a3d3fa04-dc23-4136-9eab-b579d2930817</uuid>
+  <memory unit='KiB'>524288</memory>
+  <currentMemory unit='KiB'>524288</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenfv'>hvm</type>
+    <loader type='rom'>/usr/lib/xen/boot/hvmloader</loader>
+    <boot dev='cdrom'/>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <apic/>
+    <pae/>
+    <viridian/>
+  </features>
+  <clock offset='variable' adjustment='0' basis='localtime'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>destroy</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testhvm/root.img'/>
+      <target dev='xvda' bus='xen'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testhvm/private.img'/>
+      <target dev='xvdb' bus='xen'/>
+    </disk>
+    <interface type='network'>
+      <mac address='00:16:3e:5e:6c:09'/>
+      <source network='default'/>
+    </interface>
+    <input type='tablet' bus='usb'/>
+  </devices>
+</domain>
diff --git a/tests/xlxml2xmldata/xlxml2xml-network-bridged.xml b/tests/xlxml2xmldata/xlxml2xml-network-bridged.xml
new file mode 100644
index 0000000..a6b8f59
--- /dev/null
+++ b/tests/xlxml2xmldata/xlxml2xml-network-bridged.xml
@@ -0,0 +1,38 @@
+<domain type='xen'>
+  <name>testvm</name>
+  <uuid>900e3685-4998-41ad-a2c9-e496a5ed40a4</uuid>
+  <memory unit='KiB'>4096000</memory>
+  <currentMemory unit='KiB'>409600</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenpv'>linux</type>
+    <kernel>/boot/vmlinuz-3.12.37-1</kernel>
+    <initrd>/boot/initramfs-3.12.37-1.img</initrd>
+    <cmdline>root=/dev/xvda ro nomodeset console=hvc0 rd_NO_PLYMOUTH 3</cmdline>
+  </os>
+  <clock offset='utc' adjustment='reset'>
+    <timer name='tsc' mode='native'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>destroy</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testvm/root.img'/>
+      <target dev='xvda' bus='xen'/>
+    </disk>
+    <disk type='block' device='disk'>
+      <driver name='file'/>
+      <source dev='/var/lib/libvirt/images/testvm/home.img'/>
+      <target dev='xvdb' bus='xen'/>
+    </disk>
+    <interface type='bridge'>
+      <mac address='00:16:3e:5e:6c:09'/>
+      <source bridge='xenbr0'/>
+    </interface>
+    <console type='pty'>
+      <target type='xen' port='0'/>
+    </console>
+  </devices>
+</domain>
diff --git a/tests/xlxml2xmldata/xlxml2xml-network-driver-domain.xml b/tests/xlxml2xmldata/xlxml2xml-network-driver-domain.xml
new file mode 100644
index 0000000..31c0437
--- /dev/null
+++ b/tests/xlxml2xmldata/xlxml2xml-network-driver-domain.xml
@@ -0,0 +1,38 @@
+<domain type='xen'>
+  <name>testvm</name>
+  <uuid>900e3685-4998-41ad-a2c9-e496a5ed40a4</uuid>
+  <memory unit='KiB'>4096000</memory>
+  <currentMemory unit='KiB'>409600</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenpv'>linux</type>
+    <kernel>/boot/vmlinuz-3.12.37-1</kernel>
+    <initrd>/boot/initramfs-3.12.37-1.img</initrd>
+    <cmdline>root=/dev/xvda ro nomodeset console=hvc0 rd_NO_PLYMOUTH 3</cmdline>
+  </os>
+  <clock offset='utc' adjustment='reset'>
+    <timer name='tsc' mode='native'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>destroy</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testvm/root.img'/>
+      <target dev='xvda' bus='xen'/>
+    </disk>
+    <disk type='block' device='disk'>
+      <driver name='file'/>
+      <source dev='/var/lib/libvirt/images/testvm/home.img'/>
+      <target dev='xvdb' bus='xen'/>
+    </disk>
+    <interface type='bridge'>
+      <mac address='00:16:3e:5e:6c:09'/>
+      <source bridge='xenbr0' domain='netvm'/>
+    </interface>
+    <console type='pty'>
+      <target type='xen' port='0'/>
+    </console>
+  </devices>
+</domain>
diff --git a/tests/xlxml2xmldata/xlxml2xml-network-routed.xml b/tests/xlxml2xmldata/xlxml2xml-network-routed.xml
new file mode 100644
index 0000000..fac9d8d
--- /dev/null
+++ b/tests/xlxml2xmldata/xlxml2xml-network-routed.xml
@@ -0,0 +1,39 @@
+<domain type='xen'>
+  <name>testvm</name>
+  <uuid>900e3685-4998-41ad-a2c9-e496a5ed40a4</uuid>
+  <memory unit='KiB'>4096000</memory>
+  <currentMemory unit='KiB'>409600</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenpv'>linux</type>
+    <kernel>/boot/vmlinuz-3.12.37-1</kernel>
+    <initrd>/boot/initramfs-3.12.37-1.img</initrd>
+    <cmdline>root=/dev/xvda ro nomodeset console=hvc0 rd_NO_PLYMOUTH 3</cmdline>
+  </os>
+  <clock offset='utc' adjustment='reset'>
+    <timer name='tsc' mode='native'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>destroy</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testvm/root.img'/>
+      <target dev='xvda' bus='xen'/>
+    </disk>
+    <disk type='block' device='disk'>
+      <driver name='file'/>
+      <source dev='/var/lib/libvirt/images/testvm/home.img'/>
+      <target dev='xvdb' bus='xen'/>
+    </disk>
+    <interface type='ethernet'>
+      <mac address='00:16:3e:5e:6c:09'/>
+      <ip address='192.168.0.1' family='ipv4'/>
+      <script path='vif-route'/>
+    </interface>
+    <console type='pty'>
+      <target type='xen' port='0'/>
+    </console>
+  </devices>
+</domain>
diff --git a/tests/xlxml2xmldata/xlxml2xml-pv.xml b/tests/xlxml2xmldata/xlxml2xml-pv.xml
new file mode 100644
index 0000000..b937b8b
--- /dev/null
+++ b/tests/xlxml2xmldata/xlxml2xml-pv.xml
@@ -0,0 +1,38 @@
+<domain type='xen'>
+  <name>testvm</name>
+  <uuid>900e3685-4998-41ad-a2c9-e496a5ed40a4</uuid>
+  <memory unit='KiB'>4096000</memory>
+  <currentMemory unit='KiB'>409600</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <os>
+    <type arch='x86_64' machine='xenpv'>linux</type>
+    <kernel>/boot/vmlinuz-3.12.37-1</kernel>
+    <initrd>/boot/initramfs-3.12.37-1.img</initrd>
+    <cmdline>root=/dev/xvda ro nomodeset console=hvc0 rd_NO_PLYMOUTH 3</cmdline>
+  </os>
+  <clock offset='utc' adjustment='reset'>
+    <timer name='tsc' mode='native'/>
+  </clock>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>destroy</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <driver name='file'/>
+      <source file='/var/lib/libvirt/images/testvm/root.img'/>
+      <target dev='xvda' bus='xen'/>
+    </disk>
+    <disk type='block' device='disk'>
+      <driver name='file'/>
+      <source dev='/var/lib/libvirt/images/testvm/home.img'/>
+      <target dev='xvdb' bus='xen'/>
+    </disk>
+    <interface type='network'>
+      <mac address='00:16:3e:5e:6c:09'/>
+      <source network='default'/>
+    </interface>
+    <console type='pty'>
+      <target type='xen' port='0'/>
+    </console>
+  </devices>
+</domain>
diff --git a/tests/xlxml2xmltest.c b/tests/xlxml2xmltest.c
new file mode 100644
index 0000000..131e43b
--- /dev/null
+++ b/tests/xlxml2xmltest.c
@@ -0,0 +1,189 @@
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include "testutils.h"
+
+#ifdef WITH_LIBXL
+
+# include "internal.h"
+# include "libxl/libxl_conf.h"
+# include "libxl/libxl_domain.h"
+# include "testutilsxen.h"
+# include "virstring.h"
+
+# define VIR_FROM_THIS VIR_FROM_NONE
+
+static virCapsPtr caps;
+static virDomainXMLOptionPtr xmlopt;
+
+static int
+testCompareXMLToXMLFiles(const char *inxml, const char *outxml, bool live)
+{
+    char *inXmlData = NULL;
+    char *outXmlData = NULL;
+    char *actual = NULL;
+    int ret = -1;
+    virDomainDefPtr def = NULL;
+    unsigned int parse_flags = live ? 0 : VIR_DOMAIN_DEF_PARSE_INACTIVE;
+    unsigned int format_flags = VIR_DOMAIN_DEF_FORMAT_SECURE;
+    if (!live)
+        format_flags |= VIR_DOMAIN_DEF_FORMAT_INACTIVE;
+
+    if (virtTestLoadFile(inxml, &inXmlData) < 0)
+        goto fail;
+    if (virtTestLoadFile(outxml, &outXmlData) < 0)
+        goto fail;
+
+    if (!(def = virDomainDefParseString(inXmlData, caps, xmlopt,
+                                        1 << VIR_DOMAIN_VIRT_XEN, parse_flags)))
+        goto fail;
+
+    if (!virDomainDefCheckABIStability(def, def)) {
+        fprintf(stderr, "ABI stability check failed on %s", inxml);
+        goto fail;
+    }
+
+    if (!(actual = virDomainDefFormat(def, format_flags)))
+        goto fail;
+
+    if (STRNEQ(outXmlData, actual)) {
+        virtTestDifferenceFull(stderr, outXmlData, outxml, actual, inxml);
+        goto fail;
+    }
+
+    ret = 0;
+ fail:
+    VIR_FREE(inXmlData);
+    VIR_FREE(outXmlData);
+    VIR_FREE(actual);
+    virDomainDefFree(def);
+    return ret;
+}
+
+enum {
+    WHEN_INACTIVE = 1,
+    WHEN_ACTIVE = 2,
+    WHEN_EITHER = 3,
+};
+
+struct testInfo {
+    const char *name;
+    bool different;
+    int when;
+};
+
+static int
+testCompareXMLToXMLHelper(const void *data)
+{
+    const struct testInfo *info = data;
+    char *xml_in = NULL;
+    char *xml_out = NULL;
+    char *xml_out_active = NULL;
+    char *xml_out_inactive = NULL;
+    int ret = -1;
+
+    if (virAsprintf(&xml_in, "%s/xlxml2xmldata/xlxml2xml-%s.xml",
+                    abs_srcdir, info->name) < 0 ||
+        virAsprintf(&xml_out, "%s/xlxml2xmldata/xlxml2xml-%s-out.xml",
+                    abs_srcdir, info->name) < 0 ||
+        virAsprintf(&xml_out_active,
+                    "%s/xlxml2xmldata/xlxml2xml-%s-active.xml",
+                    abs_srcdir, info->name) < 0 ||
+        virAsprintf(&xml_out_inactive,
+                    "%s/xlxml2xmldata/xlxml2xml-%s-inactive.xml",
+                    abs_srcdir, info->name) < 0)
+        goto cleanup;
+
+    if ((info->when & WHEN_INACTIVE)) {
+        char *out;
+        if (!info->different)
+            out = xml_in;
+        else if (virFileExists(xml_out_inactive))
+            out = xml_out_inactive;
+        else
+            out = xml_out;
+
+        if (testCompareXMLToXMLFiles(xml_in, out, false) < 0)
+            goto cleanup;
+    }
+
+    if ((info->when & WHEN_ACTIVE)) {
+        char *out;
+        if (!info->different)
+            out = xml_in;
+        else if (virFileExists(xml_out_active))
+            out = xml_out_active;
+        else
+            out = xml_out;
+
+        if (testCompareXMLToXMLFiles(xml_in, out, true) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(xml_in);
+    VIR_FREE(xml_out);
+    VIR_FREE(xml_out_active);
+    VIR_FREE(xml_out_inactive);
+    return ret;
+}
+
+
+static int
+mymain(void)
+{
+    int ret = 0;
+
+    if ((caps = testXLInitCaps()) == NULL)
+        return EXIT_FAILURE;
+
+    if (!(xmlopt = libxlCreateXMLConf()))
+        return EXIT_FAILURE;
+
+# define DO_TEST_FULL(name, is_different, when)                         \
+    do {                                                                \
+        const struct testInfo info = {name, is_different, when};        \
+        if (virtTestRun("LibXL XML-2-XML " name,                         \
+                        testCompareXMLToXMLHelper, &info) < 0)          \
+            ret = -1;                                                   \
+    } while (0)
+
+# define DO_TEST(name) \
+    DO_TEST_FULL(name, false, WHEN_EITHER)
+
+# define DO_TEST_DIFFERENT(name) \
+    DO_TEST_FULL(name, true, WHEN_EITHER)
+
+    DO_TEST("hvm");
+    DO_TEST("pv");
+    DO_TEST("hvm-stubdom");
+    DO_TEST("network-bridged");
+    DO_TEST("network-routed");
+    DO_TEST("network-driver-domain");
+
+    virObjectUnref(caps);
+    virObjectUnref(xmlopt);
+
+    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIRT_TEST_MAIN(mymain)
+
+#else
+
+int
+main(void)
+{
+    return EXIT_AM_SKIP;
+}
+
+#endif /* WITH_LIBXL */
-- 
1.8.3.1

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]