[libvirt PATCH 4/4] vmx: start parsing SATA disks

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

 



Always reverse-engineering VMX files, attempt to support SATA disks in
guests, and their controllers.

The esx-in-the-wild-10 test case is taken from RHBZ#1883588, while the
result of esx-in-the-wild-8 is updated with SATA disks.

Fixes (hopefully):
https://bugzilla.redhat.com/show_bug.cgi?id=1677608
https://bugzilla.redhat.com/show_bug.cgi?id=1883588

Signed-off-by: Pino Toscano <ptoscano@xxxxxxxxxx>
---
 src/vmx/vmx.c                                 | 138 ++++++++++++++++++
 .../vmx2xml-esx-in-the-wild-10.vmx            | 101 +++++++++++++
 .../vmx2xml-esx-in-the-wild-10.xml            |  36 +++++
 .../vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml |   6 +
 tests/vmx2xmltest.c                           |   1 +
 5 files changed, 282 insertions(+)
 create mode 100644 tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.vmx
 create mode 100644 tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.xml

diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 6e4b455794..51d88de750 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -90,6 +90,7 @@ def->os
 ## disks #######################################################################
 
                                         scsi[0..3]:[0..6,8..15] -> <controller>:<unit> with 1 bus per controller
+                                        sata[0..3]:[0..29] -> <controller>:<unit> with 1 bus per controller
                                         ide[0..1]:[0..1]        -> <bus>:<unit> with 1 controller
                                         floppy[0..1]            -> <unit> with 1 controller and 1 bus per controller
 
@@ -120,6 +121,26 @@ def->disks[0]...
 ->slotnum
 
 
+## disks: sata hard drive from .vmdk image #####################################
+
+                                        sata0.present = "true"                  # defaults to "false"
+                                        sata0:0.present = "true"                # defaults to "false"
+                                        sata0:0.startConnected = "true"         # defaults to "true"
+
+...
+->type = _DISK_TYPE_FILE          <=>   sata0:0.deviceType = "???"              # defaults to ?
+->device = _DISK_DEVICE_DISK      <=>   sata0:0.deviceType = "???"              # defaults to ?
+->bus = _DISK_BUS_SATA
+->src = <value>.vmdk              <=>   sata0:0.fileName = "<value>.vmdk"
+->dst = sd[<controller> * 30 + <unit> mapped to [a-z]+]
+->driverName = <driver>           <=>   sata0.virtualDev = "<driver>"           # default depends on guestOS value
+->driverType
+->cachemode                       <=>   sata0:0.writeThrough = "<value>"        # defaults to false, true -> _DISK_CACHE_WRITETHRU, false _DISK_CACHE_DEFAULT
+->readonly
+->shared
+->slotnum
+
+
 ## disks: ide hard drive from .vmdk image ######################################
 
                                         ide0:0.present = "true"                 # defaults to "false"
@@ -164,6 +185,26 @@ def->disks[0]...
 ->slotnum
 
 
+## disks: sata cdrom from .iso image ###########################################
+
+                                        sata0.present = "true"                  # defaults to "false"
+                                        sata0:0.present = "true"                # defaults to "false"
+                                        sata0:0.startConnected = "true"         # defaults to "true"
+
+...
+->type = _DISK_TYPE_FILE          <=>   sata0:0.deviceType = "cdrom-image"      # defaults to ?
+->device = _DISK_DEVICE_CDROM     <=>   sata0:0.deviceType = "cdrom-image"      # defaults to ?
+->bus = _DISK_BUS_SATA
+->src = <value>.iso               <=>   sata0:0.fileName = "<value>.iso"
+->dst = sd[<controller> * 30 + <unit> mapped to [a-z]+]
+->driverName = <driver>           <=>   sata0.virtualDev = "<driver>"           # default depends on guestOS value
+->driverType
+->cachemode
+->readonly
+->shared
+->slotnum
+
+
 ## disks: ide cdrom from .iso image ############################################
 
                                         ide0:0.present = "true"                 # defaults to "false"
@@ -524,6 +565,7 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI,
 static int virVMXParseVNC(virConfPtr conf, virDomainGraphicsDefPtr *def);
 static int virVMXParseSCSIController(virConfPtr conf, int controller, bool *present,
                                      int *virtualDev);
