[libvirt] [PATCH 3/3] Check boot order on device attach

Jiri Denemark jdenemar at redhat.com
Thu Mar 20 14:42:02 UTC 2014


https://bugzilla.redhat.com/show_bug.cgi?id=1007754

When attaching a new device, we need to check if its boot order
configuration is compatible with current domain definition.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---
 src/conf/domain_conf.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h |  1 +
 2 files changed, 80 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ecfec0d..05e9d3a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2565,6 +2565,53 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
     return 0;
 }
 
+virDomainDeviceInfoPtr
+virDomainDeviceGetInfo(virDomainDeviceDefPtr device)
+{
+    switch ((virDomainDeviceType) device->type) {
+    case VIR_DOMAIN_DEVICE_DISK:
+        return &device->data.disk->info;
+    case VIR_DOMAIN_DEVICE_FS:
+        return &device->data.fs->info;
+    case VIR_DOMAIN_DEVICE_NET:
+        return &device->data.net->info;
+    case VIR_DOMAIN_DEVICE_INPUT:
+        return &device->data.input->info;
+    case VIR_DOMAIN_DEVICE_SOUND:
+        return &device->data.sound->info;
+    case VIR_DOMAIN_DEVICE_VIDEO:
+        return &device->data.video->info;
+    case VIR_DOMAIN_DEVICE_HOSTDEV:
+        return device->data.hostdev->info;
+    case VIR_DOMAIN_DEVICE_WATCHDOG:
+        return &device->data.watchdog->info;
+    case VIR_DOMAIN_DEVICE_CONTROLLER:
+        return &device->data.controller->info;
+    case VIR_DOMAIN_DEVICE_HUB:
+        return &device->data.hub->info;
+    case VIR_DOMAIN_DEVICE_REDIRDEV:
+        return &device->data.redirdev->info;
+    case VIR_DOMAIN_DEVICE_SMARTCARD:
+        return &device->data.smartcard->info;
+    case VIR_DOMAIN_DEVICE_CHR:
+        return &device->data.chr->info;
+    case VIR_DOMAIN_DEVICE_MEMBALLOON:
+        return &device->data.memballoon->info;
+    case VIR_DOMAIN_DEVICE_NVRAM:
+        return &device->data.nvram->info;
+    case VIR_DOMAIN_DEVICE_RNG:
+        return &device->data.rng->info;
+
+    /* The following devices do not contain virDomainDeviceInfo */
+    case VIR_DOMAIN_DEVICE_LEASE:
+    case VIR_DOMAIN_DEVICE_GRAPHICS:
+    case VIR_DOMAIN_DEVICE_LAST:
+    case VIR_DOMAIN_DEVICE_NONE:
+        break;
+    }
+    return NULL;
+}
+
 static bool
 virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info, unsigned int flags)
 {
@@ -17823,11 +17870,30 @@ virDomainDeviceIsUSB(virDomainDeviceDefPtr dev)
     return false;
 }
 
+static int
+virDomainDeviceInfoCheckBootIndex(virDomainDefPtr def ATTRIBUTE_UNUSED,
+                                  virDomainDeviceDefPtr device ATTRIBUTE_UNUSED,
+                                  virDomainDeviceInfoPtr info,
+                                  void *opaque)
+{
+    virDomainDeviceInfoPtr newinfo = opaque;
+
+    if (info->bootIndex == newinfo->bootIndex) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("boot order %d is already used by another device"),
+                       newinfo->bootIndex);
+        return -1;
+    }
+    return 0;
+}
+
 int
 virDomainDefCompatibleDevice(virDomainDefPtr def,
                              virDomainDeviceDefPtr dev,
                              virDomainDeviceAction action)
 {
+    virDomainDeviceInfoPtr info = virDomainDeviceGetInfo(dev);
+
     if (action != VIR_DOMAIN_DEVICE_ACTION_ATTACH)
         return 0;
 
@@ -17840,6 +17906,19 @@ virDomainDefCompatibleDevice(virDomainDefPtr def,
         return -1;
     }
 
+    if (info && info->bootIndex > 0) {
+        if (def->os.nBootDevs > 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("per-device boot elements cannot be used"
+                             " together with os/boot elements"));
+            return -1;
+        }
+        if (virDomainDeviceInfoIterate(def,
+                                       virDomainDeviceInfoCheckBootIndex,
+                                       info) < 0)
+            return -1;
+    }
+
     return 0;
 }
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d5d5fd3..bf12414 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2291,6 +2291,7 @@ virDomainDeviceDefPtr virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
                                              virDomainXMLOptionPtr xmlopt);
 int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
                                   int type);
+virDomainDeviceInfoPtr virDomainDeviceGetInfo(virDomainDeviceDefPtr device);
 int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst,
                             virDomainDeviceInfoPtr src);
 void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info);
-- 
1.9.1




More information about the libvir-list mailing list