[libvirt] [PATCH v2 1/6] test_driver: implement virDomainAttachDeviceFlags

Ilias Stamatis stamatis.iliass at gmail.com
Wed Aug 14 16:47:05 UTC 2019


Signed-off-by: Ilias Stamatis <stamatis.iliass at gmail.com>
---
 src/test/test_driver.c | 290 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 290 insertions(+)

diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index c39eef2d4b..5f28e9017f 100755
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -4646,6 +4646,295 @@ testDomainFSTrim(virDomainPtr dom,
 }


+static int
+testDomainAttachDeviceLiveAndConfig(virDomainDefPtr vmdef,
+                                    virDomainDeviceDefPtr dev)
+{
+    virDomainDiskDefPtr disk;
+    virDomainNetDefPtr net;
+    virDomainHostdevDefPtr hostdev;
+    virDomainControllerDefPtr controller;
+    virDomainHostdevDefPtr found;
+    virDomainLeaseDefPtr lease;
+    virDomainFSDefPtr fs;
+    virDomainRedirdevDefPtr redirdev;
+    virDomainShmemDefPtr shmem;
+    char mac[VIR_MAC_STRING_BUFLEN];
+
+    switch (dev->type) {
+        case VIR_DOMAIN_DEVICE_DISK:
+            disk = dev->data.disk;
+            if (virDomainDiskIndexByName(vmdef, disk->dst, true) >= 0) {
+                virReportError(VIR_ERR_INVALID_ARG,
+                               _("target %s already exists."), disk->dst);
+                return -1;
+            }
+
+            if (virDomainDiskInsert(vmdef, disk) < 0)
+                return -1;
+
+            dev->data.disk = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_CONTROLLER:
+            controller = dev->data.controller;
+            if (controller->idx != -1 &&
+                virDomainControllerFind(vmdef, controller->type,
+                                        controller->idx) >= 0) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("Target already exists"));
+                return -1;
+            }
+
+            if (virDomainControllerInsert(vmdef, controller) < 0)
+                return -1;
+
+            dev->data.controller = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_NET:
+            net = dev->data.net;
+            if (virDomainHasNet(vmdef, net)) {
+                virReportError(VIR_ERR_INVALID_ARG,
+                               _("network device with mac %s already exists"),
+                               virMacAddrFormat(&net->mac, mac));
+                return -1;
+            }
+
+            if (virDomainNetInsert(vmdef, net))
+                return -1;
+
+            dev->data.net = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_HOSTDEV:
+            hostdev = dev->data.hostdev;
+            if (virDomainHostdevFind(vmdef, hostdev, &found) >= 0) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("device is already in the domain configuration"));
+                return -1;
+            }
+
+            if (virDomainHostdevInsert(vmdef, hostdev) < 0)
+                return -1;
+
+            dev->data.hostdev = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_LEASE:
+            lease = dev->data.lease;
+            if (virDomainLeaseIndex(vmdef, lease) >= 0) {
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                               _("Lease %s in lockspace %s already exists"),
+                               lease->key, NULLSTR(lease->lockspace));
+                return -1;
+            }
+
+            if (virDomainLeaseInsert(vmdef, lease) < 0)
+                return -1;
+
+            dev->data.lease = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_FS:
+            fs = dev->data.fs;
+            if (virDomainFSIndexByName(vmdef, fs->dst) >= 0) {
+                virReportError(VIR_ERR_OPERATION_INVALID,
+                             "%s", _("Target already exists"));
+                return -1;
+            }
+
+            if (virDomainFSInsert(vmdef, fs) < 0)
+                return -1;
+
+            dev->data.fs = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_RNG:
+            if (dev->data.rng->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+                virDomainDefHasDeviceAddress(vmdef, &dev->data.rng->info)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("a device with the same address already exists "));
+                return -1;
+            }
+
+            if (VIR_APPEND_ELEMENT(vmdef->rngs, vmdef->nrngs, dev->data.rng) < 0)
+                return -1;
+
+            dev->data.rng = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_MEMORY:
+            if (vmdef->nmems == vmdef->mem.memory_slots) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("no free memory device slot available"));
+                return -1;
+            }
+
+            vmdef->mem.cur_balloon += dev->data.memory->size;
+            if (virDomainMemoryInsert(vmdef, dev->data.memory) < 0)
+                return -1;
+
+            dev->data.memory = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_REDIRDEV:
+            redirdev = dev->data.redirdev;
+
+            if (VIR_APPEND_ELEMENT(vmdef->redirdevs, vmdef->nredirdevs, redirdev) < 0)
+                return -1;
+
+            dev->data.redirdev = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_SHMEM:
+            shmem = dev->data.shmem;
+            if (virDomainShmemDefFind(vmdef, shmem) >= 0) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("device is already in the domain configuration"));
+                return -1;
+            }
+
+            if (virDomainShmemDefInsert(vmdef, shmem) < 0)
+                return -1;
+
+            dev->data.shmem = NULL;
+            break;
+
+        case VIR_DOMAIN_DEVICE_WATCHDOG:
+            if (vmdef->watchdog) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("domain already has a watchdog"));
+                return -1;
+            }
+            VIR_STEAL_PTR(vmdef->watchdog, dev->data.watchdog);
+            break;
+
+        case VIR_DOMAIN_DEVICE_INPUT:
+            if (VIR_APPEND_ELEMENT(vmdef->inputs, vmdef->ninputs, dev->data.input) < 0)
+                return -1;
+            break;
+
+        case VIR_DOMAIN_DEVICE_VSOCK:
+            if (vmdef->vsock) {
+                virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                               _("domain already has a vsock device"));
+                return -1;
+            }
+            VIR_STEAL_PTR(vmdef->vsock, dev->data.vsock);
+            break;
+
+        default:
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("persistent attach of device is not supported"));
+            return -1;
+    }
+
+    return 0;
+}
+
+
+typedef enum {
+    TEST_DEVICE_ATTACH = 0,
+    TEST_DEVICE_DETACH,
+    TEST_DEVICE_UPDATE,
+} virTestDeviceOperation;
+
+
+static int
+testDomainDeviceOperation(testDriverPtr driver,
+                          virTestDeviceOperation operation,
+                          const char *xml,
+                          const char *alias,
+                          virDomainDefPtr def)
+{
+    virDomainDeviceDefPtr dev = NULL;
+    unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
+    int ret = -1;
+
+    if (operation == TEST_DEVICE_DETACH)
+        parse_flags |= VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
+
+    if (xml) {
+        if (!(dev = virDomainDeviceDefParse(xml, def,
+                                            driver->caps, driver->xmlopt,
+                                            NULL, parse_flags)))
+            goto cleanup;
+    } else if (alias) {
+        if (VIR_ALLOC(dev) < 0 || virDomainDefFindDevice(def, alias, dev, true) < 0)
+            goto cleanup;
+    }
+
+    switch (operation) {
+    case TEST_DEVICE_ATTACH:
+        if (testDomainAttachDeviceLiveAndConfig(def, dev) < 0)
+            goto cleanup;
+        break;
+    case TEST_DEVICE_DETACH:
+        break;
+    case TEST_DEVICE_UPDATE:
+        break;
+    }
+
+    ret = 0;
+ cleanup:
+    if (xml)
+        virDomainDeviceDefFree(dev);
+    else
+        VIR_FREE(dev);
+    return ret;
+}
+
+
+static int
+testDomainAttachDetachUpdateDevice(virDomainPtr dom,
+                                   virTestDeviceOperation operation,
+                                   const char *xml,
+                                   const char *alias,
+                                   unsigned int flags)
+{
+    testDriverPtr driver = dom->conn->privateData;
+    virDomainObjPtr vm = NULL;
+    virDomainDefPtr def;
+    virDomainDefPtr persistentDef;
+    int ret = -1;
+
+    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+    if (!(vm = testDomObjFromDomain(dom)))
+        goto cleanup;
+
+    if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
+        goto cleanup;
+
+    if (persistentDef) {
+        if (testDomainDeviceOperation(driver, operation, xml, alias, persistentDef) < 0)
+            goto cleanup;
+    }
+
+    if (def) {
+        if (testDomainDeviceOperation(driver, operation, xml, alias, def) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    virDomainObjEndAPI(&vm);
+    return ret;
+}
+
+
+static int
+testDomainAttachDeviceFlags(virDomainPtr dom,
+                            const char *xml,
+                            unsigned int flags)
+{
+    return testDomainAttachDetachUpdateDevice(dom, TEST_DEVICE_ATTACH,
+                                              xml, NULL, flags);
+}
+
+
 static int testDomainGetAutostart(virDomainPtr domain,
                                   int *autostart)
 {
@@ -9450,6 +9739,7 @@ static virHypervisorDriver testHypervisorDriver = {
     .domainFSFreeze = testDomainFSFreeze, /* 5.7.0 */
     .domainFSThaw = testDomainFSThaw, /* 5.7.0 */
     .domainFSTrim = testDomainFSTrim, /* 5.7.0 */
+    .domainAttachDeviceFlags = testDomainAttachDeviceFlags, /* 5.7.0 */
     .domainGetAutostart = testDomainGetAutostart, /* 0.3.2 */
     .domainSetAutostart = testDomainSetAutostart, /* 0.3.2 */
     .domainGetDiskErrors = testDomainGetDiskErrors, /* 5.4.0 */
--
2.22.0




More information about the libvir-list mailing list