+static int virVMXParseSATAController(virConfPtr conf, int controller, bool *present);
 static int virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt,
                            virConfPtr conf, int device, int busType,
                            int controllerOrBus, int unit, virDomainDiskDefPtr *def,
@@ -1335,6 +1377,7 @@ virVMXParseConfig(virVMXContext *ctx,
     long long coresPerSocket = 0;
     virCPUDefPtr cpu = NULL;
     char *firmware = NULL;
+    size_t saved_ndisks = 0;
 
     if (ctx->parseFileName == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1700,6 +1743,51 @@ virVMXParseConfig(virVMXContext *ctx,
                                            controller, scsi_virtualDev[controller]))
                 goto cleanup;
         }
+        saved_ndisks = def->ndisks;
+    }
+
+    /* def:disks (sata) */
+    for (controller = 0; controller < 4; ++controller) {
+        if (virVMXParseSATAController(conf, controller, &present) < 0) {
+            goto cleanup;
+        }
+
+        if (! present)
+            continue;
+
+        for (unit = 0; unit < 30; ++unit) {
+            if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
+                                VIR_DOMAIN_DISK_BUS_SATA, controller, unit,
+                                &def->disks[def->ndisks], def) < 0) {
+                goto cleanup;
+            }
+
+            if (def->disks[def->ndisks] != NULL) {
+                ++def->ndisks;
+                continue;
+            }
+
+            if (virVMXParseDisk(ctx, xmlopt, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
+                                 VIR_DOMAIN_DISK_BUS_SATA, controller, unit,
+                                 &def->disks[def->ndisks], def) < 0) {
+                goto cleanup;
+            }
+
+            if (def->disks[def->ndisks] != NULL)
+                ++def->ndisks;
+        }
+
+    }
+
+    /* add all the SATA controllers we've seen, up until the last one that is
+     * currently used by a disk */
+    if (def->ndisks - saved_ndisks != 0) {
+        virDomainDeviceInfoPtr info = &def->disks[def->ndisks - 1]->info;
+        for (controller = 0; controller <= info->addr.drive.controller; controller++) {
+            if (!virDomainDefAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_SATA,
+                                           controller, -1))
+                goto cleanup;
+        }
     }
 
     /* def:disks (ide) */
@@ -2015,6 +2103,28 @@ virVMXParseSCSIController(virConfPtr conf, int controller, bool *present,
 
 
 
+static int
+virVMXParseSATAController(virConfPtr conf, int controller, bool *present)
+{
+    char present_name[32];
+
+    if (controller < 0 || controller > 3) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("SATA controller index %d out of [0..3] range"),
+                       controller);
+        return -1;
+    }
+
+    g_snprintf(present_name, sizeof(present_name), "sata%d.present", controller);
+
+    if (virVMXGetConfigBoolean(conf, present_name, present, false, true) < 0)
+        return -1;
+
+    return 0;
+}
+
+
+
 static int
 virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr conf,
                 int device, int busType, int controllerOrBus, int unit,
@@ -2031,6 +2141,13 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
      *          device = {VIR_DOMAIN_DISK_DEVICE_DISK,
      *                    VIR_DOMAIN_DISK_DEVICE_CDROM,
      *                    VIR_DOMAIN_DISK_DEVICE_LUN}
+     *         busType = VIR_DOMAIN_DISK_BUS_SATA
+     * controllerOrBus = [0..3] -> controller
+     *            unit = [0..29]
+     *
+     *          device = {VIR_DOMAIN_DISK_DEVICE_DISK,
+     *                    VIR_DOMAIN_DISK_DEVICE_CDROM,
+     *                    VIR_DOMAIN_DISK_DEVICE_LUN}
      *         busType = VIR_DOMAIN_DISK_BUS_IDE
      * controllerOrBus = [0..1] -> bus
      *            unit = [0..1]
