To avoid memory leak of the "backingStoreRaw" field when reparsing backing chains a new function is being introduced by this patch that shall be used to clear backing store information. The memory leak was introduced in commit 8823272d41a259c1246c05d. --- src/libvirt_private.syms | 1 + src/qemu/qemu_domain.c | 8 +++----- src/qemu/qemu_driver.c | 3 +-- src/util/virstoragefile.c | 30 ++++++++++++++++++++++++------ src/util/virstoragefile.h | 1 + 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 55b016d..4cfaefc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1865,6 +1865,7 @@ virStorageNetHostTransportTypeToString; virStorageNetProtocolTypeToString; virStorageSourceAuthClear; virStorageSourceClear; +virStorageSourceClearBackingStore; virStorageSourceFree; virStorageSourceGetActualType; virStorageSourcePoolDefFree; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8fa58f3..a3c1b1c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2421,12 +2421,10 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver, goto cleanup; if (disk->src.backingStore) { - if (force) { - virStorageSourceFree(disk->src.backingStore); - disk->src.backingStore = NULL; - } else { + if (force) + virStorageSourceClearBackingStore(&disk->src); + else goto cleanup; - } } qemuDomainGetImageIds(cfg, vm, disk, &uid, &gid); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 75cf8cb..bf19c6e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12734,8 +12734,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, * recompute it. Better would be storing the chain ourselves rather than * reprobing, but this requires modifying domain_conf and our XML to fully * track the chain across libvirtd restarts. */ - virStorageSourceFree(disk->src.backingStore); - disk->src.backingStore = NULL; + virStorageSourceClearBackingStore(&disk->src); if (virStorageFileInit(&snap->src) < 0) goto cleanup; diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index dcce1ef..5c43665 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -1726,6 +1726,29 @@ virStorageSourceGetActualType(virStorageSourcePtr def) } +/** + * virStorageSourceClearBackingStore: + * + * @src: disk source to clear + * + * Clears information about backing store of the current storage file. + */ +void +virStorageSourceClearBackingStore(virStorageSourcePtr def) +{ + if (!def) + return; + + VIR_FREE(def->relPath); + VIR_FREE(def->relDir); + VIR_FREE(def->backingStoreRaw); + + /* recursively free backing chain */ + virStorageSourceFree(def->backingStore); + def->backingStore = NULL; +} + + void virStorageSourceClear(virStorageSourcePtr def) { @@ -1755,12 +1778,7 @@ virStorageSourceClear(virStorageSourcePtr def) virStorageNetHostDefFree(def->nhosts, def->hosts); virStorageSourceAuthClear(def); - VIR_FREE(def->relPath); - VIR_FREE(def->relDir); - VIR_FREE(def->backingStoreRaw); - - /* recursively free backing chain */ - virStorageSourceFree(def->backingStore); + virStorageSourceClearBackingStore(def); } diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 148776e..9e6cdba 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -316,5 +316,6 @@ void virStorageSourcePoolDefFree(virStorageSourcePoolDefPtr def); void virStorageSourceClear(virStorageSourcePtr def); int virStorageSourceGetActualType(virStorageSourcePtr def); void virStorageSourceFree(virStorageSourcePtr def); +void virStorageSourceClearBackingStore(virStorageSourcePtr def); #endif /* __VIR_STORAGE_FILE_H__ */ -- 1.9.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list