Signed-off-by: Ilias Stamatis <stamatis.iliass@xxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list