@@ -2103,6 +2220,27 @@ virVMXParseDisk(virVMXContext *ctx, virDomainXMLOptionPtr xmlopt, virConfPtr con
                virIndexToDiskName
                  (controllerOrBus * 15 + (unit < 7 ? unit : unit - 1), "sd");
 
+            if ((*def)->dst == NULL)
+                goto cleanup;
+        } else if (busType == VIR_DOMAIN_DISK_BUS_SATA) {
+            if (controllerOrBus < 0 || controllerOrBus > 3) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("SATA controller index %d out of [0..3] range"),
+                               controllerOrBus);
+                goto cleanup;
+            }
+
+            if (unit < 0 || unit >= 30) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("SATA unit index %d out of [0..29] range"),
+                               unit);
+                goto cleanup;
+            }
+
+            prefix = g_strdup_printf("sata%d:%d", controllerOrBus, unit);
+
+            (*def)->dst = virIndexToDiskName(controllerOrBus * 30 + unit, "sd");
+
             if ((*def)->dst == NULL)
                 goto cleanup;
         } else if (busType == VIR_DOMAIN_DISK_BUS_IDE) {
diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.vmx b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.vmx
new file mode 100644
index 0000000000..c8a0ef022a
--- /dev/null
+++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.vmx
@@ -0,0 +1,101 @@
+.encoding = "UTF-8"
+config.version = "8"
+virtualHW.version = "17"
+nvram = "windows2019biosvmware.nvram"
+pciBridge0.present = "TRUE"
+svga.present = "TRUE"
+pciBridge4.present = "TRUE"
+pciBridge4.virtualDev = "pcieRootPort"
+pciBridge4.functions = "8"
+pciBridge5.present = "TRUE"
+pciBridge5.virtualDev = "pcieRootPort"
+pciBridge5.functions = "8"
+pciBridge6.present = "TRUE"
+pciBridge6.virtualDev = "pcieRootPort"
+pciBridge6.functions = "8"
+pciBridge7.present = "TRUE"
+pciBridge7.virtualDev = "pcieRootPort"
+pciBridge7.functions = "8"
+vmci0.present = "TRUE"
+hpet0.present = "TRUE"
+floppy0.present = "FALSE"
+svga.vramSize = "8388608"
+numvcpus = "2"
+cpuid.coresPerSocket = "2"
+memSize = "4096"
+powerType.powerOff = "default"
+powerType.suspend = "default"
+powerType.reset = "default"
+tools.upgrade.policy = "manual"
+sched.cpu.units = "mhz"
+sched.cpu.affinity = "all"
+sched.cpu.latencySensitivity = "normal"
+vm.createDate = "1600358272642584"
+sata0.present = "TRUE"
+ethernet0.virtualDev = "e1000e"
+ethernet0.networkName = "VM Network"
+ethernet0.addressType = "vpx"
+ethernet0.generatedAddress = "00:50:56:9a:9c:7a"
+ethernet0.present = "TRUE"
+displayName = "w2019biosvmware"
+guestOS = "windows2019srv-64"
+disk.EnableUUID = "TRUE"
+toolScripts.afterPowerOn = "TRUE"
+toolScripts.afterResume = "TRUE"
+toolScripts.beforeSuspend = "TRUE"
+toolScripts.beforePowerOff = "TRUE"
+uuid.bios = "42 1a 61 77 5a a9 ab b7-59 24 fc 37 6c 18 a1 b4"
+vc.uuid = "50 1a f9 f2 6d 29 1c 76-19 a9 b2 08 ed e5 f3 74"
+migrate.hostLog = "windows2019biosvmware-25cb1ed1.hlog"
+sched.cpu.min = "0"
+sched.cpu.shares = "normal"
+sched.mem.min = "0"
+sched.mem.minSize = "0"
+sched.mem.shares = "normal"
+migrate.encryptionMode = "opportunistic"
+viv.moid = "c95f9b69-0aea-44dd-9941-696b625c8fbb:vm-22:EF/prDXvzAhPJtd46UQDN3DGPNWZzzePsgdPTSxifyo="
+numa.autosize.cookie = "20022"
+numa.autosize.vcpu.maxPerVirtualNode = "2"
+sched.swap.derivedName = "windows2019biosvmware-79c21733.vswp"
+uuid.location = "56 4d ff 27 a3 20 99 44-4a 7f b5 40 3a 8a a2 5f"
+vm.genid = "1424963296993694319"
+vm.genidX = "-5704120239402535687"
+pciBridge0.pciSlotNumber = "17"
+pciBridge4.pciSlotNumber = "21"
+pciBridge5.pciSlotNumber = "22"
+pciBridge6.pciSlotNumber = "23"
+pciBridge7.pciSlotNumber = "24"
+ethernet0.pciSlotNumber = "192"
+usb_xhci.pciSlotNumber = "-1"
+vmci0.pciSlotNumber = "32"
+sata0.pciSlotNumber = "33"
+vmotion.checkpointFBSize = "8388608"
+vmotion.checkpointSVGAPrimarySize = "8388608"
+vmotion.svga.mobMaxSize = "8388608"
+vmotion.svga.graphicsMemoryKB = "8192"
+vmci0.id = "1813553588"
+monitor.phys_bits_used = "45"
+cleanShutdown = "TRUE"
+softPowerOff = "TRUE"
+usb_xhci:4.present = "TRUE"
+usb_xhci:4.deviceType = "hid"
+usb_xhci:4.port = "4"
+usb_xhci:4.parent = "-1"
+toolsInstallManager.lastInstallError = "0"
+tools.remindInstall = "FALSE"
+toolsInstallManager.updateCounter = "3"
+extendedConfigFile = "windows2019biosvmware.vmxf"
+disable_acceleration = "TRUE"
+sata0:0.fileName = "windows2019biosvmware.vmdk"
+sata0:0.present = "TRUE"
+sata0:0.redo = ""
+sched.sata0:0.shares = "normal"
+sched.sata0:0.throughputCap = "off"
+sata0:1.startConnected = "FALSE"
+sata0:1.deviceType = "cdrom-raw"
+sata0:1.clientDevice = "TRUE"
+sata0:1.fileName = "emptyBackingString"
+sata0:1.present = "TRUE"
+svga.guestBackedPrimaryAware = "TRUE"
+tools.syncTime = "FALSE"
+guestOS.detailed.data = ""
diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.xml
new file mode 100644
index 0000000000..b8c522af1f
--- /dev/null
+++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-10.xml
@@ -0,0 +1,36 @@
+<domain type='vmware'>
+  <name>w2019biosvmware</name>
+  <uuid>421a6177-5aa9-abb7-5924-fc376c18a1b4</uuid>
+  <memory unit='KiB'>4194304</memory>
+  <currentMemory unit='KiB'>4194304</currentMemory>
+  <vcpu placement='static'>2</vcpu>
+  <cputune>
+    <shares>2000</shares>
+  </cputune>
+  <os>
+    <type arch='x86_64'>hvm</type>
+  </os>
+  <cpu>
+    <topology sockets='1' dies='1' cores='2' threads='1'/>
+  </cpu>
+  <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/windows2019biosvmware.vmdk'/>
+      <target dev='sda' bus='sata'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='sata' index='0'/>
+    <interface type='bridge'>
+      <mac address='00:50:56:9a:9c:7a' type='generated'/>
+      <source bridge='VM Network'/>
+      <model type='e1000e'/>
+    </interface>
+    <video>
+      <model type='vmvga' vram='8192' primary='yes'/>
+    </video>
+  </devices>
+</domain>
diff --git a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml
index 8276457bb3..32affb5935 100644
--- a/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml
+++ b/tests/vmx2xmldata/vmx2xml-esx-in-the-wild-8.xml
@@ -34,7 +34,13 @@
       <target dev='sdc' bus='scsi'/>
       <address type='drive' controller='0' bus='0' target='0' unit='2'/>
     </disk>
+    <disk type='file' device='cdrom'>
+      <source file='[692eb778-2d4937fe] CentOS-4.7.ServerCD-x86_64.iso'/>
+      <target dev='sda' bus='sata'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
     <controller type='scsi' index='0' model='vmpvscsi'/>
+    <controller type='sata' index='0'/>
     <interface type='bridge'>
       <mac address='00:1a:4a:16:01:55' type='static'/>
       <source bridge='VM Network'/>
diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c
index 1966aed6fe..376116bb75 100644
--- a/tests/vmx2xmltest.c
+++ b/tests/vmx2xmltest.c
@@ -262,6 +262,7 @@ mymain(void)
     DO_TEST("esx-in-the-wild-7", "esx-in-the-wild-7");
     DO_TEST("esx-in-the-wild-8", "esx-in-the-wild-8");
     DO_TEST("esx-in-the-wild-9", "esx-in-the-wild-9");
+    DO_TEST("esx-in-the-wild-10", "esx-in-the-wild-10");
 
     DO_TEST("gsx-in-the-wild-1", "gsx-in-the-wild-1");
     DO_TEST("gsx-in-the-wild-2", "gsx-in-the-wild-2");
-- 
2.26.2




[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]

  Powered by Linux