mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Attempt to improve clustered 'lvchange -aey' behaviour to try local node before
remote nodes and address some existing anomalies.
This commit is contained in:
parent
fc0f2d5031
commit
f5bfc8b10d
@ -1,5 +1,7 @@
|
||||
Version 2.02.89 -
|
||||
==================================
|
||||
Change exclusive LV activation logic to try local node before remote nodes.
|
||||
Add CLVMD_FLAG_REMOTE to skip processing on local node.
|
||||
Prompt if request is made to remove a snapshot whose "Merge failed".
|
||||
Allow removal of an invalid snapshot that was to be merged on next activation.
|
||||
Don't allow a user to merge an invalid snapshot.
|
||||
|
@ -930,6 +930,7 @@ static int _lv_is_active(struct logical_volume *lv,
|
||||
l = 1;
|
||||
|
||||
if (!vg_is_clustered(lv->vg)) {
|
||||
if (l)
|
||||
e = 1; /* exclusive by definition */
|
||||
goto out;
|
||||
}
|
||||
@ -950,21 +951,15 @@ static int _lv_is_active(struct logical_volume *lv,
|
||||
* New users of this function who specifically ask for 'exclusive'
|
||||
* will be given an error message.
|
||||
*/
|
||||
if (l) {
|
||||
if (exclusive)
|
||||
log_error("Unable to determine exclusivity of %s",
|
||||
lv->name);
|
||||
goto out;
|
||||
}
|
||||
log_error("Unable to determine exclusivity of %s", lv->name);
|
||||
|
||||
e = 0;
|
||||
|
||||
/*
|
||||
* We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
|
||||
* but it's unreliable.
|
||||
*/
|
||||
|
||||
/* FIXME: Is this fallback alright? */
|
||||
if (activate_lv_excl(lv->vg->cmd, lv)) {
|
||||
if (!deactivate_lv(lv->vg->cmd, lv))
|
||||
stack;
|
||||
/* FIXME: locally & exclusive are undefined. */
|
||||
return 0;
|
||||
}
|
||||
/* FIXME: Check exclusive value here. */
|
||||
out:
|
||||
if (locally)
|
||||
*locally = l;
|
||||
|
@ -178,21 +178,19 @@ static void _build_header(struct clvm_header *head, int clvmd_cmd, const char *n
|
||||
head->clientid = 0;
|
||||
head->arglen = len;
|
||||
|
||||
if (node) {
|
||||
/*
|
||||
* Allow a couple of special node names:
|
||||
* "*" for all nodes,
|
||||
* "." for the local node only
|
||||
* Handle special node names.
|
||||
*/
|
||||
if (strcmp(node, "*") == 0) {
|
||||
if (!node || !strcmp(node, NODE_ALL))
|
||||
head->node[0] = '\0';
|
||||
} else if (strcmp(node, ".") == 0) {
|
||||
else if (!strcmp(node, NODE_LOCAL)) {
|
||||
head->node[0] = '\0';
|
||||
head->flags = CLVMD_FLAG_LOCAL;
|
||||
} else if (!strcmp(node, NODE_REMOTE)) {
|
||||
head->node[0] = '\0';
|
||||
head->flags = CLVMD_FLAG_REMOTE;
|
||||
} else
|
||||
strcpy(head->node, node);
|
||||
} else
|
||||
head->node[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
@ -357,9 +355,6 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
|
||||
* so we only need to do them on the local node because all
|
||||
* locks are cluster-wide.
|
||||
*
|
||||
* Also, if the lock is exclusive it makes no sense to try to
|
||||
* acquire it on all nodes, so just do that on the local node too.
|
||||
*
|
||||
* P_ locks /do/ get distributed across the cluster because they might
|
||||
* have side-effects.
|
||||
*
|
||||
@ -367,13 +362,15 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
|
||||
*/
|
||||
if (clvmd_cmd == CLVMD_CMD_SYNC_NAMES) {
|
||||
if (flags & LCK_LOCAL)
|
||||
node = ".";
|
||||
node = NODE_LOCAL;
|
||||
} else if (clvmd_cmd != CLVMD_CMD_VG_BACKUP) {
|
||||
if (strncmp(name, "P_", 2) &&
|
||||
(clvmd_cmd == CLVMD_CMD_LOCK_VG ||
|
||||
(flags & LCK_LOCAL) ||
|
||||
!(flags & LCK_CLUSTER_VG)))
|
||||
node = ".";
|
||||
node = NODE_LOCAL;
|
||||
else if (flags & LCK_REMOTE)
|
||||
node = NODE_REMOTE;
|
||||
}
|
||||
|
||||
status = _cluster_request(clvmd_cmd, node, args, len,
|
||||
@ -493,12 +490,13 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
|
||||
log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
|
||||
lock_type, lock_scope,
|
||||
flags & LCK_NONBLOCK ? "|NONBLOCK" : "",
|
||||
flags & LCK_HOLD ? "|HOLD" : "",
|
||||
flags & LCK_LOCAL ? "|LOCAL" : "",
|
||||
flags & LCK_CLUSTER_VG ? "|CLUSTER" : "",
|
||||
flags & LCK_LOCAL ? "|LOCAL" : "",
|
||||
flags & LCK_REMOTE ? "|REMOTE" : "",
|
||||
flags & LCK_CACHE ? "|CACHE" : "",
|
||||
flags & LCK_ORIGIN_ONLY ? "|ORIGIN_ONLY" : "",
|
||||
flags & LCK_REVERT ? "|REVERT" : "",
|
||||
|
@ -539,6 +539,33 @@ int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* First try to activate exclusively locally.
|
||||
* Then if the VG is clustered and the LV is not yet active (e.g. due to
|
||||
* an activation filter) try activating on remote nodes.
|
||||
*/
|
||||
int activate_lv_excl(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
/* Non-clustered VGs are only activated locally. */
|
||||
if (!vg_is_clustered(lv->vg))
|
||||
return activate_lv_excl_local(cmd, lv);
|
||||
|
||||
if (lv_is_active_exclusive(lv))
|
||||
return 1;
|
||||
|
||||
if (!activate_lv_excl_local(cmd, lv))
|
||||
return_0;
|
||||
|
||||
if (lv_is_active_exclusive(lv))
|
||||
return 1;
|
||||
|
||||
/* FIXME Deal with error return codes. */
|
||||
if (activate_lv_excl_remote(cmd, lv))
|
||||
stack;
|
||||
|
||||
return lv_is_active_exclusive(lv);
|
||||
}
|
||||
|
||||
/* Lock a list of LVs */
|
||||
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
|
||||
{
|
||||
|
@ -97,6 +97,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
#define LCK_CLUSTER_VG 0x00000080U /* VG is clustered */
|
||||
|
||||
#define LCK_LOCAL 0x00000040U /* Don't propagate to other nodes */
|
||||
#define LCK_REMOTE 0x00000800U /* Propagate to remote nodes only */
|
||||
#define LCK_CACHE 0x00000100U /* Operation on cache only using P_ lock */
|
||||
#define LCK_ORIGIN_ONLY 0x00000200U /* Operation should bypass any snapshots */
|
||||
#define LCK_REVERT 0x00000400U /* Revert any incomplete change */
|
||||
@ -176,9 +177,16 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
|
||||
#define suspend_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
|
||||
#define suspend_lv_origin(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD | LCK_ORIGIN_ONLY)
|
||||
#define deactivate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
|
||||
|
||||
#define activate_lv(cmd, lv) lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
|
||||
#define activate_lv_excl(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
|
||||
#define activate_lv_excl_local(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_LOCAL)
|
||||
#define activate_lv_excl_remote(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_REMOTE)
|
||||
|
||||
struct logical_volume;
|
||||
int activate_lv_excl(struct cmd_context *cmd, struct logical_volume *lv);
|
||||
|
||||
#define activate_lv_local(cmd, lv) \
|
||||
lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
|
||||
#define deactivate_lv_local(cmd, lv) \
|
||||
|
Loading…
Reference in New Issue
Block a user