On 07/13/2011 10:56 AM, Michal Privoznik wrote:
+++ b/src/conf/domain_conf.c
@@ -11055,6 +11055,9 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
int ret = -1;
size_t depth = 0;
char *nextpath = NULL;
+ virStorageFileMetadata meta;
Existing code had a struct rather than pointer, and you just hoisted the
declaration, but this means...
+
+ memset(&meta, 0, sizeof(virStorageFileMetadata));
you had to manually clear it, but I guess I can live with that. On the
other hand, it looks like our prevailing style has instead been to use:
virStorageFileMetadata *meta;
if (VIR_ALLOC(meta) < 0) report OOM
use meta
virStorageFileMetadataFree(meta);
@@ -11137,6 +11140,8 @@ int
virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
format = meta.backingStoreFormat;
+ virStorageFileFreeMetadata(meta);
Here, you are passing by copy rather than by reference, so while this
frees the pointer to plug the leak, it leaves the caller's copy of
meta.backingStore now as a stale pointer. Not very nice. You have to
pass by reference so that the caller will see backingStore as NULL after
the cleanup function.
+++ b/src/libvirt_private.syms
@@ -940,6 +940,7 @@ virStorageGenerateQcowPassphrase;
# storage_file.h
virStorageFileFormatTypeFromString;
virStorageFileFormatTypeToString;
+virStorageFileFreeMetadata;
Generally, functions with Free in the name should be free-like (operate
on a pointer and free it, rather than operating on a struct by copy),
and listed in cfg.mk if they are no-ops when called on a NULL pointer.
Meanwhile, we use the name Clear for functions that operate on a
struct's members but do not free the struct itself (see domain_conf.c
for lots of examples). If you decide not to convert existing uses from
an in-place struct to a malloc'd pointer, then what you are implementing
might look better as:
void ATTRIBUTE_NONNULL(1)
virStorageFileMetadataClear(virStorageFileMetadata *meta)
{
VIR_FREE(meta->backingStore);
}
and update callers to do virStorageFileMetadataClear(&meta).
I agree that there's a leak to be plugged, but think we need a v2 that
clears up the naming and uses pass-by-reference, as well as deciding
whether to convert over to malloc'd pointers rather than on-stack structs.
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org