[libvirt] [PATCH v4 16/23] security_manager: Introduce metadata locking APIs

John Ferlan jferlan at redhat.com
Mon Sep 17 21:14:39 UTC 2018



On 09/10/2018 05:36 AM, Michal Privoznik wrote:
> Two new APIs are added so that security driver can lock and
> unlock paths it wishes to touch. These APIs are not for other
> drivers to call but security drivers (DAC and SELinux). That is
> the reason these APIs are not exposed through our
> libvirt_private.syms file.
> 
> Three interesting things happen in this commit. The first is the
> global @lockManagerMutex. Unfortunately, this has to exist so that
> there is only on thread talking to virtlockd at a time. If there

s/on/one

> were more threads and one of them closed the connection
> prematurely, it would cause virtlockd killing libvirtd. Instead
> of complicated code that would handle that, let's have a mutex
> and keep the code simple.
> 
> The second interesting thing is keeping connection open between
> lock and unlock API calls. This is achieved by duplicating client
> FD and keeping it open until unlock is called. This trick is used
> by regular disk content locking code when the FD is leaked to
> qemu.
> 
> Finally, the third thing is polling implemented at client side.
> Since virtlockd has only one thread that handles locking
> requests, all it can do is either acquire lock or error out.
> Therefore, the polling has to be implemented in client. The
> polling is capped at 60 second timeout, which should be plenty
> since the metadata lock is held only for a fraction of a second.

I smell a configurable timeout instead of 60 seconds, but that's mainly
because my senses are more acutely aware of such configurable timeout
changes given some recent on list patches for client lock timeouts when
(as I assume) there is a client gathering stats that takes a long time.

> 
> Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> ---
>  src/security/security_manager.c | 135 ++++++++++++++++++++++++++++++++++++++++
>  src/security/security_manager.h |   7 +++
>  2 files changed, 142 insertions(+)
> 
> diff --git a/src/security/security_manager.c b/src/security/security_manager.c
> index 5c8370c159..dd5c3ac7e5 100644
> --- a/src/security/security_manager.c
> +++ b/src/security/security_manager.c
> @@ -29,11 +29,15 @@
>  #include "virobject.h"
>  #include "virlog.h"
>  #include "locking/lock_manager.h"
> +#include "virfile.h"
> +#include "virtime.h"
>  
>  #define VIR_FROM_THIS VIR_FROM_SECURITY
>  
>  VIR_LOG_INIT("security.security_manager");
>  
> +virMutex lockManagerMutex = VIR_MUTEX_INITIALIZER;
> +
>  struct _virSecurityManager {
>      virObjectLockable parent;
>  
> @@ -43,6 +47,7 @@ struct _virSecurityManager {
>      void *privateData;
>  
>      virLockManagerPluginPtr lockPlugin;
> +    int fd;

Would you mind renaming to "clientfd" or at least "noting" in comments
here where this fd is duplicated so that future me doesn't need to go
back and read the commit where this was added to refresh my memory.

Seeing just fd and searching on that is like finding a needle in the
haystack of fd's.

>  };
>  

[...]

> +
> +/* How many seconds should we try to acquire the lock before
> + * giving up. */

How much wood could a woodchuck chuck wood if a woodchuck could chuck wood?

> +#define LOCK_ACQUIRE_TIMEOUT 60
> +
> +int
> +virSecurityManagerMetadataLock(virSecurityManagerPtr mgr,
> +                               const char * const *paths,
> +                               size_t npaths)
> +{
> +    virLockManagerPtr lock;
> +    virTimeBackOffVar timebackoff;
> +    int fd = -1;
> +    int rv;

I know you know already by rv = -1

> +    int ret = -1;
> +
> +    virMutexLock(&lockManagerMutex);
> +
> +    if (!(lock = virSecurityManagerNewLockManager(mgr, paths, npaths)))
> +        goto cleanup;
> +

Just a couple of minor things,

Reviewed-by: John Ferlan <jferlan at redhat.com>

John




More information about the libvir-list mailing list