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