Add some basic plumbing, based on the qemu driver.
Signed-off-by: John Levon <john.levon(a)nutanix.com>
---
src/test/test_driver.c | 162 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 161 insertions(+), 1 deletion(-)
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 03afe8af8d..b7e36e8451 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -10223,6 +10223,158 @@ testDomainAttachHostDevice(testDriver *driver,
}
+/**
+ * @def: Domain definition
+ * @info: Domain device info
+ *
+ * Using the device info, find the controller related to the
+ * device by index and use that controller to return the model.
+ *
+ * Returns the model if found, -1 if not with an error message set
+ */
+static int
+testDomainFindSCSIControllerModel(const virDomainDef *def,
+ virDomainDeviceInfo *info)
+{
+ virDomainControllerDef *cont;
+
+ if (!(cont = virDomainDeviceFindSCSIController(def, &info->addr.drive))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unable to find a SCSI controller for idx=%1$d"),
+ info->addr.drive.controller);
+ return -1;
+ }
+
+ return cont->model;
+}
+
+
+static int
+testAssignDeviceDiskAlias(virDomainDef *def,
+ virDomainDiskDef *disk)
+{
+ const char *prefix = virDomainDiskBusTypeToString(disk->bus);
+ int controllerModel = -1;
+
+ if (!disk->info.alias) {
+ if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) {
+ if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ controllerModel = testDomainFindSCSIControllerModel(def,
+ &disk->info);
+ if (controllerModel < 0)
+ return -1;
+ }
+
+ if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI ||
+ controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
+ disk->info.alias = g_strdup_printf("%s%d-%d-%d", prefix,
+ disk->info.addr.drive.controller,
+ disk->info.addr.drive.bus,
+ disk->info.addr.drive.unit);
+ } else {
+ disk->info.alias = g_strdup_printf("%s%d-%d-%d-%d", prefix,
+ disk->info.addr.drive.controller,
+ disk->info.addr.drive.bus,
+ disk->info.addr.drive.target,
+ disk->info.addr.drive.unit);
+ }
+ } else {
+ int idx = virDiskNameToIndex(disk->dst);
+ disk->info.alias = g_strdup_printf("%s-disk%d", prefix, idx);
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+testDomainAttachDeviceDiskLiveInternal(testDriver *driver G_GNUC_UNUSED,
+ virDomainObj *vm,
+ virDomainDeviceDef *dev)
+{
+ size_t i;
+ virDomainDiskDef *disk = dev->data.disk;
+ int ret = -1;
+
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("floppy device hotplug isn't supported"));
+ return -1;
+ }
+
+ if (virDomainDiskTranslateSourcePool(disk) < 0)
+ goto cleanup;
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ if (virDomainDiskDefCheckDuplicateInfo(vm->def->disks[i], disk) < 0)
+ goto cleanup;
+ }
+
+ switch (disk->bus) {
+ case VIR_DOMAIN_DISK_BUS_USB:
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("disk device='lun' is not supported for usb
bus"));
+ goto cleanup;
+ }
+
+ break;
+
+ case VIR_DOMAIN_DISK_BUS_VIRTIO:
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("cdrom device with virtio bus isn't
supported"));
+ goto cleanup;
+ }
+ break;
+
+ case VIR_DOMAIN_DISK_BUS_SCSI:
+ case VIR_DOMAIN_DISK_BUS_IDE:
+ case VIR_DOMAIN_DISK_BUS_FDC:
+ case VIR_DOMAIN_DISK_BUS_XEN:
+ case VIR_DOMAIN_DISK_BUS_UML:
+ case VIR_DOMAIN_DISK_BUS_SATA:
+ case VIR_DOMAIN_DISK_BUS_SD:
+ case VIR_DOMAIN_DISK_BUS_NONE:
+ case VIR_DOMAIN_DISK_BUS_LAST:
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+ _("disk bus '%1$s' cannot be hotplugged."),
+ virDomainDiskBusTypeToString(disk->bus));
+ goto cleanup;
+ }
+
+ if (testAssignDeviceDiskAlias(vm->def, disk) < 0)
+ goto cleanup;
+
+ virDomainDiskInsert(vm->def, disk);
+
+ ret = 0;
+
+ cleanup:
+ return ret;
+}
+
+
+/**
+ * testDomainAttachDeviceDiskLive:
+ * @driver: test driver struct
+ * @vm: domain object
+ * @dev: device to attach (expected type is DISK)
+ *
+ * Attach a new disk or in case of cdroms/floppies change the media in the drive.
+ * This function handles all the necessary steps to attach a new storage source
+ * to the VM.
+ */
+static int
+testDomainAttachDeviceDiskLive(testDriver *driver,
+ virDomainObj *vm,
+ virDomainDeviceDef *dev)
+{
+ return testDomainAttachDeviceDiskLiveInternal(driver, vm, dev);
+}
+
+
static int
testDomainAttachDeviceLive(virDomainObj *vm,
virDomainDeviceDef *dev,
@@ -10251,8 +10403,16 @@ testDomainAttachDeviceLive(virDomainObj *vm,
}
break;
- case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_DISK:
+ testDomainObjCheckDiskTaint(vm, dev->data.disk);
+ ret = testDomainAttachDeviceDiskLive(driver, vm, dev);
+ if (!ret) {
+ alias = dev->data.disk->info.alias;
+ dev->data.disk = NULL;
+ }
+ break;
+
+ case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_LEASE:
case VIR_DOMAIN_DEVICE_FS:
case VIR_DOMAIN_DEVICE_INPUT:
--
2.34.1