From d19c14300452be5fcfc9036cc71c527422c3a424 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Sep 13 2012 20:07:00 +0000 Subject: sanlock: request force_mode 2 is SIGUSR1 request force_mode 2 causes SIGUSR1 to be sent to the pid holding the requested resource. Signed-off-by: David Teigland --- diff --git a/src/resource.c b/src/resource.c index 2385da8..1aa7d6e 100644 --- a/src/resource.c +++ b/src/resource.c @@ -818,7 +818,7 @@ static int examine_token(struct task *task, struct token *token, return rv; } -static void do_req_kill_pid(struct token *tt, int pid) +static void do_request(struct token *tt, int pid, uint32_t force_mode) { struct helper_msg hm; struct resource *r; @@ -834,28 +834,47 @@ static void do_req_kill_pid(struct token *tt, int pid) pthread_mutex_unlock(&resource_mutex); if (!found) { - log_error("req pid %d %.48s:%.48s not found", + log_error("do_request pid %d %.48s:%.48s not found", pid, tt->r.lockspace_name, tt->r.name); return; } - log_debug("do_req_kill_pid %d flags %x %.48s:%.48s", + log_debug("do_request %d flags %x %.48s:%.48s", pid, flags, tt->r.lockspace_name, tt->r.name); if (helper_kill_fd == -1) { - log_error("do_req_kill_pid %d no helper fd", pid); + log_error("do_request %d no helper fd", pid); return; } - /* TODO: handle kill via runpath? or select signal? escalate? */ - memset(&hm, 0, sizeof(hm)); - hm.type = HELPER_MSG_KILLPID; - hm.pid = pid; - hm.sig = SIGKILL; - if (flags & R_RESTRICT_SIGKILL) - hm.sig = SIGTERM; + if (force_mode == SANLK_REQ_KILL_PID) { + hm.type = HELPER_MSG_KILLPID; + hm.pid = pid; + hm.sig = (flags & R_RESTRICT_SIGKILL) ? SIGTERM : SIGKILL; + } else if (force_mode == SANLK_REQ_SIGUSR1) { + hm.type = HELPER_MSG_KILLPID; + hm.pid = pid; + hm.sig = SIGUSR1; + } 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)); @@ -863,7 +882,7 @@ static void do_req_kill_pid(struct token *tt, int pid) goto retry; if (rv == -1) - log_error("do_req_kill_pid %d helper write error %d", + log_error("do_request %d helper write error %d", pid, errno); } @@ -957,8 +976,8 @@ static void resource_thread_examine(struct task *task, struct token *tt, int pid return; } - if (req.force_mode == SANLK_REQ_KILL_PID) { - do_req_kill_pid(tt, pid); + if (req.force_mode) { + do_request(tt, pid, req.force_mode); } else { log_error("req force_mode %u unknown", req.force_mode); } diff --git a/src/sanlock_resource.h b/src/sanlock_resource.h index dbc6e1f..5215797 100644 --- a/src/sanlock_resource.h +++ b/src/sanlock_resource.h @@ -31,8 +31,15 @@ /* release flags */ #define SANLK_REL_ALL 0x00000001 -/* request flags */ +/* + * request force_mode + * 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 + */ + #define SANLK_REQ_KILL_PID 0x00000001 +#define SANLK_REQ_SIGUSR1 0x00000002 int sanlock_register(void);