d71922
From 70e32568957d60bbea5f50fc2d9210e2faaca5cd Mon Sep 17 00:00:00 2001
d71922
Message-Id: <70e32568957d60bbea5f50fc2d9210e2faaca5cd@dist-git>
d71922
From: Matthias Bolte <matthias.bolte@googlemail.com>
d71922
Date: Mon, 8 Feb 2016 13:47:35 +0100
d71922
Subject: [PATCH] vmx: Expose datacenter path in domain XML
d71922
d71922
RHEL-7.3: https://bugzilla.redhat.com/show_bug.cgi?id=1263574
d71922
RHEL-7.2.z: https://bugzilla.redhat.com/show_bug.cgi?id=1305489
d71922
d71922
Tool such as libguestfs need the datacenter path to get access to disk
d71922
images. The ESX driver knows the correct datacenter path, but this
d71922
information cannot be accessed using libvirt API yet. Also, it cannot
d71922
be deduced from the connection URI in a robust way.
d71922
d71922
Expose the datacenter path in the domain XML as <vmware:datacenterpath>
d71922
node similar to the way the <qemu:commandline> node works. The new node
d71922
is ignored while parsing the domain XML. In contrast to <qemu:commandline>
d71922
it is output only.
d71922
d71922
(cherry picked from commit 636a99058758a0447482f3baad94de8de3ab1151)
d71922
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
d71922
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
d71922
---
d71922
 src/esx/esx_driver.c                         |  4 ++
d71922
 src/vmware/vmware_conf.c                     |  3 ++
d71922
 src/vmware/vmware_driver.c                   |  9 ++++
d71922
 src/vmx/vmx.c                                | 68 +++++++++++++++++++++++-----
d71922
 src/vmx/vmx.h                                | 10 ++--
d71922
 tests/vmx2xmldata/vmx2xml-datacenterpath.vmx |  2 +
d71922
 tests/vmx2xmldata/vmx2xml-datacenterpath.xml | 19 ++++++++
d71922
 tests/vmx2xmltest.c                          |  5 ++
d71922
 tests/xml2vmxdata/xml2vmx-datacenterpath.vmx | 10 ++++
d71922
 tests/xml2vmxdata/xml2vmx-datacenterpath.xml |  9 ++++
d71922
 tests/xml2vmxtest.c                          |  3 ++
d71922
 11 files changed, 126 insertions(+), 16 deletions(-)
d71922
 create mode 100644 tests/vmx2xmldata/vmx2xml-datacenterpath.vmx
d71922
 create mode 100644 tests/vmx2xmldata/vmx2xml-datacenterpath.xml
d71922
 create mode 100644 tests/xml2vmxdata/xml2vmx-datacenterpath.vmx
d71922
 create mode 100644 tests/xml2vmxdata/xml2vmx-datacenterpath.xml
d71922
d71922
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
d71922
index c304ff3..5944947 100644
d71922
--- a/src/esx/esx_driver.c
d71922
+++ b/src/esx/esx_driver.c
d71922
@@ -2741,6 +2741,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
d71922
     ctx.parseFileName = esxParseVMXFileName;
d71922
     ctx.formatFileName = NULL;
d71922
     ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = priv->primary->datacenterPath;
d71922
 
d71922
     def = virVMXParseConfig(&ctx, priv->xmlopt, vmx);
d71922
 
d71922
@@ -2799,6 +2800,7 @@ esxConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
d71922
     ctx.parseFileName = esxParseVMXFileName;
d71922
     ctx.formatFileName = NULL;
d71922
     ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     def = virVMXParseConfig(&ctx, priv->xmlopt, nativeConfig);
d71922
 
d71922
@@ -2853,6 +2855,7 @@ esxConnectDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
d71922
     ctx.parseFileName = NULL;
d71922
     ctx.formatFileName = esxFormatVMXFileName;
d71922
     ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version);
d71922
 
d71922
@@ -3096,6 +3099,7 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
d71922
     ctx.parseFileName = NULL;
d71922
     ctx.formatFileName = esxFormatVMXFileName;
d71922
     ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version);
d71922
 
d71922
diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c
d71922
index 21cf333..f3cbbf5 100644
d71922
--- a/src/vmware/vmware_conf.c
d71922
+++ b/src/vmware/vmware_conf.c
d71922
@@ -145,6 +145,9 @@ vmwareLoadDomains(struct vmware_driver *driver)
d71922
     virCommandPtr cmd;
d71922
 
d71922
     ctx.parseFileName = vmwareCopyVMXFileName;
