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

Michal Privoznik posted 7 patches 6 years, 3 months ago
There is a newer version of this series
[libvirt] [PATCH v2 4/7] lockd_driver_lockd: Implement metadata flag
Posted by Michal Privoznik 6 years, 3 months ago
Signed-off-by: Michal Privoznik <mprivozn@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
+
 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 (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;
 
     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) {
+        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),
 };
 
 #endif /* __VIR_LOCK_DRIVER_LOCKD_H__ */
-- 
2.16.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 4/7] lockd_driver_lockd: Implement metadata flag
Posted by John Ferlan 6 years, 3 months ago

On 08/14/2018 07:19 AM, Michal Privoznik wrote:
> Signed-off-by: Michal Privoznik <mprivozn@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__ */
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 4/7] lockd_driver_lockd: Implement metadata flag
Posted by Michal Prívozník 6 years, 3 months ago
On 08/17/2018 01:53 AM, John Ferlan wrote:
> 
> 
> On 08/14/2018 07:19 AM, Michal Privoznik wrote:
>> Signed-off-by: Michal Privoznik <mprivozn@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?

Yes, this is exactly the purpose. I've taken inspiration from qemu. They
lock bytes from 100 to 100 + N, depending on what operations they want
the disk for (checkout raw_apply_lock_bytes() form block/file-posix.c).
And my idea was for virtlockd to do the same. Currently, it locks 0th
byte of given file and with metadata flag it would lock the first one.

> 
> 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.

Oh yeah, NFSv3 and file locks. Well, I'm not making our situation any
worse here. Qemu is already locking disks, and it is doing so for the
while lifetime of the domain whereas my patches would lock for only a
fraction of a second (well, as long as it takes for chown() and
setfilecon_raw() to run). It is very unlikely that connection to the
NFSv3 server will be lost right when metadata lock is held.

> 
>>  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.

That should never happen (TM). The metadata lock is acquired only for
time that seclabels are set on some domain paths (and as we will see in
6/7 we are not going to lock all the paths). As soon as they are set the
lock is released.

> 
>>  
>>      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.

So far there isn't such caller, but sure I can add an explicit check
that errors out if both READONLY and METADATA are set at the same time.

> 
>>  
>>      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?

Well, nresources == 0 can happen regardless of METADATA flag if
autoDiskLease is turned off. In that case no domain disk is added into
@resources and thus nresources can be zero. This is the situation where
we require users to put <lease/> into domain XML which will then protect
them.


By the same token, when locking for METADATA, we can not ignore
autoDiskLease setting (because if user has turned off disk leases they
probably did not set any lockspace dir and certainly did not put it onto
shared NFS, as required by our docs
https://libvirt.org/locking-lockd.html#lockdplugin) and we can't lock
files automatically. We must rely on <lease/>. However, we shouldn't
fail because from METADATA POV we don't care if a disk is RO or RW.

Long story short, if users want to rely on <lease/> solely we should
honour that.

> 
>> +        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?
> 

Oh, okay.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 4/7] lockd_driver_lockd: Implement metadata flag
Posted by Daniel P. Berrangé 6 years, 3 months ago
On Mon, Aug 20, 2018 at 09:25:13AM +0200, Michal Prívozník wrote:
> On 08/17/2018 01:53 AM, John Ferlan wrote:
> > 
> > 
> > On 08/14/2018 07:19 AM, Michal Privoznik wrote:
> >> Signed-off-by: Michal Privoznik <mprivozn@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?
> 
> Yes, this is exactly the purpose. I've taken inspiration from qemu. They
> lock bytes from 100 to 100 + N, depending on what operations they want
> the disk for (checkout raw_apply_lock_bytes() form block/file-posix.c).
> And my idea was for virtlockd to do the same. Currently, it locks 0th
> byte of given file and with metadata flag it would lock the first one.

Agreed, NFSv3 is already doomed, and this barely makes it worse because
of the short lock time. NFSv4 is the fix for anyone who really cares.

Better to have stale NFSv3 locks due to dead clients not releasing locks
than to loose all your VM disk due to corruption.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list