File libvirt-sanlock-don-t-fail-with-unregistered-domains.patch of Package libvirt

From 1d0d71d330bd9ea20b71db3c61ffd0a6be6e35b5 Mon Sep 17 00:00:00 2001
Message-Id: <1d0d71d330bd9ea20b71db3c61ffd0a6be6e35b5@dist-git>
From: Martin Kletzander <mkletzan@redhat.com>
Date: Tue, 13 May 2014 13:34:26 +0200
Subject: [PATCH] sanlock: don't fail with unregistered domains

When a domain was started without registration in sanlock, but libvirt
was restarted after that, most of the operations failed due to
contacting sanlock about that process.  E.g. migration could not be
performed because the locks couldn't be released (or inquired before a
release).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1088034

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit da879e592142291709f7b95b9218d32bb1869d1a)

Conflicts:
	src/locking/lock_driver_sanlock.c -- 88e4e9c6 (context)

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/locking/lock_driver_sanlock.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index 3ab8ef3..207bef6 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -89,6 +89,9 @@ struct _virLockManagerSanlockPrivate {
     bool hasRWDisks;
     int res_count;
     struct sanlk_resource *res_args[SANLK_MAX_RESOURCES];
+
+    /* whether the VM was registered or not */
+    bool registered;
 };
 
 /*
@@ -448,6 +451,7 @@ static int virLockManagerSanlockNew(virLockManagerPtr lock,
     virLockManagerParamPtr param;
     virLockManagerSanlockPrivatePtr priv;
     int i;
+    int resCount = 0;
 
     virCheckFlags(0, -1);
 
@@ -489,6 +493,16 @@ static int virLockManagerSanlockNew(virLockManagerPtr lock,
         }
     }
 
+    /* Sanlock needs process registration, but the only way how to probe
+     * whether a process has been registered is to inquire the lock.  If
+     * sanlock_inquire() returns -ESRCH, then it is not registered, but
+     * if it returns any other error (rv < 0), then we cannot fail due
+     * to back-compat.  So this whole call is non-fatal, because it's
+     * called from all over the place (it will usually fail).  It merely
+     * updates privateData. */
+    if (sanlock_inquire(-1, priv->vm_pid, 0, &resCount, NULL) >= 0)
+        priv->registered = true;
+
     lock->privateData = priv;
     return 0;
 
@@ -934,6 +948,9 @@ static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
             goto error;
         }
 
+        /* Mark the pid as registered */
+        priv->registered = true;
+
         if (action != VIR_DOMAIN_LOCK_FAILURE_DEFAULT) {
             char uuidstr[VIR_UUID_STRING_BUFLEN];
             virUUIDFormat(priv->vm_uuid, uuidstr);
@@ -941,6 +958,9 @@ static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
                                                         uuidstr, action) < 0)
                 goto error;
         }
+    } else if (!priv->registered) {
+        VIR_DEBUG("Process not registered, not acquiring lock");
+        return 0;
     }
 
     /* sanlock doesn't use owner_name for anything, so it's safe to take just
@@ -1044,6 +1064,11 @@ static int virLockManagerSanlockRelease(virLockManagerPtr lock,
 
     virCheckFlags(0, -1);
 
+    if (!priv->registered) {
+        VIR_DEBUG("Process not registered, skipping release");
+        return 0;
+    }
+
     if (state) {
         if ((rv = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) {
             if (rv <= -200)
@@ -1089,6 +1114,12 @@ static int virLockManagerSanlockInquire(virLockManagerPtr lock,
 
     VIR_DEBUG("pid=%d", priv->vm_pid);
 
+    if (!priv->registered) {
+        VIR_DEBUG("Process not registered, skipping inquiry");
+        VIR_FREE(*state);
+        return 0;
+    }
+
     if ((rv = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) {
         if (rv <= -200)
             virReportError(VIR_ERR_INTERNAL_ERROR,
-- 
1.9.3

openSUSE Build Service is sponsored by