d71922
+    ctx.formatFileName = NULL;
d71922
+    ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     cmd = virCommandNewArgList(driver->vmrun, "-T",
d71922
                                vmwareDriverTypeToString(driver->type),
d71922
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
d71922
index ec74fe3..e228aaa 100644
d71922
--- a/src/vmware/vmware_driver.c
d71922
+++ b/src/vmware/vmware_driver.c
d71922
@@ -381,7 +381,10 @@ vmwareDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int fla
d71922
     if (flags & VIR_DOMAIN_DEFINE_VALIDATE)
d71922
         parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE;
d71922
 
d71922
+    ctx.parseFileName = NULL;
d71922
     ctx.formatFileName = vmwareCopyVMXFileName;
d71922
+    ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     vmwareDriverLock(driver);
d71922
     if ((vmdef = virDomainDefParseString(xml, driver->caps, driver->xmlopt,
d71922
@@ -671,7 +674,10 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml,
d71922
     if (flags & VIR_DOMAIN_START_VALIDATE)
d71922
         parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE;
d71922
 
d71922
+    ctx.parseFileName = NULL;
d71922
     ctx.formatFileName = vmwareCopyVMXFileName;
d71922
+    ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     vmwareDriverLock(driver);
d71922
 
d71922
@@ -1022,6 +1028,9 @@ vmwareConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
d71922
     }
d71922
 
d71922
     ctx.parseFileName = vmwareCopyVMXFileName;
d71922
+    ctx.formatFileName = NULL;
d71922
+    ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     def = virVMXParseConfig(&ctx, driver->xmlopt, nativeConfig);
d71922
 
d71922
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
d71922
index 805ad60..2befdb2 100644
d71922
--- a/src/vmx/vmx.c
d71922
+++ b/src/vmx/vmx.c
d71922
@@ -523,10 +523,11 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
d71922
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
d71922
  * Helpers
d71922
  */
d71922
+
d71922
 static int
d71922
-vmxDomainDefPostParse(virDomainDefPtr def,
d71922
-                      virCapsPtr caps ATTRIBUTE_UNUSED,
d71922
-                      void *opaque ATTRIBUTE_UNUSED)
d71922
+virVMXDomainDefPostParse(virDomainDefPtr def,
d71922
+                         virCapsPtr caps ATTRIBUTE_UNUSED,
d71922
+                         void *opaque ATTRIBUTE_UNUSED)
d71922
 {
d71922
     /* memory hotplug tunables are not supported by this driver */
d71922
     if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0)
d71922
@@ -536,27 +537,60 @@ vmxDomainDefPostParse(virDomainDefPtr def,
d71922
 }
d71922
 
d71922
 static int
d71922
-vmxDomainDeviceDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
d71922
-                            const virDomainDef *def ATTRIBUTE_UNUSED,
d71922
-                            virCapsPtr caps ATTRIBUTE_UNUSED,
d71922
-                            void *opaque ATTRIBUTE_UNUSED)
d71922
+virVMXDomainDevicesDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
d71922
+                                const virDomainDef *def ATTRIBUTE_UNUSED,
d71922
+                                virCapsPtr caps ATTRIBUTE_UNUSED,
d71922
+                                void *opaque ATTRIBUTE_UNUSED)
d71922
 {
d71922
     return 0;
d71922
 }
d71922
 
d71922
-virDomainDefParserConfig virVMXDomainDefParserConfig = {
d71922
+static virDomainDefParserConfig virVMXDomainDefParserConfig = {
d71922
     .hasWideSCSIBus = true,
d71922
     .macPrefix = {0x00, 0x0c, 0x29},
d71922
-    .devicesPostParseCallback = vmxDomainDeviceDefPostParse,
d71922
-    .domainPostParseCallback = vmxDomainDefPostParse,
d71922
+    .devicesPostParseCallback = virVMXDomainDevicesDefPostParse,
d71922
+    .domainPostParseCallback = virVMXDomainDefPostParse,
d71922
 };
d71922
 
d71922
+static void
d71922
+virVMXDomainDefNamespaceFree(void *nsdata)
d71922
+{
d71922
+    VIR_FREE(nsdata);
d71922
+}
d71922
+
d71922
+static int
d71922
+virVMXDomainDefNamespaceFormatXML(virBufferPtr buf, void *nsdata)
d71922
+{
d71922
+    const char *datacenterPath = nsdata;
d71922
+
d71922
+    if (!datacenterPath)
d71922
+        return 0;
d71922
+
d71922
+    virBufferAddLit(buf, "<vmware:datacenterpath>");
d71922
+    virBufferEscapeString(buf, "%s", datacenterPath);
d71922
+    virBufferAddLit(buf, "</vmware:datacenterpath>\n");
d71922
+
d71922
+    return 0;
d71922
+}
d71922
+
d71922
+static const char *
d71922
+virVMXDomainDefNamespaceHref(void)
d71922
+{
d71922
+    return "xmlns:vmware='http://libvirt.org/schemas/domain/vmware/1.0'";
d71922
+}
d71922
+
d71922
+static virDomainXMLNamespace virVMXDomainXMLNamespace = {
d71922
+    .parse = NULL,
d71922
+    .free = virVMXDomainDefNamespaceFree,
d71922
+    .format = virVMXDomainDefNamespaceFormatXML,
d71922
+    .href = virVMXDomainDefNamespaceHref,
d71922
+};
d71922
 
d71922
 virDomainXMLOptionPtr
d71922
 virVMXDomainXMLConfInit(void)
d71922
 {
d71922
-    return virDomainXMLOptionNew(&virVMXDomainDefParserConfig,
d71922
-                               NULL, NULL);
d71922
+    return virDomainXMLOptionNew(&virVMXDomainDefParserConfig, NULL,
d71922
+                                 &virVMXDomainXMLNamespace);
d71922
 }
d71922
 
d71922
 char *
d71922
@@ -1266,6 +1300,7 @@ virVMXParseConfig(virVMXContext *ctx,
d71922
     bool hgfs_disabled = true;
d71922
     long long sharedFolder_maxNum = 0;
d71922
     int cpumasklen;
d71922
+    char *namespaceData;
d71922
 
d71922
     if (ctx->parseFileName == NULL) {
d71922
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
d71922
@@ -1765,6 +1800,15 @@ virVMXParseConfig(virVMXContext *ctx,
d71922
             ++def->nparallels;
d71922
     }
d71922
 
d71922
+    /* ctx:datacenterPath -> def:namespaceData */
d71922
+    if (ctx->datacenterPath) {
d71922
+        if (VIR_STRDUP(namespaceData, ctx->datacenterPath) < 0)
d71922
+            goto cleanup;
d71922
+
d71922
+        def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
d71922
+        def->namespaceData = namespaceData;
d71922
+    }
d71922
+
d71922
     success = true;
d71922
 
d71922
  cleanup:
d71922
diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h
d71922
index 6a68c8b..0f012fd 100644
d71922
--- a/src/vmx/vmx.h
d71922
+++ b/src/vmx/vmx.h
d71922
@@ -1,7 +1,7 @@
d71922
 /*
d71922
  * vmx.h: VMware VMX parsing/formatting functions
d71922
  *
d71922
- * Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte@googlemail.com>
d71922
+ * Copyright (C) 2009-2011, 2015 Matthias Bolte <matthias.bolte@googlemail.com>
d71922
  *
d71922
  * This library is free software; you can redistribute it and/or
d71922
  * modify it under the terms of the GNU Lesser General Public
d71922
@@ -41,15 +41,17 @@ typedef int (*virVMXAutodetectSCSIControllerModel)(virDomainDiskDefPtr def,
d71922
                                                    int *model, void *opaque);
d71922
 
d71922
 /*
d71922
- * virVMXParseFileName is only used by virVMXParseConfig.
d71922
- * virVMXFormatFileName is only used by virVMXFormatConfig.
d71922
- * virVMXAutodetectSCSIControllerModel is optionally used by virVMXFormatConfig.
d71922
+ * parseFileName is only used by virVMXParseConfig.
d71922
+ * formatFileName is only used by virVMXFormatConfig.
d71922
+ * autodetectSCSIControllerModel is optionally used by virVMXFormatConfig.
d71922
+ * datacenterPath is only used by virVMXFormatConfig.
d71922
  */
d71922
 struct _virVMXContext {
d71922
     void *opaque;
d71922
     virVMXParseFileName parseFileName;
d71922
     virVMXFormatFileName formatFileName;
d71922
     virVMXAutodetectSCSIControllerModel autodetectSCSIControllerModel;
d71922
+    const char *datacenterPath; /* including folders */
d71922
 };
d71922
 
d71922
 
d71922
diff --git a/tests/vmx2xmldata/vmx2xml-datacenterpath.vmx b/tests/vmx2xmldata/vmx2xml-datacenterpath.vmx
d71922
new file mode 100644
d71922
index 0000000..a8e5db3
d71922
--- /dev/null
d71922
+++ b/tests/vmx2xmldata/vmx2xml-datacenterpath.vmx
d71922
@@ -0,0 +1,2 @@
d71922
+config.version = "8"
d71922
+virtualHW.version = "4"
d71922
diff --git a/tests/vmx2xmldata/vmx2xml-datacenterpath.xml b/tests/vmx2xmldata/vmx2xml-datacenterpath.xml
d71922
new file mode 100644
d71922
index 0000000..a690c0f
d71922
--- /dev/null
d71922
+++ b/tests/vmx2xmldata/vmx2xml-datacenterpath.xml
d71922
@@ -0,0 +1,19 @@
d71922
+<domain type='vmware' xmlns:vmware='http://libvirt.org/schemas/domain/vmware/1.0'>
d71922
+  <uuid>00000000-0000-0000-0000-000000000000</uuid>
d71922
+  <memory unit='KiB'>32768</memory>
d71922
+  <currentMemory unit='KiB'>32768</currentMemory>
d71922
+  <vcpu placement='static'>1</vcpu>
d71922
+  <os>
d71922
+    <type arch='i686'>hvm</type>
d71922
+  </os>
d71922
+  <clock offset='utc'/>
d71922
+  <on_poweroff>destroy</on_poweroff>
d71922
+  <on_reboot>restart</on_reboot>
d71922
+  <on_crash>destroy</on_crash>
d71922
+  <devices>
d71922
+    <video>
d71922
+      <model type='vmvga' vram='4096'/>
d71922
+    </video>
d71922
+  </devices>
d71922
+  <vmware:datacenterpath>folder1/folder2/datacenter1</vmware:datacenterpath>
d71922
+</domain>
d71922
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
d71922
index b8dbd31..258cba3 100644
d71922
--- a/tests/vmx2xmltest.c
d71922
+++ b/tests/vmx2xmltest.c
d71922
@@ -201,6 +201,7 @@ mymain(void)
d71922
     ctx.parseFileName = testParseVMXFileName;
d71922
     ctx.formatFileName = NULL;
d71922
     ctx.autodetectSCSIControllerModel = NULL;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     DO_TEST("case-insensitive-1", "case-insensitive-1");
d71922
     DO_TEST("case-insensitive-2", "case-insensitive-2");
d71922
@@ -283,6 +284,10 @@ mymain(void)
d71922
 
d71922
     DO_TEST("svga", "svga");
d71922
 
d71922
+    ctx.datacenterPath = "folder1/folder2/datacenter1";
d71922
+
d71922
+    DO_TEST("datacenterpath", "datacenterpath");
d71922
+
d71922
     virObjectUnref(caps);
d71922
     virObjectUnref(xmlopt);
d71922
 
d71922
diff --git a/tests/xml2vmxdata/xml2vmx-datacenterpath.vmx b/tests/xml2vmxdata/xml2vmx-datacenterpath.vmx
d71922
new file mode 100644
d71922
index 0000000..59bde03
d71922
--- /dev/null
d71922
+++ b/tests/xml2vmxdata/xml2vmx-datacenterpath.vmx
d71922
@@ -0,0 +1,10 @@
d71922
+.encoding = "UTF-8"
d71922
+config.version = "8"
d71922
+virtualHW.version = "4"
d71922
+guestOS = "other"
d71922
+uuid.bios = "56 4d 9b ef ac d9 b4 e0-c8 f0 ae a8 b9 10 35 15"
d71922
+displayName = "datacenterpath"
d71922
+memsize = "4"
d71922
+numvcpus = "1"
d71922
+floppy0.present = "false"
d71922
+floppy1.present = "false"
d71922
diff --git a/tests/xml2vmxdata/xml2vmx-datacenterpath.xml b/tests/xml2vmxdata/xml2vmx-datacenterpath.xml
d71922
new file mode 100644
d71922
index 0000000..048e13d
d71922
--- /dev/null
d71922
+++ b/tests/xml2vmxdata/xml2vmx-datacenterpath.xml
d71922
@@ -0,0 +1,9 @@
d71922
+<domain type='vmware' xmlns:vmware='http://libvirt.org/schemas/domain/vmware/1.0'>
d71922
+  <name>datacenterpath</name>
d71922
+  <uuid>564d9bef-acd9-b4e0-c8f0-aea8b9103515</uuid>
d71922
+  <memory unit='KiB'>4096</memory>
d71922
+  <os>
d71922
+    <type>hvm</type>
d71922
+  </os>
d71922
+  <vmware:datacenterpath>folder1/folder2/datacenter1</vmware:datacenterpath>
d71922
+</domain>
d71922
diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c
d71922
index 0efd278..d970240 100644
d71922
--- a/tests/xml2vmxtest.c
d71922
+++ b/tests/xml2vmxtest.c
d71922
@@ -221,6 +221,7 @@ mymain(void)
d71922
     ctx.parseFileName = NULL;
d71922
     ctx.formatFileName = testFormatVMXFileName;
d71922
     ctx.autodetectSCSIControllerModel = testAutodetectSCSIControllerModel;
d71922
+    ctx.datacenterPath = NULL;
d71922
 
d71922
     DO_TEST("minimal", "minimal", 4);
d71922
     DO_TEST("minimal-64bit", "minimal-64bit", 4);
d71922
@@ -295,6 +296,8 @@ mymain(void)
d71922
 
d71922
     DO_TEST("svga", "svga", 4);
d71922
 
d71922
+    DO_TEST("datacenterpath", "datacenterpath", 4);
d71922
+
d71922
     virObjectUnref(caps);
d71922
     virObjectUnref(xmlopt);
d71922
 
d71922
-- 
d71922
2.7.2
d71922