[libvirt] [PATCH v2 4/7] lockd_driver_lockd: Implement metadata flag

John Ferlan jferlan at redhat.com
Thu Aug 16 23:53:15 UTC 2018



On 08/14/2018 07:19 AM, Michal Privoznik wrote:
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/locking/lock_daemon_dispatch.c | 12 ++++++++++--
>  src/locking/lock_driver_lockd.c    | 31 +++++++++++++++++++++----------
>  src/locking/lock_driver_lockd.h    |  1 +
>  3 files changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git a/src/locking/lock_daemon_dispatch.c b/src/locking/lock_daemon_dispatch.c
> index 10248ec0b5..c24571ceac 100644
> --- a/src/locking/lock_daemon_dispatch.c
> +++ b/src/locking/lock_daemon_dispatch.c
> @@ -37,6 +37,9 @@ VIR_LOG_INIT("locking.lock_daemon_dispatch");
>  
>  #include "lock_daemon_dispatch_stubs.h"
>  
> +#define DEFAULT_OFFSET 0
> +#define METADATA_OFFSET 1
> +

Curious, does this lead to the prospect of being able to acquire/use
offset==0 length==1 and offset==1 length==1 at least conceptually and
granularity wise?

Related or not, there's a strange NFSv3 collision between QEMU and NFS
related to some sort of fcntl locking granularity. More details that you
possibly want to read at:

https://bugzilla.redhat.com/show_bug.cgi?id=1592582
https://bugzilla.redhat.com/show_bug.cgi?id=1547095

I only note it because well it was on my 'short term history' radar and
suffice to say it's an ugly and not fun issue dealing with these locks.

>  static int
>  virLockSpaceProtocolDispatchAcquireResource(virNetServerPtr server ATTRIBUTE_UNUSED,
>                                              virNetServerClientPtr client,
> @@ -50,13 +53,14 @@ virLockSpaceProtocolDispatchAcquireResource(virNetServerPtr server ATTRIBUTE_UNU
>          virNetServerClientGetPrivateData(client);
>      virLockSpacePtr lockspace;
>      unsigned int newFlags;
> -    off_t start = 0;
> +    off_t start = DEFAULT_OFFSET;
>      off_t len = 1;
>  
>      virMutexLock(&priv->lock);
>  
>      virCheckFlagsGoto(VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED |
> -                      VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE, cleanup);
> +                      VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE |
> +                      VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_METADATA, cleanup);
>  
>      if (priv->restricted) {
>          virReportError(VIR_ERR_OPERATION_DENIED, "%s",
> @@ -82,6 +86,10 @@ virLockSpaceProtocolDispatchAcquireResource(virNetServerPtr server ATTRIBUTE_UNU
>          newFlags |= VIR_LOCK_SPACE_ACQUIRE_SHARED;
>      if (flags & VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE)
>          newFlags |= VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE;
> +    if (flags & VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_METADATA) {
> +        start = METADATA_OFFSET;
> +        newFlags |= VIR_LOCK_SPACE_ACQUIRE_WAIT;
> +    }

If this is documented in more detail, then it should be noted that a
METADATA lock forces usage of the wait API's. I can only imagine
someone, some day will ask for a wait w/ timeout to avoid waiting too long.

>  
>      if (virLockSpaceAcquireResource(lockspace,
>                                      args->name,
> diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c
> index 957a963a7b..bd14ed8930 100644
> --- a/src/locking/lock_driver_lockd.c
> +++ b/src/locking/lock_driver_lockd.c
> @@ -475,9 +475,11 @@ static int virLockManagerLockDaemonAddResource(virLockManagerPtr lock,
>      bool autoCreate = false;
>  
>      virCheckFlags(VIR_LOCK_MANAGER_RESOURCE_READONLY |
> -                  VIR_LOCK_MANAGER_RESOURCE_SHARED, -1);
> +                  VIR_LOCK_MANAGER_RESOURCE_SHARED |
> +                  VIR_LOCK_MANAGER_RESOURCE_METADATA, -1);
>  
> -    if (flags & VIR_LOCK_MANAGER_RESOURCE_READONLY)
> +    if (flags & VIR_LOCK_MANAGER_RESOURCE_READONLY &&
> +        !(flags & VIR_LOCK_MANAGER_RESOURCE_METADATA))
>          return 0;

Could someone pass READONLY & METADATA and not return 0 here?  Yes,
doesn't make sense, but combining them leads to the logic matrix question.

>  
>      switch (type) {
> @@ -489,7 +491,8 @@ static int virLockManagerLockDaemonAddResource(virLockManagerPtr lock,
>          }
>          if (!driver->autoDiskLease) {
>              if (!(flags & (VIR_LOCK_MANAGER_RESOURCE_SHARED |
> -                           VIR_LOCK_MANAGER_RESOURCE_READONLY)))
> +                           VIR_LOCK_MANAGER_RESOURCE_READONLY |
> +                           VIR_LOCK_MANAGER_RESOURCE_METADATA)))
>                  priv->hasRWDisks = true;
>              return 0;
>          }
> @@ -602,6 +605,10 @@ static int virLockManagerLockDaemonAddResource(virLockManagerPtr lock,
>          priv->resources[priv->nresources-1].flags |=
>              VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE;
>  
> +    if (flags & VIR_LOCK_MANAGER_RESOURCE_METADATA)
> +        priv->resources[priv->nresources-1].flags |=
> +            VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_METADATA;
> +
>      return 0;
>  
>   error:
> @@ -626,12 +633,15 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
>      virCheckFlags(VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY |
>                    VIR_LOCK_MANAGER_ACQUIRE_RESTRICT, -1);
>  
> -    if (priv->nresources == 0 &&
> -        priv->hasRWDisks &&
> -        driver->requireLeaseForDisks) {
> -        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> -                       _("Read/write, exclusive access, disks were present, but no leases specified"));
> -        return -1;
> +    if (priv->nresources == 0) {

I'm assuming there's a relationship between metadata and nresources == 0
which really isn't apparent especially since the subsequent error
message is about leases.  Do we need to check for resource type?

Or in the top level API do we need to only allow METADATA for DISK type?

> +        if (priv->hasRWDisks &&
> +            driver->requireLeaseForDisks) {
> +            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> +                           _("Read/write, exclusive access, disks were present, but no leases specified"));
> +            return -1;
> +        }
> +
> +        return 0;
>      }
>  
>      if (!(client = virLockManagerLockDaemonConnect(lock, &program, &counter)))
> @@ -711,7 +721,8 @@ static int virLockManagerLockDaemonRelease(virLockManagerPtr lock,
>  
>          args.flags &=
>              ~(VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED |
> -              VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE);
> +              VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE |
> +              VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_METADATA);
>  
>          if (virNetClientProgramCall(program,
>                                      client,
> diff --git a/src/locking/lock_driver_lockd.h b/src/locking/lock_driver_lockd.h
> index 6931fe7425..9882793260 100644
> --- a/src/locking/lock_driver_lockd.h
> +++ b/src/locking/lock_driver_lockd.h
> @@ -25,6 +25,7 @@
>  enum virLockSpaceProtocolAcquireResourceFlags {
>          VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED = (1 << 0),
>          VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE = (1 << 1),
> +        VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_METADATA = (1 << 2),

Use of RESOURCE_METADATA would be more consistent wouldn't it?

John

I'll continue looking tomorrow...

>  };
>  
>  #endif /* __VIR_LOCK_DRIVER_LOCKD_H__ */
> 




More information about the libvir-list mailing list