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:
parent
21849a8587
commit
c054e7cc56
@ -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
|
||||||
===================================
|
===================================
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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:
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user