1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Fix for bug 677739: removing final exclusive cmirror snapshot,

results in clvmd deadlock

When a logical volume is activated exclusively in a cluster, the
local (non-cluster-aware) target is used.  However, when creating
a snapshot on the exclusive LV, the resulting suspend/resume fails
to load the appropriate device-mapper table - instead loading the
cluster-aware target.

This patch adds an 'exclusive' parameter to the pertinent resume
functions to allow for the right target type to be loaded.
This commit is contained in:
Jonathan Earl Brassow 2011-02-18 00:36:04 +00:00
parent 21849a8587
commit c054e7cc56
6 changed files with 32 additions and 9 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.85 - Version 2.02.85 -
=================================== ===================================
Fix to make resuming exclusive cluster mirror use local target type.
Version 2.02.84 - 9th February 2011 Version 2.02.84 - 9th February 2011
=================================== ===================================

View File

@ -399,7 +399,7 @@ error:
/* Resume the LV if it was active */ /* Resume the LV if it was active */
static int do_resume_lv(char *resource, unsigned char lock_flags) static int do_resume_lv(char *resource, unsigned char lock_flags)
{ {
int oldmode; int oldmode, origin_only, exclusive;
/* Is it open ? */ /* Is it open ? */
oldmode = get_current_lock(resource); oldmode = get_current_lock(resource);
@ -407,8 +407,10 @@ static int do_resume_lv(char *resource, unsigned char lock_flags)
DEBUGLOG("do_resume_lv, lock not already held\n"); DEBUGLOG("do_resume_lv, lock not already held\n");
return 0; /* We don't need to do anything */ return 0; /* We don't need to do anything */
} }
origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0;
exclusive = (oldmode == LCK_EXCL) ? 1 : 0;
if (!lv_resume_if_active(cmd, resource, (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0)) if (!lv_resume_if_active(cmd, resource, origin_only, exclusive))
return EIO; return EIO;
return 0; return 0;

View File

@ -1156,8 +1156,18 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
} }
***********/ ***********/
/*
* _lv_resume
* @cmd
* @lvid_s
* @origin_only
* @exclusive: This parameter only has an affect in cluster-context.
* It forces local target type to be used (instead of
* cluster-aware type).
* @error_if_not_active
*/
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s, static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
unsigned origin_only, unsigned origin_only, unsigned exclusive,
int error_if_not_active) int error_if_not_active)
{ {
struct logical_volume *lv; struct logical_volume *lv;
@ -1189,6 +1199,14 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
goto out; goto out;
} }
/*
* When targets are activated exclusively in a cluster, the
* non-clustered target should be used. This only happens
* if ACTIVATE_EXCL is set in lv->status.
*/
if (exclusive)
lv->status |= ACTIVATE_EXCL;
if (!_lv_activate_lv(lv, origin_only)) if (!_lv_activate_lv(lv, origin_only))
goto_out; goto_out;
@ -1206,14 +1224,15 @@ out:
} }
/* Returns success if the device is not active */ /* Returns success if the device is not active */
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only) int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
unsigned origin_only, unsigned exclusive)
{ {
return _lv_resume(cmd, lvid_s, origin_only, 0); return _lv_resume(cmd, lvid_s, origin_only, exclusive, 0);
} }
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only) int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only)
{ {
return _lv_resume(cmd, lvid_s, origin_only, 1); return _lv_resume(cmd, lvid_s, origin_only, 0, 1);
} }
static int _lv_has_open_snapshots(struct logical_volume *lv) static int _lv_has_open_snapshots(struct logical_volume *lv)

View File

@ -56,7 +56,8 @@ void activation_exit(void);
/* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */ /* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only); int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only); int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only);
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only); int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
unsigned origin_only, unsigned exclusive);
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive); int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive);
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
int exclusive); int exclusive);

View File

@ -293,7 +293,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource,
switch (flags & LCK_TYPE_MASK) { switch (flags & LCK_TYPE_MASK) {
case LCK_UNLOCK: case LCK_UNLOCK:
log_very_verbose("Unlocking LV %s%s", resource, origin_only ? " without snapshots" : ""); log_very_verbose("Unlocking LV %s%s", resource, origin_only ? " without snapshots" : "");
if (!lv_resume_if_active(cmd, resource, origin_only)) if (!lv_resume_if_active(cmd, resource, origin_only, 0))
return 0; return 0;
break; break;
case LCK_NULL: case LCK_NULL:

View File

@ -46,7 +46,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
case LCK_NULL: case LCK_NULL:
return lv_deactivate(cmd, resource); return lv_deactivate(cmd, resource);
case LCK_UNLOCK: case LCK_UNLOCK:
return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0); return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0, 0);
case LCK_READ: case LCK_READ:
return lv_activate_with_filter(cmd, resource, 0); return lv_activate_with_filter(cmd, resource, 0);
case LCK_WRITE: case LCK_WRITE: