[libvirt] [PATCH 15/17] nwfilter: Convert _virNWFilterObjList to be a virObjectLockable

Michal Privoznik mprivozn at redhat.com
Thu Jul 13 14:40:48 UTC 2017


On 06/02/2017 12:25 PM, John Ferlan wrote:
> Perhaps a bit out of order from the normal convert driver object to
> virObjectLockable, then convert the driver object list. However, as
> it turns out nwfilter objects have been using a recursive mutex for
> which the common virObject code does not want to use.
> 
> So, if we convert the nwfilter object list to use virObjectLockable,
> then it will be more possible to make the necessary adjustments to
> the virNWFilterObjListFindInstantiateFilter algorithm in order to
> handle a recursive lock operation required as part of the <rule> and
> <filterref> (or "inc" list) processing.
> 
> This patch takes the plunge, modifying the nwfilter object list
> handling code to utilize hash tables for both the UUID and Name
> for which an nwfilter def would utilize. This makes lookup by
> either "key" possible without needing to first lock the object
> in order to find a match as long as of course the object list itself
> is locked.
> 
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
>  src/conf/virnwfilterobj.c      | 395 +++++++++++++++++++++++++++++------------
>  src/nwfilter/nwfilter_driver.c |   4 +
>  2 files changed, 286 insertions(+), 113 deletions(-)
> 
> diff --git a/src/conf/virnwfilterobj.c b/src/conf/virnwfilterobj.c
> index 99be59c..84ef7d1 100644
> --- a/src/conf/virnwfilterobj.c
> +++ b/src/conf/virnwfilterobj.c
> @@ -53,10 +53,34 @@ struct _virNWFilterObj {
>  };
>  
>  struct _virNWFilterObjList {
> -    size_t count;
> -    virNWFilterObjPtr *objs;
> +    virObjectLockable parent;
> +
> +    /* uuid string -> virNWFilterObj  mapping
> +     * for O(1), lockless lookup-by-uuid */
> +    virHashTable *objs;
> +
> +    /* name -> virNWFilterObj mapping for O(1),
> +     * lockless lookup-by-name */
> +    virHashTable *objsName;
>  };
>  
> +static virClassPtr virNWFilterObjListClass;
> +static void virNWFilterObjListDispose(void *opaque);
> +
> +static int
> +virNWFilterObjOnceInit(void)
> +{
> +    if (!(virNWFilterObjListClass = virClassNew(virClassForObjectLockable(),
> +                                                "virNWFilterObjList",
> +                                                sizeof(virNWFilterObjList),
> +                                                virNWFilterObjListDispose)))
> +        return -1;
> +
> +    return 0;
> +}
> +
> +VIR_ONCE_GLOBAL_INIT(virNWFilterObj)
> +
>  
>  static virNWFilterObjPtr
>  virNWFilterObjNew(virNWFilterDefPtr def)
> @@ -151,14 +175,30 @@ virNWFilterObjUnref(virNWFilterObjPtr obj)
>  }
>  
>  
> +static void
> +virNWFilterObjListDispose(void *opaque)
> +{
> +    virNWFilterObjListPtr nwfilters = opaque;
> +
> +    virHashFree(nwfilters->objs);
> +    virHashFree(nwfilters->objsName);
> +}
> +
> +
>  void
>  virNWFilterObjListFree(virNWFilterObjListPtr nwfilters)
>  {
> -    size_t i;
> -    for (i = 0; i < nwfilters->count; i++)
> -        virNWFilterObjUnref(nwfilters->objs[i]);
> -    VIR_FREE(nwfilters->objs);
> -    VIR_FREE(nwfilters);
> +    virObjectUnref(nwfilters);
> +}
> +
> +
> +static void
> +virNWFilterObjListObjsFreeData(void *payload,
> +                               const void *name ATTRIBUTE_UNUSED)
> +{
> +    virNWFilterObjPtr obj = payload;
> +
> +    virNWFilterObjUnref(obj);
>  }
>  
>  
> @@ -167,8 +207,24 @@ virNWFilterObjListNew(void)
>  {
>      virNWFilterObjListPtr nwfilters;
>  
> -    if (VIR_ALLOC(nwfilters) < 0)
> +    if (virNWFilterObjInitialize() < 0)
> +        return NULL;
> +
> +    if (!(nwfilters = virObjectLockableNew(virNWFilterObjListClass)))
> +        return NULL;
> +
> +    if (!(nwfilters->objs = virHashCreate(10, virNWFilterObjListObjsFreeData))) {
> +        virObjectUnref(nwfilters);
> +        return NULL;
> +    }
> +
> +    if (!(nwfilters->objsName =
> +          virHashCreate(10, virNWFilterObjListObjsFreeData))) {

Again, 86 characters is not that much ;-)

> +        virHashFree(nwfilters->objs);
> +        virObjectUnref(nwfilters);
>          return NULL;
> +    }
> +
>      return nwfilters;
>  }

Otherwise looking good.

ACK

Michal




More information about the libvir-list mailing list