mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 14:45:24 +00:00
Add wide SCSI bus disk address generation support
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.
This commit is contained in:
parent
a73b389d12
commit
f8f29b1fc2
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -5022,7 +5022,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;
|
||||
@ -5195,7 +5196,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);
|
||||
@ -6007,7 +6008,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) {
|
||||
@ -6155,7 +6156,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);
|
||||
|
Loading…
Reference in New Issue
Block a user