mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-09-09 01:04:59 +00:00
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>
This commit is contained in:
parent
d99057423c
commit
da879e5921
@ -91,6 +91,9 @@ struct _virLockManagerSanlockPrivate {
|
|||||||
bool hasRWDisks;
|
bool hasRWDisks;
|
||||||
int res_count;
|
int res_count;
|
||||||
struct sanlk_resource *res_args[SANLK_MAX_RESOURCES];
|
struct sanlk_resource *res_args[SANLK_MAX_RESOURCES];
|
||||||
|
|
||||||
|
/* whether the VM was registered or not */
|
||||||
|
bool registered;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -450,6 +453,7 @@ static int virLockManagerSanlockNew(virLockManagerPtr lock,
|
|||||||
virLockManagerParamPtr param;
|
virLockManagerParamPtr param;
|
||||||
virLockManagerSanlockPrivatePtr priv;
|
virLockManagerSanlockPrivatePtr priv;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int resCount = 0;
|
||||||
|
|
||||||
virCheckFlags(0, -1);
|
virCheckFlags(0, -1);
|
||||||
|
|
||||||
@ -487,6 +491,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;
|
lock->privateData = priv;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -915,6 +929,9 @@ static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the pid as registered */
|
||||||
|
priv->registered = true;
|
||||||
|
|
||||||
if (action != VIR_DOMAIN_LOCK_FAILURE_DEFAULT) {
|
if (action != VIR_DOMAIN_LOCK_FAILURE_DEFAULT) {
|
||||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
virUUIDFormat(priv->vm_uuid, uuidstr);
|
virUUIDFormat(priv->vm_uuid, uuidstr);
|
||||||
@ -922,6 +939,9 @@ static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
|
|||||||
uuidstr, action) < 0)
|
uuidstr, action) < 0)
|
||||||
goto error;
|
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
|
/* sanlock doesn't use owner_name for anything, so it's safe to take just
|
||||||
@ -1025,6 +1045,11 @@ static int virLockManagerSanlockRelease(virLockManagerPtr lock,
|
|||||||
|
|
||||||
virCheckFlags(0, -1);
|
virCheckFlags(0, -1);
|
||||||
|
|
||||||
|
if (!priv->registered) {
|
||||||
|
VIR_DEBUG("Process not registered, skipping release");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
if ((rv = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) {
|
if ((rv = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) {
|
||||||
if (rv <= -200)
|
if (rv <= -200)
|
||||||
@ -1070,6 +1095,12 @@ static int virLockManagerSanlockInquire(virLockManagerPtr lock,
|
|||||||
|
|
||||||
VIR_DEBUG("pid=%d", priv->vm_pid);
|
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 = sanlock_inquire(-1, priv->vm_pid, 0, &res_count, state)) < 0) {
|
||||||
if (rv <= -200)
|
if (rv <= -200)
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
Loading…
Reference in New Issue
Block a user