[libvirt] [PATCH 03/12] Extend the virDomainDeviceAddress struture to allow disk controller addresses

Daniel P. Berrange berrange at redhat.com
Thu Dec 10 22:22:23 UTC 2009


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




More information about the libvir-list mailing list