mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 15:15:25 +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
|
#ifndef __VIR_CAPABILITIES_H
|
||||||
# define __VIR_CAPABILITIES_H
|
# define __VIR_CAPABILITIES_H
|
||||||
|
|
||||||
|
# include <stdbool.h>
|
||||||
|
|
||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
# include "util.h"
|
# include "util.h"
|
||||||
# include "buf.h"
|
# include "buf.h"
|
||||||
@ -125,6 +127,7 @@ struct _virCaps {
|
|||||||
void (*privateDataFreeFunc)(void *);
|
void (*privateDataFreeFunc)(void *);
|
||||||
int (*privateDataXMLFormat)(virBufferPtr, void *);
|
int (*privateDataXMLFormat)(virBufferPtr, void *);
|
||||||
int (*privateDataXMLParse)(xmlXPathContextPtr, void *);
|
int (*privateDataXMLParse)(xmlXPathContextPtr, void *);
|
||||||
|
bool hasWideScsiBus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1339,7 +1339,7 @@ virDomainParseLegacyDeviceAddress(char *devaddr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
virDomainDiskDefAssignAddress(virDomainDiskDefPtr def)
|
virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
|
||||||
{
|
{
|
||||||
int idx = virDiskNameToIndex(def->dst);
|
int idx = virDiskNameToIndex(def->dst);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
@ -1347,12 +1347,30 @@ virDomainDiskDefAssignAddress(virDomainDiskDefPtr def)
|
|||||||
|
|
||||||
switch (def->bus) {
|
switch (def->bus) {
|
||||||
case VIR_DOMAIN_DISK_BUS_SCSI:
|
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.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
|
||||||
|
|
||||||
|
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.controller = idx / 7;
|
||||||
def->info.addr.drive.bus = 0;
|
def->info.addr.drive.bus = 0;
|
||||||
def->info.addr.drive.unit = idx % 7;
|
def->info.addr.drive.unit = idx % 7;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DISK_BUS_IDE:
|
case VIR_DOMAIN_DISK_BUS_IDE:
|
||||||
@ -1385,7 +1403,8 @@ virDomainDiskDefAssignAddress(virDomainDiskDefPtr def)
|
|||||||
* @param node XML nodeset to parse for disk definition
|
* @param node XML nodeset to parse for disk definition
|
||||||
*/
|
*/
|
||||||
static virDomainDiskDefPtr
|
static virDomainDiskDefPtr
|
||||||
virDomainDiskDefParseXML(xmlNodePtr node,
|
virDomainDiskDefParseXML(virCapsPtr caps,
|
||||||
|
xmlNodePtr node,
|
||||||
int flags) {
|
int flags) {
|
||||||
virDomainDiskDefPtr def;
|
virDomainDiskDefPtr def;
|
||||||
xmlNodePtr cur;
|
xmlNodePtr cur;
|
||||||
@ -1615,7 +1634,7 @@ virDomainDiskDefParseXML(xmlNodePtr node,
|
|||||||
serial = NULL;
|
serial = NULL;
|
||||||
|
|
||||||
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
|
if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE
|
||||||
&& virDomainDiskDefAssignAddress(def) < 0)
|
&& virDomainDiskDefAssignAddress(caps, def) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@ -3687,7 +3706,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
|
|||||||
|
|
||||||
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
|
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
|
||||||
dev->type = VIR_DOMAIN_DEVICE_DISK;
|
dev->type = VIR_DOMAIN_DEVICE_DISK;
|
||||||
if (!(dev->data.disk = virDomainDiskDefParseXML(node, flags)))
|
if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node, flags)))
|
||||||
goto error;
|
goto error;
|
||||||
} else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) {
|
} else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) {
|
||||||
dev->type = VIR_DOMAIN_DEVICE_FS;
|
dev->type = VIR_DOMAIN_DEVICE_FS;
|
||||||
@ -4237,7 +4256,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
|||||||
if (n && VIR_ALLOC_N(def->disks, n) < 0)
|
if (n && VIR_ALLOC_N(def->disks, n) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
for (i = 0 ; i < n ; i++) {
|
for (i = 0 ; i < n ; i++) {
|
||||||
virDomainDiskDefPtr disk = virDomainDiskDefParseXML(nodes[i],
|
virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, nodes[i],
|
||||||
flags);
|
flags);
|
||||||
if (!disk)
|
if (!disk)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -999,7 +999,7 @@ int virDomainDiskInsert(virDomainDefPtr def,
|
|||||||
virDomainDiskDefPtr disk);
|
virDomainDiskDefPtr disk);
|
||||||
void virDomainDiskInsertPreAlloced(virDomainDefPtr def,
|
void virDomainDiskInsertPreAlloced(virDomainDefPtr def,
|
||||||
virDomainDiskDefPtr disk);
|
virDomainDiskDefPtr disk);
|
||||||
int virDomainDiskDefAssignAddress(virDomainDiskDefPtr def);
|
int virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def);
|
||||||
|
|
||||||
int virDomainControllerInsert(virDomainDefPtr def,
|
int virDomainControllerInsert(virDomainDefPtr def,
|
||||||
virDomainControllerDefPtr controller);
|
virDomainControllerDefPtr controller);
|
||||||
|
@ -228,6 +228,8 @@ esxCapsInit(esxPrivate *priv)
|
|||||||
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 });
|
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 });
|
||||||
virCapabilitiesAddHostMigrateTransport(caps, "esx");
|
virCapabilitiesAddHostMigrateTransport(caps, "esx");
|
||||||
|
|
||||||
|
caps->hasWideScsiBus = true;
|
||||||
|
|
||||||
if (esxLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0) {
|
if (esxLookupHostSystemBiosUuid(priv, caps->host.host_uuid) < 0) {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -5022,7 +5022,8 @@ error:
|
|||||||
* Will fail if not using the 'index' keyword
|
* Will fail if not using the 'index' keyword
|
||||||
*/
|
*/
|
||||||
static virDomainDiskDefPtr
|
static virDomainDiskDefPtr
|
||||||
qemuParseCommandLineDisk(const char *val,
|
qemuParseCommandLineDisk(virCapsPtr caps,
|
||||||
|
const char *val,
|
||||||
int nvirtiodisk)
|
int nvirtiodisk)
|
||||||
{
|
{
|
||||||
virDomainDiskDefPtr def = NULL;
|
virDomainDiskDefPtr def = NULL;
|
||||||
@ -5195,7 +5196,7 @@ qemuParseCommandLineDisk(const char *val,
|
|||||||
else
|
else
|
||||||
def->dst[2] = 'a' + idx;
|
def->dst[2] = 'a' + idx;
|
||||||
|
|
||||||
if (virDomainDiskDefAssignAddress(def) < 0) {
|
if (virDomainDiskDefAssignAddress(caps, def) < 0) {
|
||||||
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
qemuReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("invalid device name '%s'"), def->dst);
|
_("invalid device name '%s'"), def->dst);
|
||||||
virDomainDiskDefFree(def);
|
virDomainDiskDefFree(def);
|
||||||
@ -6007,7 +6008,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virDomainDiskDefAssignAddress(disk) < 0)
|
if (virDomainDiskDefAssignAddress(caps, disk) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
|
||||||
@ -6155,7 +6156,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
|||||||
} else if (STREQ(arg, "-drive")) {
|
} else if (STREQ(arg, "-drive")) {
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
WANT_VALUE();
|
WANT_VALUE();
|
||||||
if (!(disk = qemuParseCommandLineDisk(val, nvirtiodisk)))
|
if (!(disk = qemuParseCommandLineDisk(caps, val, nvirtiodisk)))
|
||||||
goto error;
|
goto error;
|
||||||
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
|
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
|
||||||
virDomainDiskDefFree(disk);
|
virDomainDiskDefFree(disk);
|
||||||
|
Loading…
Reference in New Issue
Block a user