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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list