src/cmd.c | 6 ++++--
src/paxos_lease.c | 9 +++++++++
src/paxos_lease.h | 1 +
src/resource.c | 10 ++++++++--
src/sanlock_resource.h | 6 ++++++
src/sanlock_rv.h | 1 +
6 files changed, 29 insertions(+), 4 deletions(-)
New commits:
commit badc556ff4f0c60b7e82af25fe5d0f362cc41ccb
Author: David Teigland <teigland(a)redhat.com>
Date: Wed Oct 14 12:02:33 2015 -0500
sanlock: add acquire flag to avoid waiting
When a paxos lease is requested that was held by
a failed, but not yet expired host, the acquire
routine waits for the lease to expire before
returning. Add a flag to avoid waiting for the
expiration for programs that want to just retry
instead of block in sanlock_acquire().
diff --git a/src/cmd.c b/src/cmd.c
index 93387c0..64f7f00 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -126,6 +126,7 @@ static const char *acquire_error_str(int error)
case SANLK_ACQUIRE_IDLIVE:
case SANLK_ACQUIRE_OWNED:
case SANLK_ACQUIRE_OTHER:
+ case SANLK_ACQUIRE_OWNED_RETRY:
return "lease owned by other host";
case SANLK_ACQUIRE_SHRETRY:
@@ -181,8 +182,8 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca)
new_tokens_count = ca->header.data;
- log_debug("cmd_acquire %d,%d,%d ci_in %d fd %d count %d",
- cl_ci, cl_fd, cl_pid, ca->ci_in, fd, new_tokens_count);
+ log_debug("cmd_acquire %d,%d,%d ci_in %d fd %d count %d flags %x",
+ cl_ci, cl_fd, cl_pid, ca->ci_in, fd, new_tokens_count, ca->header.cmd_flags);
if (new_tokens_count > SANLK_MAX_RESOURCES) {
log_error("cmd_acquire %d,%d,%d new %d max %d",
@@ -396,6 +397,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca)
case SANLK_ACQUIRE_IDLIVE:
case SANLK_ACQUIRE_OWNED:
case SANLK_ACQUIRE_OTHER:
+ case SANLK_ACQUIRE_OWNED_RETRY:
lvl = com.quiet_fail ? LOG_DEBUG : LOG_ERR;
break;
default:
diff --git a/src/paxos_lease.c b/src/paxos_lease.c
index df60ee6..eae2fd9 100644
--- a/src/paxos_lease.c
+++ b/src/paxos_lease.c
@@ -1661,6 +1661,15 @@ int paxos_lease_acquire(struct task *task,
goto run;
}
+ if (flags & PAXOS_ACQUIRE_OWNER_NOWAIT) {
+ log_token(token, "paxos_acquire owner %llu %llu %llu no wait",
+ (unsigned long long)cur_leader.owner_id,
+ (unsigned long long)cur_leader.owner_generation,
+ (unsigned long long)cur_leader.timestamp);
+ error = SANLK_ACQUIRE_OWNED_RETRY;
+ goto out;
+ }
+
skip_live_check:
/* TODO: test with sleep(2) here */
sleep(1);
diff --git a/src/paxos_lease.h b/src/paxos_lease.h
index de5e095..d66a210 100644
--- a/src/paxos_lease.h
+++ b/src/paxos_lease.h
@@ -12,6 +12,7 @@
#define PAXOS_ACQUIRE_FORCE 0x00000001
#define PAXOS_ACQUIRE_QUIET_FAIL 0x00000002
#define PAXOS_ACQUIRE_SHARED 0x00000004
+#define PAXOS_ACQUIRE_OWNER_NOWAIT 0x00000008
uint32_t leader_checksum(struct leader_record *lr);
diff --git a/src/resource.c b/src/resource.c
index 15d88a9..b378f62 100644
--- a/src/resource.c
+++ b/src/resource.c
@@ -569,7 +569,7 @@ int res_get_lvb(struct sanlk_resource *res, char **lvb_out, int *lvblen)
static int acquire_disk(struct task *task, struct token *token,
uint64_t acquire_lver, int new_num_hosts,
- struct leader_record *leader)
+ int owner_nowait, struct leader_record *leader)
{
struct leader_record leader_tmp;
int rv;
@@ -581,6 +581,9 @@ static int acquire_disk(struct task *task, struct token *token,
if (token->acquire_flags & SANLK_RES_SHARED)
flags |= PAXOS_ACQUIRE_SHARED;
+ if (owner_nowait)
+ flags |= PAXOS_ACQUIRE_OWNER_NOWAIT;
+
memset(&leader_tmp, 0, sizeof(leader_tmp));
rv = paxos_lease_acquire(task, token, flags, &leader_tmp, acquire_lver,
@@ -1320,6 +1323,7 @@ int acquire_token(struct task *task, struct token *token, uint32_t cmd_flags,
int live_count = 0;
int allow_orphan = 0;
int only_orphan = 0;
+ int owner_nowait = 0;
int rv;
if (token->acquire_flags & SANLK_RES_LVER)
@@ -1331,6 +1335,8 @@ int acquire_token(struct task *task, struct token *token, uint32_t cmd_flags,
allow_orphan = 1;
if (cmd_flags & SANLK_ACQUIRE_ORPHAN_ONLY)
only_orphan = 1;
+ if (cmd_flags & SANLK_ACQUIRE_OWNER_NOWAIT)
+ owner_nowait = 1;
pthread_mutex_lock(&resource_mutex);
@@ -1493,7 +1499,7 @@ int acquire_token(struct task *task, struct token *token, uint32_t cmd_flags,
retry:
memset(&leader, 0, sizeof(struct leader_record));
- rv = acquire_disk(task, token, acquire_lver, new_num_hosts, &leader);
+ rv = acquire_disk(task, token, acquire_lver, new_num_hosts, owner_nowait, &leader);
if (rv == SANLK_ACQUIRE_IDLIVE || rv == SANLK_ACQUIRE_OWNED || rv == SANLK_ACQUIRE_OTHER) {
/*
diff --git a/src/sanlock_resource.h b/src/sanlock_resource.h
index 624a7d0..d412482 100644
--- a/src/sanlock_resource.h
+++ b/src/sanlock_resource.h
@@ -43,11 +43,17 @@
* If the lock already exists as an orphan,
* then acquire it. Otherwise, do not acquire
* a lock at all and return -ENOENT.
+ *
+ * SANLK_ACQUIRE_OWNER_NOWAIT
+ * If the lock cannot be granted immediately
+ * because the owner's lease needs to time out, do
+ * not wait, but return -SANLK_ACQUIRE_OWNED_RETRY.
*/
#define SANLK_ACQUIRE_LVB 0x00000001
#define SANLK_ACQUIRE_ORPHAN 0x00000002
#define SANLK_ACQUIRE_ORPHAN_ONLY 0x00000004
+#define SANLK_ACQUIRE_OWNER_NOWAIT 0x00000008
/*
* release flags
diff --git a/src/sanlock_rv.h b/src/sanlock_rv.h
index 686603a..bafef2b 100644
--- a/src/sanlock_rv.h
+++ b/src/sanlock_rv.h
@@ -47,6 +47,7 @@
#define SANLK_ACQUIRE_OWNED -244
#define SANLK_ACQUIRE_OTHER -245
#define SANLK_ACQUIRE_SHRETRY -246
+#define SANLK_ACQUIRE_OWNED_RETRY -247
#define SANLK_RELEASE_LVER -250
#define SANLK_RELEASE_OWNER -251