The domain XML parsing code autogenerates disk address and controller elements when they are not explicitly specified. The code assumes a narrow SCSI bus (7 units per bus). ESX uses a wide SCSI bus (16 units per bus). This is a step towards controller support for the ESX driver. --- src/conf/capabilities.h | 3 +++ src/conf/domain_conf.c | 39 +++++++++++++++++++++++++++++---------- src/conf/domain_conf.h | 2 +- src/esx/esx_driver.c | 2 ++ src/qemu/qemu_conf.c | 9 +++++---- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index bdf44fa..9290c82 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -24,6 +24,8 @@ #ifndef __VIR_CAPABILITIES_H # define __VIR_CAPABILITIES_H +# include <stdbool.h> + # include "internal.h" # include "util.h" # include "buf.h" @@ -125,6 +127,7 @@ struct _virCaps { void (*privateDataFreeFunc)(void *); int (*privateDataXMLFormat)(virBufferPtr, void *); int (*privateDataXMLParse)(xmlXPathContextPtr, void *); + bool hasWideScsiBus; }; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 64b5cf3..cac4042 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1339,7 +1339,7 @@ virDomainParseLegacyDeviceAddress(char *devaddr, } int -virDomainDiskDefAssignAddress(virDomainDiskDefPtr def) +virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def) { int idx = virDiskNameToIndex(def->dst); if (idx < 0) @@ -1347,12 +1347,30 @@ virDomainDiskDefAssignAddress(virDomainDiskDefPtr def) switch (def->bus) { case VIR_DOMAIN_DISK_BUS_SCSI: - /* For SCSI we define the default mapping to be 7 units - * per bus, 1 bus per controller, many controllers */ def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; - def->info.addr.drive.controller = idx / 7; - def->info.addr.drive.bus = 0; - def->info.addr.drive.unit = idx % 7; + + if (caps->hasWideScsiBus) { + /* For a wide SCSI bus we define the default mapping to be + * 16 units per bus, 1 bus per controller, many controllers. + * Unit 7 is the SCSI controller itself. Therefore unit 7 + * cannot be assigned to disks and is skipped. + */ + def->info.addr.drive.controller = idx / 15; + def->info.addr.drive.bus = 0; + def->info.addr.drive.unit = idx % 15; + + /* Skip the SCSI controller at unit 7 */ + if (def->info.addr.drive.unit >= 7) { + ++def->info.addr.drive.unit; + } + } else { + /* For a narrow SCSI bus we define the default mapping to be + * 7 units per bus, 1 bus per controller, many controllers */ + def->info.addr.drive.controller = idx / 7; + def->info.addr.drive.bus = 0; + def->info.addr.drive.unit = idx % 7; + } + break; case VIR_DOMAIN_DISK_BUS_IDE: @@ -1385,7 +1403,8 @@ virDomainDiskDefAssignAddress(virDomainDiskDefPtr def) * @param node XML nodeset to parse for disk definition */ static virDomainDiskDefPtr -virDomainDiskDefParseXML(xmlNodePtr node, +virDomainDiskDefParseXML(virCapsPtr caps, + xmlNodePtr node, int flags) { virDomainDiskDefPtr def; xmlNodePtr cur; @@ -1615,7 +1634,7 @@ virDomainDiskDefParseXML(xmlNodePtr node, serial = NULL; if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE - && virDomainDiskDefAssignAddress(def) < 0) + && virDomainDiskDefAssignAddress(caps, def) < 0) goto error; cleanup: @@ -3687,7 +3706,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps, if (xmlStrEqual(node->name, BAD_CAST "disk")) { dev->type = VIR_DOMAIN_DEVICE_DISK; - if (!(dev->data.disk = virDomainDiskDefParseXML(node, flags))) + if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, flags))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) { dev->type = VIR_DOMAIN_DEVICE_FS; @@ -4237,7 +4256,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, if (n && VIR_ALLOC_N(def->disks, n) < 0) goto no_memory; for (i = 0 ; i < n ; i++) { - virDomainDiskDefPtr disk = virDomainDiskDefParseXML(nodes[i], + virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, nodes[i], flags); if (!disk) goto error; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f83de83..701849f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -999,7 +999,7 @@ int virDomainDiskInsert(virDomainDefPtr def, virDomainDiskDefPtr disk); void virDomainDiskInsertPreAlloced(virDomainDefPtr def, virDomainDiskDefPtr disk); -int virDomainDiskDefAssignAddress(virDomainDiskDefPtr def); +int virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def); int virDomainControllerInsert(virDomainDefPtr def, virDomainControllerDefPtr controller); diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 1968537..f50e090 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -228,6 +228,8 @@ esxCapsInit(esxPrivate *priv) virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 }); virCapabilitiesAddHostMigrateTransport(caps, "esx"); + caps->hasWideScsiBus = true; + if (esxLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0) { goto failure; } diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index f096876..1b18a5f 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -5019,7 +5019,8 @@ error: * Will fail if not using the 'index' keyword */ static virDomainDiskDefPtr -qemuParseCommandLineDisk(const char *val, +qemuParseCommandLineDisk(virCapsPtr caps, + const char *val, int nvirtiodisk) { virDomainDiskDefPtr def = NULL; @@ -5192,7 +5193,7 @@ qemuParseCommandLineDisk(const char *val, else def->dst[2] = 'a' + idx; - if (virDomainDiskDefAssignAddress(def) < 0) { + if (virDomainDiskDefAssignAddress(caps, def) < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("invalid device name '%s'"), def->dst); virDomainDiskDefFree(def); @@ -6004,7 +6005,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, goto no_memory; } - if (virDomainDiskDefAssignAddress(disk) < 0) + if (virDomainDiskDefAssignAddress(caps, disk) < 0) goto error; if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) { @@ -6152,7 +6153,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps, } else if (STREQ(arg, "-drive")) { virDomainDiskDefPtr disk; WANT_VALUE(); - if (!(disk = qemuParseCommandLineDisk(val, nvirtiodisk))) + if (!(disk = qemuParseCommandLineDisk(caps, val, nvirtiodisk))) goto error; if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) { virDomainDiskDefFree(disk); -- 1.7.0.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list