src/cmd.c | 7 ++++++- src/resource.c | 35 +++++++++++++++++++++-------------- src/resource.h | 3 ++- src/sanlock.8 | 3 +++ src/sanlock_internal.h | 2 ++ src/sanlock_resource.h | 2 ++ 6 files changed, 36 insertions(+), 16 deletions(-)
New commits: commit 0ea5e61b9e73459a75ccabfc248359405b2a6b3f Author: David Teigland teigland@redhat.com Date: Tue Apr 9 14:41:25 2013 -0500
sanlock: add request killpath
sanlock_request with force_mode 3 "REQ_KILLPATH" will cause killpath to be run against the pid.
Signed-off-by: David Teigland teigland@redhat.com
diff --git a/src/cmd.c b/src/cmd.c index 6f9310f..19416be 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -126,6 +126,8 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca) struct sanlk_resource res; struct sanlk_options opt; struct space_info spi; + char killpath[SANLK_HELPER_PATH_LEN]; + char killargs[SANLK_HELPER_ARGS_LEN]; char *opt_str; int token_len, disks_len; int fd, rv, i, j, empty_slots, lvl; @@ -165,6 +167,9 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca) if (!cl->tokens[i]) empty_slots++; } + + memcpy(killpath, cl->killpath, SANLK_HELPER_PATH_LEN); + memcpy(killargs, cl->killargs, SANLK_HELPER_ARGS_LEN); pthread_mutex_unlock(&cl->mutex);
if (empty_slots < new_tokens_count) { @@ -320,7 +325,7 @@ static void cmd_acquire(struct task *task, struct cmd_args *ca) for (i = 0; i < new_tokens_count; i++) { token = new_tokens[i];
- rv = acquire_token(task, token); + rv = acquire_token(task, token, killpath, killargs); if (rv < 0) { switch (rv) { case -EEXIST: diff --git a/src/resource.c b/src/resource.c index 1aa7d6e..2a60a16 100644 --- a/src/resource.c +++ b/src/resource.c @@ -569,7 +569,8 @@ static struct resource *new_resource(struct token *token) return r; }
-int acquire_token(struct task *task, struct token *token) +int acquire_token(struct task *task, struct token *token, + char *killpath, char *killargs) { struct leader_record leader; struct resource *r; @@ -626,6 +627,8 @@ int acquire_token(struct task *task, struct token *token) return -ENOMEM; }
+ memcpy(r->killpath, killpath, SANLK_HELPER_PATH_LEN); + memcpy(r->killargs, killargs, SANLK_HELPER_ARGS_LEN); list_add(&token->list, &r->tokens); list_add(&r->list, &resources_add); token->resource = r; @@ -820,6 +823,8 @@ static int examine_token(struct task *task, struct token *token,
static void do_request(struct token *tt, int pid, uint32_t force_mode) { + char killpath[SANLK_HELPER_PATH_LEN]; + char killargs[SANLK_HELPER_ARGS_LEN]; struct helper_msg hm; struct resource *r; uint32_t flags; @@ -830,6 +835,8 @@ static void do_request(struct token *tt, int pid, uint32_t force_mode) if (r && r->pid == pid) { found = 1; flags = r->flags; + memcpy(killpath, r->killpath, SANLK_HELPER_PATH_LEN); + memcpy(killargs, r->killargs, SANLK_HELPER_ARGS_LEN); } pthread_mutex_unlock(&resource_mutex);
@@ -857,24 +864,24 @@ static void do_request(struct token *tt, int pid, uint32_t force_mode) hm.type = HELPER_MSG_KILLPID; hm.pid = pid; hm.sig = SIGUSR1; + } else if (force_mode == SANLK_REQ_KILLPATH) { + if (!killpath[0]) { + log_error("do_request %d force_mode %d no killpath", + pid, force_mode); + return; + } + /* there's no thread locking for the clients array so + we can't go searching for killpath/killargs for this + pid from here, so we copy the info into struct + resource so we can use it here. */ + hm.type = HELPER_MSG_RUNPATH; + memcpy(hm.path, killpath, SANLK_HELPER_PATH_LEN); + memcpy(hm.args, killargs, SANLK_HELPER_ARGS_LEN); } else { log_error("do_request %d unknown force_mode %d", pid, force_mode); return; } -#if 0 - /* TODO: this is difficult because we can't dig into the clients - array to get the killpath/killargs; the clients array is not - locked and can only be accessed by the main thread. */ - - else if (force_mode == SANLK_REQ_KILLPATH) { - hm.type = HELPER_MSG_RUNPATH; - memcpy(hm.path, cl->killpath, SANLK_HELPER_PATH_LEN); - memcpy(hm.args, cl->killargs, SANLK_HELPER_ARGS_LEN); - if (cl->flags & CL_KILLPATH_PID) - hm.pid = pid; - } -#endif
retry: rv = write(helper_kill_fd, &hm, sizeof(hm)); diff --git a/src/resource.h b/src/resource.h index a75f1a1..b3e99a2 100644 --- a/src/resource.h +++ b/src/resource.h @@ -15,7 +15,8 @@ int lockspace_is_used(struct sanlk_lockspace *ls);
void check_mode_block(struct token *token, int q, char *dblock);
-int acquire_token(struct task *task, struct token *token); +int acquire_token(struct task *task, struct token *token, + char *killpath, char *killargs); int release_token(struct task *task, struct token *token); void release_token_async(struct token *token);
diff --git a/src/sanlock.8 b/src/sanlock.8 index dca5db8..a23e54a 100644 --- a/src/sanlock.8 +++ b/src/sanlock.8 @@ -522,6 +522,9 @@ is restricted.)
\fB2\fP (SIGUSR1): send SIGUSR1 to the process holding the resource lease.
+\fB3\fP (KILLPATH): run the program configured by sanlock_killpath +against the process holding the resource lease. + .SS Graceful recovery
When a lockspace host_id cannot be renewed for a specific period of time, diff --git a/src/sanlock_internal.h b/src/sanlock_internal.h index 6deef0e..34ce260 100644 --- a/src/sanlock_internal.h +++ b/src/sanlock_internal.h @@ -109,6 +109,8 @@ struct resource { int pid; /* copied from token when ex */ uint32_t flags; uint32_t release_token_id; /* copy to temp token (tt) for log messages */ + char killpath[SANLK_HELPER_PATH_LEN]; /* copied from client */ + char killargs[SANLK_HELPER_ARGS_LEN]; /* copied from client */ struct leader_record leader; /* copy of last leader_record we wrote */ struct sanlk_resource r; }; diff --git a/src/sanlock_resource.h b/src/sanlock_resource.h index cf2a798..f68fc3e 100644 --- a/src/sanlock_resource.h +++ b/src/sanlock_resource.h @@ -36,10 +36,12 @@ * SANLK_REQ_KILL_PID: send SIGKILL to pid holding the resource, or * SIGTERM if SIGKILL is restricted * SANLK_REQ_SIGUSR1: send SIGUSR1 to pid holding the resource + * SANLK_REQ_KILLPATH: run configured killpath against the pid */
#define SANLK_REQ_KILL_PID 0x00000001 #define SANLK_REQ_SIGUSR1 0x00000002 +#define SANLK_REQ_KILLPATH 0x00000003
int sanlock_register(void);
----- Original Message -----
From: "David Teigland" teigland@fedoraproject.org To: sanlock-devel@lists.fedorahosted.org Sent: Tuesday, April 9, 2013 9:55:08 PM Subject: src/cmd.c src/resource.c src/resource.h src/sanlock.8 src/sanlock_internal.h src/sanlock_resource.h
src/cmd.c | 7 ++++++- src/resource.c | 35 +++++++++++++++++++++-------------- src/resource.h | 3 ++- src/sanlock.8 | 3 +++ src/sanlock_internal.h | 2 ++ src/sanlock_resource.h | 2 ++ 6 files changed, 36 insertions(+), 16 deletions(-)
New commits: commit 0ea5e61b9e73459a75ccabfc248359405b2a6b3f Author: David Teigland teigland@redhat.com Date: Tue Apr 9 14:41:25 2013 -0500
sanlock: add request killpath sanlock_request with force_mode 3 "REQ_KILLPATH" will cause killpath to be run against the pid.
I have the feeling that this shouldn't be separated from SANLK_REQ_SIGUSR1. Let's say that the host that submits the request doesn't know if there's a killpath defined on the target.
I think that there are only two kind of requests:
1. graceful (either with SIGUSR1 or eventually with killpath when it's defined on the target) 2. forced (SIGKILL)
Now this means that when one host receives the SANLK_REQ_SIGUSR1 request should either handle it with killpath or SIGUSR1 (if killpath is not defined). The SANLK_REQ_SIGUSR1 name might be misleading and therefore I suggest to add a new macro called SANLK_REQ_GRACEFUL which is exactly == SANLK_REQ_SIGUSR1. The SANLK_REQ_SIGUSR1 can be obsoleted in the future but for now we should keep it for backward compatibility.
sanlock-devel@lists.fedorahosted.org