On 7/19/24 15:25, Adam Julis wrote:
Disk targets were generated in virVMXParseConfig() with
virVMXGenerateDiskTarget(). It works on combination of
controller, fix offset, unit and prefix. While SCSI and SATA have
same prefix "sd", function virVMXGenerateDiskTarget() could
returned in some cases same targets.
In this patch, after loaded SCSI and SATA disks to the def, it
checks if in array exists any SATA disks after SCSI. If not,
nothing happened. If yes, targets of all SATA disks are changed.
Disk target is calculated as: last SCSI target value + n, where n
is position of disk in array after last SCSI (1,2,..).
Because assigned addresses of disks are generated from their
indexes, for every changed SATA disk is called
virDomainDiskDefAssignAddress() with the updated value.
The corresponding tests have been modified to match the index
changes.
Signed-off-by: Adam Julis <ajulis(a)redhat.com>
---
src/vmx/vmx.c | 32 ++++++++++++++++++++++++
tests/vmx2xmldata/esx-in-the-wild-12.xml | 4 +--
tests/vmx2xmldata/esx-in-the-wild-8.xml | 4 +--
3 files changed, 36 insertions(+), 4 deletions(-)
It's nice to see this in action (i.e. test cases being fixed).
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 227744d062..9fdf0f1cd4 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1389,6 +1389,9 @@ virVMXParseConfig(virVMXContext *ctx,
bool smbios_reflecthost = false;
int controller;
int bus;
+ int ndisk;
+ int last_scsi;
+ int offset = -1;
int port;
bool present;
int scsi_virtualDev[4] = { -1, -1, -1, -1 };
@@ -1805,6 +1808,35 @@ virVMXParseConfig(virVMXContext *ctx,
}
}
+ /* now disks contain only SCSI and SATA, SATA could have same index (dst) as SCSI
+ * find last SCSI index in array and use it as offset for all SATA indexes
+ * (overwrite old values)
+ * finally, regenerate correct addresses, while it depends on the index */
+ for (ndisk = 0; ndisk < def->ndisks; ndisk++) {
+ virDomainDiskDef *dsc = def->disks[ndisk];
+
+ if (dsc->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ offset = virDiskNameToIndex(dsc->dst);
+ last_scsi = ndisk;
+ continue;
+ }
+
+ if (offset > -1) {
+ VIR_FREE(def->disks[ndisk]->dst);
+ def->disks[ndisk]->dst = virIndexToDiskName(offset + ndisk -
last_scsi, "sd");
+
+ if (virDomainDiskDefAssignAddress(NULL, def->disks[ndisk], def) < 0)
{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not assign address to disk
'%1$s'"),
+ virDomainDiskGetSource(dsc));
+ goto cleanup;
+ }
+ }
+
+ else
+ break;
+ }
I'm wondering whether we actually need this logic. At this point, we
know SCSI disks are at the beginning of def->disks array, followed by
SATA disks. I wonder we should just do plain:
for (i = 0; i < def->ndisks; i++) {
virDomainDiskDef *disk = def->disks[i];
VIR_FREE(disk->dst);
disk->dst = virIndexToDiskName(i, "sd");
if (virDomainDiskDefAssignAddress(NULL, disk, def) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not assign address to disk
'%1$s'"),
virDomainDiskGetSource(disk));
goto cleanup;
}
}
This has a downside of overwriting more targets. But then again, disk
target is just an unique identifier and we do not (can not) guarantee
the same naming inside guest.
Michal