On Thu, Jun 17, 2010 at 11:15:42PM +0200, Matthias Bolte wrote: > 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); That looks fine to me, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list