From 8247ae0539b9e13c3b9537a8a9c8fd7bbba98d77 Mon Sep 17 00:00:00 2001
From: Matthias Bolte <matthias.bolte@googlemail.com>
Date: Sat, 9 Jul 2011 16:16:45 +0200
Subject: [PATCH] vmx: Add snapshot preset and persistent options for disks

Suggested by Oleh Paliy.
---
 docs/schemas/domain.rng                         |   10 +++
 src/conf/domain_conf.c                          |   10 +++
 src/conf/domain_conf.h                          |    2 +
 src/vmx/vmx.c                                   |   89 ++++++++++++++++++-----
 tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.vmx |   63 ++++++++++++++++
 tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.xml |   51 +++++++++++++
 tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml |    1 +
 tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml |    1 +
 tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml |    1 +
 tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml |    1 +
 tests/vmx2xmltest.c                             |    1 +
 tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.vmx |   34 +++++++++
 tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.xml |   51 +++++++++++++
 tests/xml2vmxtest.c                             |    1 +
 14 files changed, 297 insertions(+), 19 deletions(-)
 create mode 100644 tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.vmx
 create mode 100644 tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.xml
 create mode 100644 tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.vmx
 create mode 100644 tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.xml

diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 8a4e3fe..d73c2fd 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -610,6 +610,16 @@
       </element>
     </optional>
     <optional>
+      <element name="independent">
+        <empty/>
+      </element>
+    </optional>
+    <optional>
+      <element name="nonpersistent">
+        <empty/>
+      </element>
+    </optional>
+    <optional>
       <element name="serial">
         <ref name="diskSerial"/>
       </element>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index bf2eadf..356619a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2150,6 +2150,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
                 def->readonly = 1;
             } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
                 def->shared = 1;
