提交 385eb839 编写于 作者: M Michal Privoznik

lock_driver: Introduce VIR_LOCK_MANAGER_ACQUIRE_ROLLBACK

Soon there will be a virtlockd client that wants to either lock
all the resources or none (in order to avoid virtlockd killing
the client on connection close). Because on the RPC layer we can
only acquire one resource at a time, we have to perform a
rollback once we hit a resource that can't be acquired.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NJohn Ferlan <jferlan@redhat.com>
上级 997283b5
...@@ -67,6 +67,10 @@ typedef enum { ...@@ -67,6 +67,10 @@ typedef enum {
VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY = (1 << 0), VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY = (1 << 0),
/* Prevent further lock/unlock calls from this process */ /* Prevent further lock/unlock calls from this process */
VIR_LOCK_MANAGER_ACQUIRE_RESTRICT = (1 << 1), VIR_LOCK_MANAGER_ACQUIRE_RESTRICT = (1 << 1),
/* Used when acquiring more resources in which one of them
* can't be acquired, perform a rollback and release all
* resources acquired so far. */
VIR_LOCK_MANAGER_ACQUIRE_ROLLBACK = (1 << 2),
} virLockManagerAcquireFlags; } virLockManagerAcquireFlags;
typedef enum { typedef enum {
......
...@@ -735,6 +735,34 @@ static int virLockManagerLockDaemonAddResource(virLockManagerPtr lock, ...@@ -735,6 +735,34 @@ static int virLockManagerLockDaemonAddResource(virLockManagerPtr lock,
} }
static int virLockManagerLockDaemonReleaseImpl(virNetClientPtr client,
virNetClientProgramPtr program,
int counter,
virLockManagerLockDaemonResourcePtr res)
{
virLockSpaceProtocolReleaseResourceArgs args;
memset(&args, 0, sizeof(args));
args.path = res->lockspace;
args.name = res->name;
args.flags = res->flags;
args.flags &=
~(VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED |
VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE |
VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_METADATA);
return virNetClientProgramCall(program,
client,
counter,
VIR_LOCK_SPACE_PROTOCOL_PROC_RELEASE_RESOURCE,
0, NULL, NULL, NULL,
(xdrproc_t)xdr_virLockSpaceProtocolReleaseResourceArgs, &args,
(xdrproc_t)xdr_void, NULL);
}
static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock, static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
const char *state ATTRIBUTE_UNUSED, const char *state ATTRIBUTE_UNUSED,
unsigned int flags, unsigned int flags,
...@@ -745,10 +773,13 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock, ...@@ -745,10 +773,13 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
virNetClientProgramPtr program = NULL; virNetClientProgramPtr program = NULL;
int counter = 0; int counter = 0;
int rv = -1; int rv = -1;
ssize_t i;
ssize_t lastGood = -1;
virLockManagerLockDaemonPrivatePtr priv = lock->privateData; virLockManagerLockDaemonPrivatePtr priv = lock->privateData;
virCheckFlags(VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY | virCheckFlags(VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY |
VIR_LOCK_MANAGER_ACQUIRE_RESTRICT, -1); VIR_LOCK_MANAGER_ACQUIRE_RESTRICT |
VIR_LOCK_MANAGER_ACQUIRE_ROLLBACK, -1);
if (priv->type == VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN && if (priv->type == VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN &&
priv->nresources == 0 && priv->nresources == 0 &&
...@@ -767,7 +798,6 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock, ...@@ -767,7 +798,6 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
goto cleanup; goto cleanup;
if (!(flags & VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY)) { if (!(flags & VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY)) {
size_t i;
for (i = 0; i < priv->nresources; i++) { for (i = 0; i < priv->nresources; i++) {
virLockSpaceProtocolAcquireResourceArgs args; virLockSpaceProtocolAcquireResourceArgs args;
...@@ -785,6 +815,7 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock, ...@@ -785,6 +815,7 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
(xdrproc_t)xdr_virLockSpaceProtocolAcquireResourceArgs, &args, (xdrproc_t)xdr_virLockSpaceProtocolAcquireResourceArgs, &args,
(xdrproc_t)xdr_void, NULL) < 0) (xdrproc_t)xdr_void, NULL) < 0)
goto cleanup; goto cleanup;
lastGood = i;
} }
} }
...@@ -795,8 +826,28 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock, ...@@ -795,8 +826,28 @@ static int virLockManagerLockDaemonAcquire(virLockManagerPtr lock,
rv = 0; rv = 0;
cleanup: cleanup:
if (rv != 0 && fd) if (rv < 0) {
VIR_FORCE_CLOSE(*fd); int saved_errno = errno;
virErrorPtr origerr;
virErrorPreserveLast(&origerr);
if (fd)
VIR_FORCE_CLOSE(*fd);
if (flags & VIR_LOCK_MANAGER_ACQUIRE_ROLLBACK) {
for (i = lastGood; i >= 0; i--) {
virLockManagerLockDaemonResourcePtr res = &priv->resources[i];
if (virLockManagerLockDaemonReleaseImpl(client, program,
counter++, res) < 0)
VIR_WARN("Unable to release resource lockspace=%s name=%s",
res->lockspace, res->name);
}
}
virErrorRestore(&origerr);
errno = saved_errno;
}
virNetClientClose(client); virNetClientClose(client);
virObjectUnref(client); virObjectUnref(client);
virObjectUnref(program); virObjectUnref(program);
...@@ -824,27 +875,10 @@ static int virLockManagerLockDaemonRelease(virLockManagerPtr lock, ...@@ -824,27 +875,10 @@ static int virLockManagerLockDaemonRelease(virLockManagerPtr lock,
goto cleanup; goto cleanup;
for (i = 0; i < priv->nresources; i++) { for (i = 0; i < priv->nresources; i++) {
virLockSpaceProtocolReleaseResourceArgs args; virLockManagerLockDaemonResourcePtr res = &priv->resources[i];
memset(&args, 0, sizeof(args));
if (priv->resources[i].lockspace) if (virLockManagerLockDaemonReleaseImpl(client, program,
args.path = priv->resources[i].lockspace; counter++, res) < 0)
args.name = priv->resources[i].name;
args.flags = priv->resources[i].flags;
args.flags &=
~(VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_SHARED |
VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_AUTOCREATE |
VIR_LOCK_SPACE_PROTOCOL_ACQUIRE_RESOURCE_METADATA);
if (virNetClientProgramCall(program,
client,
counter++,
VIR_LOCK_SPACE_PROTOCOL_PROC_RELEASE_RESOURCE,
0, NULL, NULL, NULL,
(xdrproc_t)xdr_virLockSpaceProtocolReleaseResourceArgs, &args,
(xdrproc_t)xdr_void, NULL) < 0)
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册