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@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
sanlock-devel@lists.fedorahosted.org