[libvirt] [PATCH] storage: Avoid memory leak on metadata fetching

Eric Blake eblake at redhat.com
Wed Jul 13 17:13:47 UTC 2011


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 at redhat.com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20110713/eed1b7fb/attachment-0001.sig>


More information about the libvir-list mailing list