1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-30 17:18:21 +03:00

lvmlockd: let vgchange lockstop fail with EBUSY for orphans

vgchange --lockstop will fail with EBUSY if orphan locks in the
lock manager prevent stopping the lockspace.  The orphan locks
can then be adopted and released, and the lockspace then stopped
cleanly.
This commit is contained in:
David Teigland 2024-06-26 12:06:02 -05:00
parent f32fd1fcb9
commit d85ceff9c5
2 changed files with 42 additions and 5 deletions

View File

@ -2488,6 +2488,7 @@ static void *lockspace_thread_main(void *arg_in)
struct list_head tmp_act;
struct list_head act_close;
char tmp_name[MAX_NAME+5];
int fail_stop_busy;
int free_vg = 0;
int drop_vg = 0;
int error = 0;
@ -2498,6 +2499,7 @@ static void *lockspace_thread_main(void *arg_in)
int rv;
INIT_LIST_HEAD(&act_close);
INIT_LIST_HEAD(&tmp_act);
/* first action may be client add */
pthread_mutex_lock(&ls->mutex);
@ -2566,6 +2568,8 @@ static void *lockspace_thread_main(void *arg_in)
if (error)
goto out_act;
restart:
while (1) {
pthread_mutex_lock(&ls->mutex);
while (!ls->thread_work) {
@ -2818,17 +2822,48 @@ out_rem:
* Leave the lockspace.
*/
rv = lm_rem_lockspace(ls, NULL, free_vg);
fail_stop_busy = 0;
log_debug("S %s rem_lockspace done %d", ls->name, rv);
rv = lm_rem_lockspace(ls, NULL, free_vg);
if (rv < 0) {
pthread_mutex_lock(&ls->mutex);
list_for_each_entry_safe(act, safe, &ls->actions, list) {
/*
* If there's a stop action then there's a path to return an error,
* and in the case of EBUSY presumably there's a chance to redo it.
*/
if ((act->op == LD_OP_STOP) && (rv == -EBUSY)) {
log_debug("S %s rem_lockspace for stop error %d", ls->name, rv);
act->result = -EBUSY;
list_del(&act->list);
list_add_tail(&act->list, &tmp_act);
ls->thread_stop = 0;
fail_stop_busy = 1;
break;
}
}
pthread_mutex_unlock(&ls->mutex);
if (fail_stop_busy) {
pthread_mutex_lock(&client_mutex);
list_del(&act->list);
list_add_tail(&act->list, &client_results);
pthread_cond_signal(&client_cond);
pthread_mutex_unlock(&client_mutex);
goto restart;
}
}
if (rv < 0)
log_debug("S %s rem_lockspace error %d", ls->name, rv);
else
log_debug("S %s rem_lockspace done", ls->name);
out_act:
/*
* Move remaining actions to results; this will usually (always?)
* be only the stop action.
*/
INIT_LIST_HEAD(&tmp_act);
pthread_mutex_lock(&ls->mutex);
list_for_each_entry_safe(act, safe, &ls->actions, list) {
if (act->op == LD_OP_FREE) {

View File

@ -1563,8 +1563,10 @@ int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
goto out;
rv = sanlock_rem_lockspace(&lms->ss, 0);
if (rv < 0)
if (rv < 0) {
log_error("S %s rem_lockspace_san error %d", ls->name, rv);
return rv;
}
if (free_vg) {
/*