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:
parent
f32fd1fcb9
commit
d85ceff9c5
@ -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) {
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user