mirror of https://gitee.com/openkylin/libvirt.git
Extend the virDomainDeviceAddress struture to allow disk controller addresses
Introduce a new structure struct _virDomainDeviceDriveAddress { unsigned int controller; unsigned int bus; unsigned int unit; }; and plug that into virDomainDeviceAddress and generates XML that looks like <address type='drive' controller='1' bus='0' unit='5'/> This syntax will be used by the QEMU driver to explicitly control how drives are attached to the bus * src/conf/domain_conf.h, src/conf/domain_conf.c: Parsing and formatting of drive addresses * docs/schemas/domain.rng: Define new address format for drives
This commit is contained in:
parent
1b0cce7d3a
commit
d812e7aeb8
|
@ -1189,6 +1189,21 @@
|
|||
<ref name="pciFunc"/>
|
||||
</attribute>
|
||||
</define>
|
||||
<define name="driveaddress">
|
||||
<optional>
|
||||
<attribute name="controller">
|
||||
<ref name="driveController"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="bus">
|
||||
<ref name="driveBus"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<attribute name="unit">
|
||||
<ref name="driveUnit"/>
|
||||
</attribute>
|
||||
</define>
|
||||
<!--
|
||||
Devices attached to a domain.
|
||||
-->
|
||||
|
@ -1305,6 +1320,12 @@
|
|||
</attribute>
|
||||
<ref name="pciaddress"/>
|
||||
</group>
|
||||
<group>
|
||||
<attribute name="type">
|
||||
<value>drive</value>
|
||||
</attribute>
|
||||
<ref name="driveaddress"/>
|
||||
</group>
|
||||
</choice>
|
||||
</element>
|
||||
</define>
|
||||
|
@ -1434,6 +1455,21 @@
|
|||
<param name="pattern">(0x)?[0-7]</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name="driveController">
|
||||
<data type="string">
|
||||
<param name="pattern">[0-9]{1,2}</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name="driveBus">
|
||||
<data type="string">
|
||||
<param name="pattern">[0-9]{1,2}</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name="driveUnit">
|
||||
<data type="string">
|
||||
<param name="pattern">[0-9]{1,2}</param>
|
||||
</data>
|
||||
</define>
|
||||
<define name="featureName">
|
||||
<data type="string">
|
||||
<param name='pattern'>[a-zA-Z0-9\-_]+</param>
|
||||
|
|
|
@ -90,7 +90,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
|
|||
|
||||
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
|
||||
"none",
|
||||
"pci")
|
||||
"pci",
|
||||
"drive");
|
||||
|
||||
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
||||
"block",
|
||||
|
@ -748,6 +749,9 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
|
|||
switch (info->type) {
|
||||
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
|
||||
return virDomainDevicePCIAddressIsValid(&info->addr.pci);
|
||||
|
||||
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
|
||||
return virDomainDeviceDriveAddressIsValid(&info->addr.drive);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -760,6 +764,13 @@ int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr)
|
|||
}
|
||||
|
||||
|
||||
int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/*return addr->controller || addr->bus || addr->unit;*/
|
||||
return 1; /* 0 is valid for all fields, so any successfully parsed addr is valid */
|
||||
}
|
||||
|
||||
|
||||
int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info)
|
||||
{
|
||||
if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
|
||||
|
@ -803,6 +814,13 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf,
|
|||
info->addr.pci.function);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
|
||||
virBufferVSprintf(buf, " controller='%d' bus='%d' unit='%d'",
|
||||
info->addr.drive.controller,
|
||||
info->addr.drive.bus,
|
||||
info->addr.drive.unit);
|
||||
break;
|
||||
|
||||
default:
|
||||
virDomainReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("unknown address type '%d'"), info->type);
|
||||
|
@ -828,6 +846,18 @@ int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a,
|
|||
}
|
||||
|
||||
|
||||
int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a,
|
||||
virDomainDeviceDriveAddressPtr b)
|
||||
{
|
||||
if (a->controller == b->controller &&
|
||||
a->bus == b->bus &&
|
||||
a->unit == b->unit)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDevicePCIAddressParseXML(virConnectPtr conn,
|
||||
xmlNodePtr node,
|
||||
|
@ -888,6 +918,56 @@ cleanup:
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDeviceDriveAddressParseXML(virConnectPtr conn,
|
||||
xmlNodePtr node,
|
||||
virDomainDeviceDriveAddressPtr addr)
|
||||
{
|
||||
char *bus, *unit, *controller;
|
||||
int ret = -1;
|
||||
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
|
||||
controller = virXMLPropString(node, "controller");
|
||||
bus = virXMLPropString(node, "bus");
|
||||
unit = virXMLPropString(node, "unit");
|
||||
|
||||
if (controller &&
|
||||
virStrToLong_ui(controller, NULL, 10, &addr->controller) < 0) {
|
||||
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot parse <address> 'controller' attribute"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (bus &&
|
||||
virStrToLong_ui(bus, NULL, 10, &addr->bus) < 0) {
|
||||
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot parse <address> 'bus' attribute"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (unit &&
|
||||
virStrToLong_ui(unit, NULL, 10, &addr->unit) < 0) {
|
||||
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot parse <address> 'unit' attribute"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!virDomainDeviceDriveAddressIsValid(addr)) {
|
||||
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Insufficient specification for drive address"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(controller);
|
||||
VIR_FREE(bus);
|
||||
VIR_FREE(unit);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse the XML definition for a device address
|
||||
* @param node XML nodeset to parse for device address definition
|
||||
*/
|
||||
|
@ -938,6 +1018,11 @@ virDomainDeviceInfoParseXML(virConnectPtr conn,
|
|||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
|
||||
if (virDomainDeviceDriveAddressParseXML(conn, node, &info->addr.drive) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Should not happen */
|
||||
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
|
|
|
@ -67,6 +67,7 @@ enum virDomainVirtType {
|
|||
enum virDomainDeviceAddressType {
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE,
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
|
||||
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
|
||||
};
|
||||
|
@ -80,12 +81,21 @@ struct _virDomainDevicePCIAddress {
|
|||
unsigned int function;
|
||||
};
|
||||
|
||||
typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress;
|
||||
typedef virDomainDeviceDriveAddress *virDomainDeviceDriveAddressPtr;
|
||||
struct _virDomainDeviceDriveAddress {
|
||||
unsigned int controller;
|
||||
unsigned int bus;
|
||||
unsigned int unit;
|
||||
};
|
||||
|
||||
typedef struct _virDomainDeviceInfo virDomainDeviceInfo;
|
||||
typedef virDomainDeviceInfo *virDomainDeviceInfoPtr;
|
||||
struct _virDomainDeviceInfo {
|
||||
int type;
|
||||
union {
|
||||
virDomainDevicePCIAddress pci;
|
||||
virDomainDeviceDriveAddress drive;
|
||||
} addr;
|
||||
};
|
||||
|
||||
|
@ -690,9 +700,12 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def);
|
|||
void virDomainDeviceDefFree(virDomainDeviceDefPtr def);
|
||||
int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a,
|
||||
virDomainDevicePCIAddressPtr b);
|
||||
int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a,
|
||||
virDomainDeviceDriveAddressPtr b);
|
||||
int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
|
||||
int type);
|
||||
int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr);
|
||||
int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr);
|
||||
int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info);
|
||||
void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info);
|
||||
void virDomainDefFree(virDomainDefPtr vm);
|
||||
|
|
Loading…
Reference in New Issue