Source device/file is not unique now, we should check it when attach device. Signed-off-by: YueWenyuan <yuewenyuan@xxxxxxxxxx> Signed-off-by: Zhang Bo <oscar.zhangbo@xxxxxxxxxx> --- src/conf/domain_conf.c | 15 +++++++++++++++ src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 12 +++++++++++- src/qemu/qemu_hotplug.c | 42 +++++++++++++++++++++++++++--------------- 5 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 58b98c6..3fd729c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18191,6 +18191,21 @@ virDomainControllerDefFormat(virBufferPtr buf, int +virDomainFSIndexBySrc(virDomainDefPtr def, const char *src) +{ + virDomainFSDefPtr fs; + size_t i; + + for (i = 0; i < def->nfss; i++) { + fs = def->fss[i]; + if (STREQ(fs->src, src)) + return i; + } + return -1; +} + + +int virDomainFSIndexByName(virDomainDefPtr def, const char *name) { virDomainFSDefPtr fs; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e6fa3c9..e23f289 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2804,6 +2804,7 @@ int virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk, virDomainFSDefPtr virDomainGetFilesystemForTarget(virDomainDefPtr def, const char *target); int virDomainFSInsert(virDomainDefPtr def, virDomainFSDefPtr fs); +int virDomainFSIndexBySrc(virDomainDefPtr def, const char *src); int virDomainFSIndexByName(virDomainDefPtr def, const char *name); virDomainFSDefPtr virDomainFSRemove(virDomainDefPtr def, size_t i); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7166283..611c0d4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -274,6 +274,7 @@ virDomainDiskSourceIsBlockType; virDomainEmulatorPinAdd; virDomainEmulatorPinDel; virDomainFSDefFree; +virDomainFSIndexBySrc; virDomainFSIndexByName; virDomainFSInsert; virDomainFSRemove; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cbb6e1b..3b187f0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7953,6 +7953,11 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, _("target %s already exists"), disk->dst); return -1; } + if (virDomainDiskIndexByName(vmdef, disk->src->path, true) >= 0) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("source %s already exists"), disk->src->path); + return -1; + } if (qemuCheckDiskConfig(disk) < 0) return -1; if (virDomainDiskInsert(vmdef, disk)) @@ -8035,7 +8040,12 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, fs = dev->data.fs; if (virDomainFSIndexByName(vmdef, fs->dst) >= 0) { virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("Target already exists")); + _("Target %s already exists"), fs->dst); + return -1; + } + if (virDomainFSIndexBySrc(vmdef, fs->src) >= 0) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("Source %s already exists"), fs->src); return -1; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 2f0549e..5dd2453 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -315,12 +315,34 @@ qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver, } static int +qemuDomainCheckDiskDeviceExists(virDomainObjPtr vm, + virDomainDiskDefPtr disk) +{ + int ret = -1; + size_t i; + for (i = 0; i < vm->def->ndisks; i++) { + if (STREQ(vm->def->disks[i]->dst, disk->dst)) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("target %s already exists"), disk->dst); + return ret; + } + if (disk->src && vm->def->disks[i]->src && + disk->src->path && vm->def->disks[i]->src->path && + STREQ(vm->def->disks[i]->src->path, disk->src->path)) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("source %s already exists"), disk->src->path); + return ret; + } + } + return 0; +} + +static int qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDiskDefPtr disk) { - size_t i; int ret = -1; const char* type = virDomainDiskBusTypeToString(disk->bus); qemuDomainObjPrivatePtr priv = vm->privateData; @@ -338,13 +360,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn, disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390; } - for (i = 0; i < vm->def->ndisks; i++) { - if (STREQ(vm->def->disks[i]->dst, disk->dst)) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("target %s already exists"), disk->dst); - goto cleanup; - } - } + if (qemuDomainCheckDiskDeviceExists(vm, disk) < 0) + goto cleanup; if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0) goto cleanup; @@ -579,13 +596,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn, int ret = -1; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - for (i = 0; i < vm->def->ndisks; i++) { - if (STREQ(vm->def->disks[i]->dst, disk->dst)) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("target %s already exists"), disk->dst); - goto cleanup; - } - } + if (qemuDomainCheckDiskDeviceExists(vm, disk) < 0) + goto cleanup; if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0) goto cleanup; -- 1.7.12.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list