This prevents restoring the unpriv_sgio if the disk is shared, and is being used by other active domain. Because we don't want to fall into the corruption situation. * src/conf/domain_conf.h (Declare virDomainDiskIsUsed, which is to detect if a disk is using by domain) * src/conf/domain_conf.c (Implement virDomainDiskIsUsed) * src/libvirt_private.syms: (Export virDomainDIskIsUsed) * src/qemu/qemu_process.c (Don't restore unpriv_sgio if the disk is shared, and is being used by other active domain). --- src/conf/domain_conf.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_process.c | 11 +++++++ 4 files changed, 82 insertions(+), 0 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b25229a..02df96e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -15697,3 +15697,69 @@ virDomainDefAddSecurityLabelDef(virDomainDefPtr def, const char *model) return seclabel; } + +struct virDomainDiskIsUsedData { + char *diskSrc; + char *name; /* Want to exclude some domain? */ + bool active; /* Want to only iterate the active domains? */ +}; + +static int +virDomainObjListSearchDiskPath(const void *payload, + const void *name ATTRIBUTE_UNUSED, + const void *opaque) +{ + virDomainObjPtr obj = (virDomainObjPtr)payload; + const struct virDomainDiskIsUsedData *data = opaque; + int i; + int ret = 0; + + virDomainObjLock(obj); + + if (data->active && + !virDomainObjIsActive(obj)) + goto cleanup; + + if (data->name && + STREQ(data->name, obj->def->name)) + goto cleanup; + + for (i = 0; i < obj->def->ndisks; i++) { + virDomainDiskDefPtr disk = obj->def->disks[i]; + + if (STREQ(disk->src, data->diskSrc)) { + ret = 1; + goto cleanup; + } + } + +cleanup: + virDomainObjUnlock(obj); + return ret; +} + +/** + * virDomainDiskIsUsed: + * @doms: List of domain objects + * @name: The domain name want to exclude + * @diskSrc: The disk path + * @active: Whether to exclude inactive domains + * + * Returns true if the disk is being used. Otherwise returns false. + */ +bool +virDomainDiskIsUsed(const virDomainObjList doms, + char *name, + char *diskSrc, + bool active) +{ + virDomainObjPtr obj; + + struct virDomainDiskIsUsedData data = { diskSrc, name, active }; + + obj = virHashSearch(doms.objs, virDomainObjListSearchDiskPath, &data); + if (obj) + return true; + + return false; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1a8de71..3105e05 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1874,6 +1874,10 @@ virDomainObjPtr virDomainFindByUUID(const virDomainObjListPtr doms, const unsigned char *uuid); virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms, const char *name); +bool virDomainDiskIsUsed(const virDomainObjList doms, + char *name, + char *diskSrc, + bool active); bool virDomainObjTaint(virDomainObjPtr obj, enum virDomainTaintFlags taint); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c756130..b9019b7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -319,6 +319,7 @@ virDomainDefFormatInternal; virDomainDefFree; virDomainDefGetSecurityLabelDef; virDomainDiskDefGetSecurityLabelDef; +virDomainDiskIsUsed; virDomainDefAddSecurityLabelDef; virDomainDefParseFile; virDomainDefParseNode; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index e48eed0..eeaaea0 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4120,6 +4120,17 @@ void qemuProcessStop(struct qemud_driver *driver, if (!disk->unpriv_sgio) continue; + /* Don't try to restore the unpriv_sgio if the disk is shared + * by other active domain(s). We don't want to fall into the + * corruptions. + */ + if (disk->shared && + virDomainDiskIsUsed(driver->domains, + vm->def->name, + disk->src, + true)) + continue; + if (virSetDeviceUnprivSGIO(disk->src, disk->old_unpriv_sgio) < 0) VIR_WARN("Unable to restore unpriv_sgio for disk '%s'", disk->src); } -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list