From db2259e9ea5bdf00599db84b4818733d466c8667 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Apr 30 2012 19:31:10 +0000 Subject: sanlock: UNUSED flag for lockspace rem salock_rem_lockspace(UNUSED) will return -EBUSY if any resources exist for the given lockspace, instead of forcibly removing the lockspace by killing any pids using resources within the lockspace, and then removing the lockspace once all resources are gone. Signed-off-by: David Teigland --- diff --git a/src/cmd.c b/src/cmd.c index d5f5c3d..6417df0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -982,6 +982,13 @@ static void cmd_rem_lockspace(struct cmd_args *ca) log_debug("cmd_rem_lockspace %d,%d %.48s flags %x", ca->ci_in, fd, lockspace.name, ca->header.cmd_flags); + if (ca->header.cmd_flags & SANLK_REM_UNUSED) { + if (lockspace_is_used(&lockspace)) { + result = -EBUSY; + goto reply; + } + } + rv = rem_lockspace_start(&lockspace, &space_id); if (rv < 0) { result = rv; diff --git a/src/resource.c b/src/resource.c index 6e6de5d..cef0765 100644 --- a/src/resource.c +++ b/src/resource.c @@ -475,6 +475,30 @@ static struct resource *find_resource(struct token *token, return NULL; } +int lockspace_is_used(struct sanlk_lockspace *ls) +{ + struct resource *r; + + pthread_mutex_lock(&resource_mutex); + list_for_each_entry(r, &resources_held, list) { + if (!strncmp(r->r.lockspace_name, ls->name, NAME_ID_SIZE)) + goto yes; + } + list_for_each_entry(r, &resources_add, list) { + if (!strncmp(r->r.lockspace_name, ls->name, NAME_ID_SIZE)) + goto yes; + } + list_for_each_entry(r, &resources_rem, list) { + if (!strncmp(r->r.lockspace_name, ls->name, NAME_ID_SIZE)) + goto yes; + } + pthread_mutex_unlock(&resource_mutex); + return 0; + yes: + pthread_mutex_unlock(&resource_mutex); + return 1; +} + static void copy_disks(void *dst, void *src, int num_disks) { struct sync_disk *d, *s; diff --git a/src/resource.h b/src/resource.h index 5393728..a75f1a1 100644 --- a/src/resource.h +++ b/src/resource.h @@ -11,6 +11,8 @@ void send_state_resources(int fd); +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); diff --git a/src/sanlock_admin.h b/src/sanlock_admin.h index 64d654c..c5a3a0f 100644 --- a/src/sanlock_admin.h +++ b/src/sanlock_admin.h @@ -15,6 +15,7 @@ /* rem flags */ #define SANLK_REM_ASYNC 0x00000001 +#define SANLK_REM_UNUSED 0x00000002 /* * add_lockspace returns: @@ -40,9 +41,10 @@ int sanlock_inq_lockspace(struct sanlk_lockspace *ls, uint32_t flags); * 0: the lockspace has been removed successfully * -EINPROGRESS: the lockspace is already in the process of being removed * -ENOENT: lockspace not found + * -EBUSY: UNUSED was set and lockspace is being used * * The sanlock daemon will kill any pids using the lockspace when the - * lockspace is removed. + * lockspace is removed (unless UNUSED is set). */ int sanlock_rem_lockspace(struct sanlk_lockspace *ls, uint32_t flags);