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(a)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(a)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);