+            } else if (xmlStrEqual(cur->name, BAD_CAST "independent")) {
+                def->independent = 1;
+            } else if (xmlStrEqual(cur->name, BAD_CAST "nonpersistent")) {
+                def->nonpersistent = 1;
             } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) &&
                        xmlStrEqual(cur->name, BAD_CAST "state")) {
                 /* Legacy back-compat. Don't add any more attributes here */
@@ -7182,6 +7186,8 @@ static bool virDomainDiskDefCheckABIStability(virDomainDiskDefPtr src,
         goto cleanup;
     }
 
+    /* FIXME: do we need to check independent and nonpersistent here too? */
+
     if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
         goto cleanup;
 
@@ -8579,6 +8585,10 @@ virDomainDiskDefFormat(virBufferPtr buf,
         virBufferAddLit(buf, "      <readonly/>\n");
     if (def->shared)
         virBufferAddLit(buf, "      <shareable/>\n");
+    if (def->independent)
+        virBufferAddLit(buf, "      <independent/>\n");
+    if (def->nonpersistent)
+        virBufferAddLit(buf, "      <nonpersistent/>\n");
     if (def->serial)
         virBufferEscapeString(buf, "      <serial>%s</serial>\n",
                               def->serial);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8262d25..bcfc2ac 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -236,6 +236,8 @@ struct _virDomainDiskDef {
     int ioeventfd;
     unsigned int readonly : 1;
     unsigned int shared : 1;
+    unsigned int independent : 1;
+    unsigned int nonpersistent : 1;
     virDomainDeviceInfo info;
     virStorageEncryptionPtr encryption;
 };
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index b37f03b..cd436cd 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -97,11 +97,6 @@ def->disks[0]...
                                         scsi0:0.present = "true"                # defaults to "false"
                                         scsi0:0.startConnected = "true"         # defaults to "true"
 
-???                               <=>   scsi0:0.mode = "persistent"             # defaults to "persistent"
-                                        scsi0:0.mode = "undoable"
-                                        scsi0:0.mode = "independent-persistent"
-                                        scsi0:0.mode = "independent-nonpersistent"
-
 ...
 ->type = _DISK_TYPE_FILE          <=>   scsi0:0.deviceType = "scsi-hardDisk"    # defaults to ?
 ->device = _DISK_DEVICE_DISK      <=>   scsi0:0.deviceType = "scsi-hardDisk"    # defaults to ?
@@ -113,7 +108,11 @@ def->disks[0]...
 ->cachemode                       <=>   scsi0:0.writeThrough = "<value>"        # defaults to false, true -> _DISK_CACHE_WRITETHRU, false _DISK_CACHE_DEFAULT
 ->readonly
 ->shared
-->slotnum
+->independent                     <=>   scsi0:0.mode = "persistent"             # defaults to "persistent"
+->nonpersistent                         scsi0:0.mode = "independent-persistent"
+                                        scsi0:0.mode = "independent-nonpersistent"
+                                        scsi0:0.mode = "undoable"               # legacy
+                                        scsi0:0.mode = "nonpersistent"          # legacy
 
 
 ## disks: ide hard drive from .vmdk image ######################################
@@ -121,11 +120,6 @@ def->disks[0]...
                                         ide0:0.present = "true"                 # defaults to "false"
                                         ide0:0.startConnected = "true"          # defaults to "true"
 
-???                               <=>   ide0:0.mode = "persistent"              # defaults to "persistent"
-                                        ide0:0.mode = "undoable"
-                                        ide0:0.mode = "independent-persistent"
-                                        ide0:0.mode = "independent-nonpersistent"
-
 ...
 ->type = _DISK_TYPE_FILE          <=>   ide0:0.deviceType = "ata-hardDisk"      # defaults to ?
 ->device = _DISK_DEVICE_DISK      <=>   ide0:0.deviceType = "ata-hardDisk"      # defaults to ?
@@ -137,7 +131,11 @@ def->disks[0]...
 ->cachemode                       <=>   ide0:0.writeThrough = "<value>"         # defaults to false, true -> _DISK_CACHE_WRITETHRU, false _DISK_CACHE_DEFAULT
 ->readonly
 ->shared
-->slotnum
+->independent                     <=>   ide0:0.mode = "persistent"              # defaults to "persistent"
+->nonpersistent                         ide0:0.mode = "independent-persistent"
+                                        ide0:0.mode = "independent-nonpersistent"
+                                        ide0:0.mode = "undoable"                # legacy
+                                        ide0:0.mode = "nonpersistent"           # legacy
 
 
 ## disks: scsi cdrom from .iso image ###########################################
@@ -157,7 +155,8 @@ def->disks[0]...
 ->cachemode
 ->readonly
 ->shared
-->slotnum
+->independent
+->nonpersistent
 
 
 ## disks: ide cdrom from .iso image ############################################
@@ -176,7 +175,8 @@ def->disks[0]...
 ->cachemode
 ->readonly
 ->shared
-->slotnum
+->independent
+->nonpersistent
 
 
 ## disks: scsi cdrom from host device ##########################################
@@ -196,7 +196,8 @@ def->disks[0]...
 ->cachemode
 ->readonly
 ->shared
-->slotnum
+->independent
+->nonpersistent
 
 
 ## disks: ide cdrom from host device ###########################################
@@ -216,7 +217,8 @@ def->disks[0]...
 ->cachemode
 ->readonly
 ->shared
-->slotnum
+->independent
+->nonpersistent
 
 
 ## disks: floppy from .flp image ###############################################
@@ -236,7 +238,8 @@ def->disks[0]...
 ->cachemode
 ->readonly
 ->shared
-->slotnum
+->independent
+->nonpersistent
 
 
 ## disks: floppy from host device ##############################################
@@ -256,7 +259,8 @@ def->disks[0]...
 ->cachemode
 ->readonly
 ->shared
-->slotnum
+->independent
+->nonpersistent
 
 
 
@@ -1932,6 +1936,9 @@ virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf,
     char writeThrough_name[32] = "";
     bool writeThrough = false;
 
+    char mode_name[32] = "";
+    char *mode = NULL;
+
     if (def == NULL || *def != NULL) {
         VMX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
         return -1;
@@ -2053,6 +2060,7 @@ virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf,
     VMX_BUILD_NAME(fileType);
     VMX_BUILD_NAME(fileName);
     VMX_BUILD_NAME(writeThrough);
+    VMX_BUILD_NAME(mode);
 
     /* vmx:present */
     if (virVMXGetConfigBoolean(conf, present_name, &present, false, true) < 0) {
@@ -2105,6 +2113,11 @@ virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf,
         goto cleanup;
     }
 
+    /* vmx:mode -> def:independent, def:nonpersistent */
+    if (virVMXGetConfigString(conf, mode_name, &mode, true) < 0) {
+        goto cleanup;
+    }
+
     /* Setup virDomainDiskDef */
     if (device == VIR_DOMAIN_DISK_DEVICE_DISK) {
         if (virFileHasSuffix(fileName, ".vmdk")) {
@@ -2130,10 +2143,29 @@ virVMXParseDisk(virVMXContext *ctx, virCapsPtr caps, virConfPtr conf,
 
             (*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
             (*def)->src = ctx->parseFileName(fileName, ctx->opaque);
+
+            if ((*def)->src == NULL) {
+                goto cleanup;
+            }
+
             (*def)->cachemode = writeThrough ? VIR_DOMAIN_DISK_CACHE_WRITETHRU
                                              : VIR_DOMAIN_DISK_CACHE_DEFAULT;
 
-            if ((*def)->src == NULL) {
+            if (mode == NULL || STRCASEEQ(mode, "persistent")) {
+                (*def)->independent = 0;
+                (*def)->nonpersistent = 0;
+            } else if (STRCASEEQ(mode, "independent-persistent") ||
+                       STRCASEEQ(mode, "undoable")) {
+                (*def)->independent = 1;
+                (*def)->nonpersistent = 0;
+            } else if (STRCASEEQ(mode, "independent-nonpersistent") ||
+                       STRCASEEQ(mode, "nonpersistent")) {
+                (*def)->independent = 1;
+                (*def)->nonpersistent = 1;
+            } else {
+                VMX_ERROR(VIR_ERR_INTERNAL_ERROR,
+                          _("Invalid or not yet handled value '%s' for VMX "
+                            "entry '%s'"), mode, mode_name);
                 goto cleanup;
             }
         } else if (virFileHasSuffix(fileName, ".iso") ||
@@ -3310,6 +3342,7 @@ virVMXFormatHardDisk(virVMXContext *ctx, virDomainDiskDefPtr def,
     }
 
     if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+        /* def:cachemode -> vmx:writeThrough */
         if (def->cachemode == VIR_DOMAIN_DISK_CACHE_WRITETHRU) {
             virBufferAsprintf(buffer, "%s%d:%d.writeThrough = \"true\"\n",
                               entryPrefix, controllerOrBus, unit);
@@ -3322,6 +3355,24 @@ virVMXFormatHardDisk(virVMXContext *ctx, virDomainDiskDefPtr def,
         }
     }
 
+    /* def:independent, def:nonpersistent -> vmx:mode */
+    /* FIXME: might need to output undoable and nonpersistent here too  */
+    if (def->independent == 0 && def->nonpersistent == 0) {
+        /* persistent is the default, don't output it */
+    } else if (def->independent == 1 && def->nonpersistent == 0) {
+        virBufferAsprintf(buffer, "%s%d:%d.mode = \"independent-persistent\"\n",
+                          entryPrefix, controllerOrBus, unit);
+    } else if (def->independent == 1 && def->nonpersistent == 1) {
+        virBufferAsprintf(buffer, "%s%d:%d.mode = \"independent-nonpersistent\"\n",
+                          entryPrefix, controllerOrBus, unit);
+    } else {
+        VMX_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
+                  _("%s harddisk '%s' has unsupported "
+                    "independent/nonpersistent combination"),
+                  busName, def->dst);
+        return -1;
+    }
+
     return 0;
 }
 
diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.vmx b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.vmx
new file mode 100644
index 0000000..4846df1
--- /dev/null
+++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.vmx
@@ -0,0 +1,63 @@
+#!/usr/bin/vmware
+.encoding = "UTF-8"
+config.version = "8"
+virtualHW.version = "4"
+nvram = "testvm.nvram"
+virtualHW.productCompatibility = "hosted"
+powerType.powerOff = "soft"
+powerType.powerOn = "hard"
+powerType.suspend = "hard"
+powerType.reset = "soft"
+displayName = "testvm"
+extendedConfigFile = "testvm.vmxf"
+scsi0.present = "TRUE"
+scsi0.sharedBus = "none"
+scsi0.virtualDev = "lsilogic"
+memsize = "256"
+scsi0:0.present = "TRUE"
+scsi0:0.fileName = "testvm.vmdk"
+scsi0:0.deviceType = "scsi-hardDisk"
+ide0:0.present = "TRUE"
+ide0:0.fileName = "CD-ROM 1"
+ide0:0.deviceType = "atapi-cdrom"
+ide0:0.startConnected = "FALSE"
+ethernet0.present = "TRUE"
+ethernet0.wakeOnPcktRcv = "FALSE"
+ethernet0.networkName = "VM Network"
+ethernet0.addressType = "generated"
+guestOS = "linux"
+uuid.location = "56 4d 27 3f 39 75 42 d5-82 7b d5 37 50 90 f1 f0"
+uuid.bios = "56 4d 27 3f 39 75 42 d5-82 7b d5 37 50 90 f1 f0"
+vc.uuid = "52 18 27 61 7f 30 e8 eb-e7 47 3e 82 9e c8 e1 88"
+sched.cpu.min = "0"
+sched.cpu.units = "mhz"
+sched.cpu.shares = "normal"
+sched.mem.minsize = "0"
+sched.mem.shares = "normal"
+ethernet0.generatedAddress = "00:0c:29:90:f1:f0"
+cleanShutdown = "TRUE"
+replay.supported = "FALSE"
+sched.swap.derivedName = "/vmfs/volumes/4d515963-ef9b0cde-15f7-001517fa90d1/testvm/testvm-b2877b1f.vswp"
+replay.filename = ""
+scsi0:0.redo = ""
+vmotion.checkpointFBSize = "4194304"
+ethernet0.generatedAddressOffset = "0"
+hostCPUID.0 = "0000000b756e65476c65746e49656e69"
+hostCPUID.1 = "000206c200200800029ee3ffbfebfbff"
+hostCPUID.80000001 = "0000000000000000000000012c100800"
+guestCPUID.0 = "0000000b756e65476c65746e49656e69"
+guestCPUID.1 = "000206c200010800029822030febfbff"
+guestCPUID.80000001 = "00000000000000000000000128100800"
+userCPUID.0 = "0000000b756e65476c65746e49656e69"
+userCPUID.1 = "000206c200200800029822030febfbff"
+userCPUID.80000001 = "00000000000000000000000128100800"
+evcCompatibilityMode = "FALSE"
+scsi0:1.present = "TRUE"
+scsi0:1.fileName = "testvm_1.vmdk"
+scsi0:1.mode = "independent-persistent"
+scsi0:1.deviceType = "scsi-hardDisk"
+scsi0:2.present = "TRUE"
+scsi0:2.fileName = "testvm_2.vmdk"
+scsi0:2.mode = "independent-nonpersistent"
+scsi0:2.deviceType = "scsi-hardDisk"
+floppy0.present = "FALSE"
diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.xml
new file mode 100644
index 0000000..7432ff5
--- /dev/null
+++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-7.xml
@@ -0,0 +1,51 @@
+<domain type='vmware'>
+  <name>testvm</name>
+  <uuid>564d273f-3975-42d5-827b-d5375090f1f0</uuid>
+  <memory>262144</memory>
+  <currentMemory>262144</currentMemory>
+  <vcpu>1</vcpu>
+  <cputune>
+    <shares>1000</shares>
+  </cputune>
+  <os>
+    <type arch='i686'>hvm</type>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <source file='[datastore] directory/testvm.vmdk'/>
+      <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='[datastore] directory/testvm_1.vmdk'/>
+      <target dev='sdb' bus='scsi'/>
+      <independent/>
+      <address type='drive' controller='0' bus='0' unit='1'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='[datastore] directory/testvm_2.vmdk'/>
+      <target dev='sdc' bus='scsi'/>
+      <independent/>
+      <nonpersistent/>
+      <address type='drive' controller='0' bus='0' unit='2'/>
+    </disk>
+    <disk type='block' device='cdrom'>
+      <source dev='CD-ROM 1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='lsilogic'/>
+    <controller type='ide' index='0'/>
+    <interface type='bridge'>
+      <mac address='00:0c:29:90:f1:f0'/>
+      <source bridge='VM Network'/>
+    </interface>
+    <video>
+      <model type='vmvga' vram='4096'/>
+    </video>
+  </devices>
+</domain>
diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml
index b572ad1..acc8abf 100644
--- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml
+++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml
@@ -15,6 +15,7 @@
     <disk type='file' device='disk'>
       <source file='[datastore] directory/Debian-System1-0-cl2.vmdk'/>
       <target dev='hda' bus='ide'/>
+      <independent/>
       <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
     <controller type='ide' index='0'/>
diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml
index 180cf68..9058d06 100644
--- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml
+++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml
@@ -15,6 +15,7 @@
     <disk type='file' device='disk'>
       <source file='[datastore] directory/Debian-System1-0-cl3.vmdk'/>
       <target dev='hda' bus='ide'/>
+      <independent/>
       <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
     <controller type='ide' index='0'/>
diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml
index 571c83a..8b0ac85 100644
--- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml
+++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml
@@ -15,6 +15,7 @@
     <disk type='file' device='disk'>
       <source file='[datastore] directory/Debian-System1-0-cl1.vmdk'/>
       <target dev='hda' bus='ide'/>
+      <independent/>
       <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
     <controller type='ide' index='0'/>
diff --git a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml
index fc3b966..a9a9522 100644
--- a/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml
+++ b/tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml
@@ -15,6 +15,7 @@
     <disk type='file' device='disk'>
       <source file='[datastore] directory/Debian-System1-0-cl2.vmdk'/>
       <target dev='hda' bus='ide'/>
+      <independent/>
       <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
     <controller type='ide' index='0'/>
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
index 92dc7d4..5ae934b 100644
--- a/tests/vmx2xmltest.c
+++ b/tests/vmx2xmltest.c
@@ -262,6 +262,7 @@ mymain(void)
     DO_TEST("esx-in-the-wild-4", "esx-in-the-wild-4");
     DO_TEST("esx-in-the-wild-5", "esx-in-the-wild-5");
     DO_TEST("esx-in-the-wild-6", "esx-in-the-wild-6");
+    DO_TEST("esx-in-the-wild-7", "esx-in-the-wild-7");
 
     DO_TEST("gsx-in-the-wild-1", "gsx-in-the-wild-1");
     DO_TEST("gsx-in-the-wild-2", "gsx-in-the-wild-2");
diff --git a/tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.vmx b/tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.vmx
new file mode 100644
index 0000000..999b0ee
--- /dev/null
+++ b/tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.vmx
@@ -0,0 +1,34 @@
+.encoding = "UTF-8"
+config.version = "8"
+virtualHW.version = "4"
+guestOS = "other"
+uuid.bios = "56 4d 27 3f 39 75 42 d5-82 7b d5 37 50 90 f1 f0"
+displayName = "testvm"
+memsize = "256"
+numvcpus = "1"
+sched.cpu.shares = "normal"
+scsi0.present = "true"
+scsi0.virtualDev = "lsilogic"
+scsi0:0.present = "true"
+scsi0:0.deviceType = "scsi-hardDisk"
+scsi0:0.fileName = "/vmfs/volumes/datastore/directory/testvm.vmdk"
+scsi0:1.present = "true"
+scsi0:1.deviceType = "scsi-hardDisk"
+scsi0:1.fileName = "/vmfs/volumes/datastore/directory/testvm_1.vmdk"
+scsi0:1.mode = "independent-persistent"
+scsi0:2.present = "true"
+scsi0:2.deviceType = "scsi-hardDisk"
+scsi0:2.fileName = "/vmfs/volumes/datastore/directory/testvm_2.vmdk"
+scsi0:2.mode = "independent-nonpersistent"
+ide0:0.present = "true"
+ide0:0.deviceType = "atapi-cdrom"
+ide0:0.fileName = "CD-ROM 1"
+floppy0.present = "false"
+floppy1.present = "false"
+ethernet0.present = "true"
+ethernet0.networkName = "VM Network"
+ethernet0.connectionType = "bridged"
+ethernet0.addressType = "generated"
+ethernet0.generatedAddress = "00:0C:29:90:F1:F0"
+ethernet0.generatedAddressOffset = "0"
+svga.vramSize = "4194304"
diff --git a/tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.xml b/tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.xml
new file mode 100644
index 0000000..7432ff5
--- /dev/null
+++ b/tests/xml2vmxdata/xml2vmx-esx-in-the-wild-7.xml
@@ -0,0 +1,51 @@
+<domain type='vmware'>
+  <name>testvm</name>
+  <uuid>564d273f-3975-42d5-827b-d5375090f1f0</uuid>
+  <memory>262144</memory>
+  <currentMemory>262144</currentMemory>
+  <vcpu>1</vcpu>
+  <cputune>
+    <shares>1000</shares>
+  </cputune>
+  <os>
+    <type arch='i686'>hvm</type>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <disk type='file' device='disk'>
+      <source file='[datastore] directory/testvm.vmdk'/>
+      <target dev='sda' bus='scsi'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='[datastore] directory/testvm_1.vmdk'/>
+      <target dev='sdb' bus='scsi'/>
+      <independent/>
+      <address type='drive' controller='0' bus='0' unit='1'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='[datastore] directory/testvm_2.vmdk'/>
+      <target dev='sdc' bus='scsi'/>
+      <independent/>
+      <nonpersistent/>
+      <address type='drive' controller='0' bus='0' unit='2'/>
+    </disk>
+    <disk type='block' device='cdrom'>
+      <source dev='CD-ROM 1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='lsilogic'/>
+    <controller type='ide' index='0'/>
+    <interface type='bridge'>
+      <mac address='00:0c:29:90:f1:f0'/>
+      <source bridge='VM Network'/>
+    </interface>
+    <video>
+      <model type='vmvga' vram='4096'/>
+    </video>
+  </devices>
+</domain>
diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c
index 439ddc8..70f28aa 100644
--- a/tests/xml2vmxtest.c
+++ b/tests/xml2vmxtest.c
@@ -274,6 +274,7 @@ mymain(void)
     DO_TEST("esx-in-the-wild-4", "esx-in-the-wild-4", 4);
     DO_TEST("esx-in-the-wild-5", "esx-in-the-wild-5", 4);
     DO_TEST("esx-in-the-wild-6", "esx-in-the-wild-6", 4);
+    DO_TEST("esx-in-the-wild-7", "esx-in-the-wild-7", 4);
 
     DO_TEST("gsx-in-the-wild-1", "gsx-in-the-wild-1", 4);
     DO_TEST("gsx-in-the-wild-2", "gsx-in-the-wild-2", 4);
-- 
1.7.4.1

