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'/>
* src/conf/domain_conf.h, src/conf/domain_conf.c: Parsing and
formatting of drive addresses
---
src/conf/domain_conf.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 13 +++++++
2 files changed, 100 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0e88362..9c0b8cf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -91,7 +91,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"none",
"pci",
- "usb");
+ "usb",
+ "drive");
VIR_ENUM_IMPL(virDomainDeviceAddressMode, VIR_DOMAIN_DEVICE_ADDRESS_MODE_LAST,
"dynamic",
@@ -750,6 +751,9 @@ int virDomainDeviceAddressIsValid(virDomainDeviceAddressPtr addr,
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB:
return virDomainDeviceUSBAddressIsValid(&addr->data.usb);
+
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
+ return virDomainDeviceDriveAddressIsValid(&addr->data.drive);
}
return 0;
@@ -767,6 +771,11 @@ int virDomainDeviceUSBAddressIsValid(virDomainDeviceUSBAddressPtr
addr)
return addr->bus || addr->dev;
}
+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 */
+}
void virDomainDeviceAddressClear(virDomainDeviceAddressPtr addr)
{
@@ -817,6 +826,13 @@ static int virDomainDeviceAddressFormat(virBufferPtr buf,
addr->data.usb.dev);
break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
+ virBufferVSprintf(buf, " controller='%d' bus='%d'
unit='%d'",
+ addr->data.drive.controller,
+ addr->data.drive.bus,
+ addr->data.drive.unit);
+ break;
+
default:
virDomainReportError(NULL, VIR_ERR_INTERNAL_ERROR,
_("unknown address type '%d'"),
addr->type);
@@ -846,6 +862,9 @@ int virDomainDeviceAddressEqual(virDomainDeviceAddressPtr a,
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB:
return virDomainDeviceUSBAddressEqual(&a->data.usb,
&b->data.usb);
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
+ return virDomainDeviceDriveAddressEqual(&a->data.drive,
+ &b->data.drive);
}
return 0;
@@ -876,6 +895,18 @@ int virDomainDeviceUSBAddressEqual(virDomainDeviceUSBAddressPtr 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,
@@ -977,6 +1008,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
*/
@@ -1036,6 +1117,11 @@ virDomainDeviceAddressParseXML(virConnectPtr conn,
goto cleanup;
break;
+ case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
+ if (virDomainDeviceDriveAddressParseXML(conn, node, &addr->data.drive)
< 0)
+ goto cleanup;
+ break;
+
default:
/* Should not happen */
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1ae63bd..d1c1b67 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -67,6 +67,7 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB,
+ VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
};
@@ -94,6 +95,14 @@ struct _virDomainDeviceUSBAddress {
unsigned int dev;
};
+typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress;
+typedef virDomainDeviceDriveAddress *virDomainDeviceDriveAddressPtr;
+struct _virDomainDeviceDriveAddress {
+ unsigned int controller;
+ unsigned int bus;
+ unsigned int unit;
+};
+
typedef struct _virDomainDeviceAddress virDomainDeviceAddress;
typedef virDomainDeviceAddress *virDomainDeviceAddressPtr;
struct _virDomainDeviceAddress {
@@ -102,6 +111,7 @@ struct _virDomainDeviceAddress {
union {
virDomainDevicePCIAddress pci;
virDomainDeviceUSBAddress usb;
+ virDomainDeviceDriveAddress drive;
} data;
};
@@ -705,10 +715,13 @@ int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a,
virDomainDevicePCIAddressPtr b);
int virDomainDeviceUSBAddressEqual(virDomainDeviceUSBAddressPtr a,
virDomainDeviceUSBAddressPtr b);
+int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a,
+ virDomainDeviceDriveAddressPtr b);
int virDomainDeviceAddressIsValid(virDomainDeviceAddressPtr addr,
int type);
int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr);
int virDomainDeviceUSBAddressIsValid(virDomainDeviceUSBAddressPtr addr);
+int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr);
void virDomainDeviceAddressClear(virDomainDeviceAddressPtr addr);
void virDomainDefFree(virDomainDefPtr vm);
void virDomainObjRef(virDomainObjPtr vm);
--
1.6.5.2