[libvirt] [PATCH 1/4] secret: Return with locked obj from virSecretObjListRemove

Erik Skultety eskultet at redhat.com
Thu Mar 22 09:44:17 UTC 2018


On Wed, Mar 21, 2018 at 11:53:32AM -0400, John Ferlan wrote:
> Rather than unlock the object that was expected to be locked on
> input, let the caller perform the unlock or more succinctly a
> virSecretObjEndAPI on the object which will perform the Unref
> and Unlock and clear the @obj.

I understand the incentive for this change and I agree with it, but I do have a
question below.

>
> Also clean up the virSecretObjListRemove function comments.
>
> Signed-off-by: John Ferlan <jferlan at redhat.com>
> ---
>  src/conf/virsecretobj.c    | 15 ++++++++-------
>  src/secret/secret_driver.c |  4 ----
>  2 files changed, 8 insertions(+), 11 deletions(-)
>
> diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c
> index 47e0b28968..49c341484b 100644
> --- a/src/conf/virsecretobj.c
> +++ b/src/conf/virsecretobj.c
> @@ -284,11 +284,14 @@ virSecretObjListFindByUsage(virSecretObjListPtr secrets,
>  /*
>   * virSecretObjListRemove:
>   * @secrets: list of secret objects
> - * @secret: a secret object
> + * @obj: a secret object
>   *
> - * Remove the object from the hash table.  The caller must hold the lock
> - * on the driver owning @secrets and must have also locked @secret to
> - * ensure no one else is either waiting for @secret or still using it.
> + * Remove @obj from the secret obj list hash table. The caller must hold
> + * the lock on @obj to ensure no one else is either waiting for @obj or
> + * still using it.
> + *
> + * Upon return the @obj remains locked with at least 1 reference and
> + * the caller is expected to use virSecretObjEndAPI on it.
>   */
>  void
>  virSecretObjListRemove(virSecretObjListPtr secrets,
> @@ -308,7 +311,6 @@ virSecretObjListRemove(virSecretObjListPtr secrets,
>      virObjectRWLockWrite(secrets);
>      virObjectLock(obj);
>      virHashRemoveEntry(secrets->objs, uuidstr);
> -    virObjectUnlock(obj);
>      virObjectUnref(obj);
>      virObjectRWUnlock(secrets);

So, why do we require the caller to hold a lock on the object when the very
first thing we do is that we ref the @obj, UNLOCK it to avoid a deadlock with
someone else already holding a lock on @secrets and waiting on @obj and only
when we have the lock on @secrets, we re-lock @obj. Why isn't it sufficient to
just ref @obj since that's an atomic op and then only lock it once we acquire a
lock on @secrets too. In this case, you don't have to accept and return a locked
object, you only lock when absolutely necessary, what am I missing? In my
opinion this lock-unlock-lock (with occasional ref) fire dance is quite
cumbersome, but I guess I might be missing some important aspect here which I
don't see at the first glance.

>  }
> @@ -927,8 +929,7 @@ virSecretLoad(virSecretObjListPtr secrets,
>
>      if (virSecretLoadValue(obj) < 0) {
>          virSecretObjListRemove(secrets, obj);
> -        virObjectUnref(obj);
> -        obj = NULL;
> +        virSecretObjEndAPI(&obj); /* clears obj */

This can be further simplified by moving the ObjEndAPI to the cleanup section
and removing the braces on this 'if' block.

Erik




More information about the libvir-list mailing list