master - lvmlockd: detect when dlm lvb is invalidated
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=45222d29ac43b7...
Commit: 45222d29ac43b7354b275e9de61972eea4637a3f
Parent: 436ec3221eb5c429b2a0a01c95e962cbf1706e65
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Aug 26 14:55:27 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Aug 26 15:50:18 2015 -0500
lvmlockd: detect when dlm lvb is invalidated
The lvb content can be lost during dlm recovery,
and we need to detect when this happens to revalidate.
---
daemons/lvmlockd/lvmlockd-core.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 3d41bd2..ac2d224 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -1057,7 +1057,18 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
/* lm_lock() reads new r_version */
- if ((r_version > r->version) || (!r->version && !r->version_zero_valid)) {
+ if ((r_version != r->version) || (!r->version && !r->version_zero_valid)) {
+
+ /*
+ * r_version only increases, so if it goes down, it means the
+ * dlm lvb became invalid (happens during recovery if the
+ * resource master leaves).
+ */
+ if (r_version < r->version) {
+ log_debug("S %s R %s res_lock lvb invalid r_version %u prev %u",
+ ls->name, r->name, r_version, r->version);
+ }
+
/*
* New r_version of the lock: means that another
* host has changed data protected by this lock
8 years, 7 months
master - lvmlockd: rescan lockd VG in two new cases
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=436ec3221eb5c4...
Commit: 436ec3221eb5c429b2a0a01c95e962cbf1706e65
Parent: c58f4892f606aafb3828c8c0d2738ed8b6407577
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Aug 26 14:06:39 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Aug 26 15:49:55 2015 -0500
lvmlockd: rescan lockd VG in two new cases
Previously, a command would only rescan a lockd VG
when lvmetad returned the "vg_invalid" flag indicating
that the cached copy was invalid (which is done by
lvmlockd.) This is still the only usual reason for
rescanning a lockd VG, but two new special cases are
added where we also do the rescan:
. When the --shared option is used to display lockd VGs
from hosts not using lvmlockd. This is the same case
as using --foreign to display foreign VGs, but --shared
was missing the corresponding bits to rescan the VGs.
. When a lockd VG is allowed to be read for displaying
after failing to acquire the lock from lvmlockd. In
this case, the usual mechanism for validating the
cache is missed, so assume the cache would have been
invalidated. (This had been a previous todo item
that was lost during other cleanup.)
These were long-standing todos that were lost track of.
---
lib/cache/lvmetad.c | 45 ++++++++++++++++++++++++++++++++++++++++++-
lib/commands/toolcontext.h | 1 +
lib/locking/lvmlockd.c | 35 ++++++++++++++++++++++++++++++++-
3 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 856b30f..b2e2f55 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -434,6 +434,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
struct format_type *fmt;
struct dm_config_node *pvcn;
struct pv_list *pvl;
+ int rescan = 0;
if (!lvmetad_active())
return NULL;
@@ -493,15 +494,55 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
goto_out;
/*
+ * Read the VG from disk, ignoring the lvmetad copy in these
+ * cases:
+ *
+ * 1. The host is not using lvmlockd, but is reading lockd VGs
+ * using the --shared option. The shared option is meant to
+ * let hosts not running lvmlockd look at lockd VGs, like the
+ * foreign option allows hosts to look at foreign VGs. When
+ * --foreign is used, the code forces a rescan since the local
+ * lvmetad cache of foreign VGs is likely stale. Similarly,
+ * for --shared, have the code reading the shared VGs below
+ * not use the cached copy from lvmetad but to rescan the VG.
+ *
+ * 2. The host failed to acquire the VG lock from lvmlockd for
+ * the lockd VG. In this case, the usual mechanisms for
+ * updating the lvmetad copy of the VG have been missed. Since
+ * we don't know if the cached copy is valid, assume it's not.
+ *
+ * 3. lvmetad has returned the "vg_invalid" flag, which is the
+ * usual mechanism used by lvmlockd/lvmetad to cause a host to
+ * reread a VG from disk that has been modified from another
+ * host.
+ */
+
+ if (is_lockd_type(vg->lock_type) && cmd->include_shared_vgs) {
+ log_debug_lvmetad("Rescan VG %s because including shared", vgname);
+ rescan = 1;
+ } else if (is_lockd_type(vg->lock_type) && cmd->lockd_vg_rescan) {
+ log_debug_lvmetad("Rescan VG %s because no lvmlockd lock is held", vgname);
+ rescan = 1;
+ } else if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
+ log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ rescan = 1;
+ }
+
+ /*
* locking may have detected a newer vg version and
* invalidated the cached vg.
*/
- if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
+ if (rescan) {
log_debug_lvmetad("Update invalid lvmetad cache for VG %s", vgname);
vg2 = lvmetad_pvscan_vg(cmd, vg);
release_vg(vg);
vg = vg2;
- fid = vg->fid;
+ if (!vg) {
+ log_debug_lvmetad("VG %s from lvmetad not found during rescan.", vgname);
+ fid = NULL;
+ goto out;
+ } else
+ fid = vg->fid;
}
dm_list_iterate_items(pvl, &vg->pvs) {
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 0440163..cd55348 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -134,6 +134,7 @@ struct cmd_context {
unsigned lockd_vg_disable:1;
unsigned lockd_lv_disable:1;
unsigned lockd_gl_removed:1;
+ unsigned lockd_vg_rescan:1;
unsigned lockd_vg_default_sh:1;
unsigned lockd_vg_enforce_sh:1;
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index e647c96..45159d2 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -1323,6 +1323,9 @@ int lockd_gl_create(struct cmd_context *cmd, const char *def_mode, const char *v
return 0;
}
+ /* --shared with vgcreate does not mean include_shared_vgs */
+ cmd->include_shared_vgs = 0;
+
lvmetad_validate_global_cache(cmd, 1);
return 1;
@@ -1631,8 +1634,31 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
int result;
int ret;
+ /*
+ * The result of the VG lock request is saved in lockd_state to be
+ * passed into vg_read where the lock result is needed once we
+ * know if this is a local VG or lockd VG.
+ */
*lockd_state = 0;
+ /*
+ * Use of lockd_vg_rescan.
+ *
+ * This is the VG equivalent of using lvmetad_validate_global_cache()
+ * for the global lock (after failing to acquire the global lock). If
+ * we fail to acquire the VG lock from lvmlockd, then the lvmlockd
+ * mechanism has been missed that would have updated the cached lvmetad
+ * copy of the VG. So, set lockd_vg_rescan to tell the VG reading code
+ * to treat the lvmetad copy as if the invalid flag had been returned.
+ * i.e. If a lockd VG is read without a lock, ignore the lvmetad copy
+ * and read it from disk since we don't know if the cache is stale.
+ *
+ * Because lvmlockd requests return an error for local VGs, this will
+ * be set for local VGs, but it ends up being ignored once the VG is
+ * read and found to be a local VG.
+ */
+ cmd->lockd_vg_rescan = 0;
+
if (!is_real_vg(vg_name))
return 1;
@@ -1703,6 +1729,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
*/
if (!_use_lvmlockd) {
*lockd_state |= LDST_FAIL_REQUEST;
+ cmd->lockd_vg_rescan = 1;
return 1;
}
@@ -1719,6 +1746,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
* this error for local VGs, but we do care for lockd VGs.
*/
*lockd_state |= LDST_FAIL_REQUEST;
+ cmd->lockd_vg_rescan = 1;
return 1;
}
@@ -1737,12 +1765,15 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
break;
case -ENOLS:
*lockd_state |= LDST_FAIL_NOLS;
+ cmd->lockd_vg_rescan = 1;
break;
case -ESTARTING:
*lockd_state |= LDST_FAIL_STARTING;
+ cmd->lockd_vg_rescan = 1;
break;
default:
*lockd_state |= LDST_FAIL_OTHER;
+ cmd->lockd_vg_rescan = 1;
}
/*
@@ -1758,8 +1789,8 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
* since a sanlock VG must be stopped everywhere before it's removed.
*/
if (result == -EREMOVED) {
- log_error("VG %s lock is removed", vg_name);
- ret = 0;
+ log_error("VG %s lock failed: removed", vg_name);
+ ret = 1;
goto out;
}
8 years, 7 months
master - lvmlockd: improve VG removal for lock_type dlm
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c58f4892f606aa...
Commit: c58f4892f606aafb3828c8c0d2738ed8b6407577
Parent: 7c8fc4b842223c96ed2a1b77ad774871dd34a2e2
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Aug 26 10:01:05 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Aug 26 15:27:22 2015 -0500
lvmlockd: improve VG removal for lock_type dlm
This makes lvmlockd removal steps for dlm VGs closely match
sanlock VGs. Because dlm lockspaces are not required to be
stopped on all hosts before vgremove, there is an extra bit
for dlm lockspaces, where a flag is set in the VG lock lvb
indicating that the VG was removed. If other hosts happen
to use the VG lock they will see this flag and stop their
lockspace.
---
daemons/lvmlockd/lvmlockd-client.h | 1 +
daemons/lvmlockd/lvmlockd-core.c | 7 +++-
daemons/lvmlockd/lvmlockd-dlm.c | 25 ++++++++++++----
daemons/lvmlockd/lvmlockd-internal.h | 4 ++
lib/locking/lvmlockd.c | 51 ++++++++++++++++++++++++---------
5 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-client.h b/daemons/lvmlockd/lvmlockd-client.h
index 0a1424f..67fcbe3 100644
--- a/daemons/lvmlockd/lvmlockd-client.h
+++ b/daemons/lvmlockd/lvmlockd-client.h
@@ -47,5 +47,6 @@ static inline void lvmlockd_close(daemon_handle h)
#define ELOCKD 216
#define EVGKILLED 217 /* sanlock lost access to leases and VG is killed. */
#define ELOCKIO 218 /* sanlock io errors during lock op, may be transient. */
+#define EREMOVED 219
#endif /* _LVM_LVMLOCKD_CLIENT_H */
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index b99cb0b..3d41bd2 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -1763,7 +1763,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
list_del(&act->list);
add_client_result(act);
}
- if (rv == -EUNATCH)
+ if (rv == -EUNATCH || rv == -EREMOVED)
goto r_free;
}
}
@@ -1796,7 +1796,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
list_del(&act->list);
add_client_result(act);
}
- if (rv == -EUNATCH)
+ if (rv == -EUNATCH || rv == -EREMOVED)
goto r_free;
break;
}
@@ -1817,6 +1817,9 @@ r_free:
lm_rem_resource(ls, r);
list_del(&r->list);
free_resource(r);
+
+ if (rv == -EREMOVED)
+ ls->thread_stop = 1;
}
#define LOCKS_EXIST_ANY 1
diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c
index e242685..676c944 100644
--- a/daemons/lvmlockd/lvmlockd-dlm.c
+++ b/daemons/lvmlockd/lvmlockd-dlm.c
@@ -443,6 +443,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk vb;
uint32_t flags = 0;
uint16_t vb_version;
+ uint16_t vb_flags;
int mode;
int rv;
@@ -522,6 +523,7 @@ lockrv:
memcpy(&vb, lksb->sb_lvbptr, sizeof(struct val_blk));
vb_version = le16_to_cpu(vb.version);
+ vb_flags = le16_to_cpu(vb.flags);
if (vb_version && ((vb_version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
log_error("S %s R %s lock_dlm ignore vb_version %x",
@@ -536,8 +538,14 @@ lockrv:
*r_version = le32_to_cpu(vb.r_version);
memcpy(rdd->vb, &vb, sizeof(vb)); /* rdd->vb saved as le */
- log_debug("S %s R %s lock_dlm get r_version %u",
- ls->name, r->name, *r_version);
+ log_debug("S %s R %s lock_dlm get r_version %u flags %x",
+ ls->name, r->name, *r_version, vb_flags);
+
+ if (vb_flags & VBF_REMOVED) {
+ log_debug("S %s R %s lock_dlm VG has been removed",
+ ls->name, r->name);
+ return -EREMOVED;
+ }
}
out:
return 0;
@@ -593,7 +601,7 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
}
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
- uint32_t r_version, uint32_t lmuf_flags)
+ uint32_t r_version, uint32_t lmu_flags)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
@@ -602,7 +610,7 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
int rv;
log_debug("S %s R %s unlock_dlm r_version %u flags %x",
- ls->name, r->name, r_version, lmuf_flags);
+ ls->name, r->name, r_version, lmu_flags);
/*
* Do not set PERSISTENT, because we don't need an orphan
@@ -611,12 +619,17 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
flags |= LKF_CONVERT;
- if (rdd->vb && r_version && (r->mode == LD_LK_EX)) {
+ if (rdd->vb && (r->mode == LD_LK_EX)) {
if (!rdd->vb->version) {
/* first time vb has been written */
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
}
- rdd->vb->r_version = cpu_to_le32(r_version);
+ if (r_version)
+ rdd->vb->r_version = cpu_to_le32(r_version);
+
+ if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG))
+ rdd->vb->flags = cpu_to_le16(VBF_REMOVED);
+
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
log_debug("S %s R %s unlock_dlm set r_version %u",
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
index 8e0582b..46ae67f 100644
--- a/daemons/lvmlockd/lvmlockd-internal.h
+++ b/daemons/lvmlockd/lvmlockd-internal.h
@@ -194,8 +194,12 @@ struct lockspace {
struct list_head resources; /* resource/lock state for gl/vg/lv */
};
+/* val_blk version */
#define VAL_BLK_VERSION 0x0101
+/* val_blk flags */
+#define VBF_REMOVED 0x0001
+
struct val_blk {
uint16_t version;
uint16_t flags;
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 3f73cf3..e647c96 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -694,7 +694,8 @@ out:
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
- uint32_t lockd_flags;
+ daemon_reply reply;
+ uint32_t lockd_flags = 0;
int result;
int ret;
@@ -704,23 +705,31 @@ static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
return 0;
/*
- * Unlocking the vg lock here preempts the lvmlockd unlock in
- * toollib.c which happens too late since the lockspace is
- * left here.
+ * For the dlm, free_vg means unlock the ex VG lock,
+ * and include an indication in the lvb that the VG
+ * has been removed. Then, leave the lockspace.
+ * If another host tries to acquire the VG lock, it
+ * will see that the VG has been removed by looking
+ * at the lvb value.
*/
- /* Equivalent to a standard unlock. */
- ret = _lockd_request(cmd, "lock_vg",
- vg->name, NULL, NULL, NULL, NULL, NULL, "un", NULL,
- &result, &lockd_flags);
+ reply = _lockd_send("free_vg",
+ "pid = %d", getpid(),
+ "vg_name = %s", vg->name,
+ "vg_lock_type = %s", vg->lock_type,
+ "vg_lock_args = %s", vg->lock_args,
+ NULL);
- if (!ret || result < 0) {
- log_error("_free_vg_dlm lvmlockd result %d", result);
- return 0;
+ if (!_lockd_result(reply, &result, &lockd_flags)) {
+ ret = 0;
+ } else {
+ ret = (result < 0) ? 0 : 1;
}
- /* Leave the dlm lockspace. */
- lockd_stop_vg(cmd, vg);
+ if (!ret)
+ log_error("_free_vg_dlm lvmlockd result %d", result);
+
+ daemon_reply_destroy(reply);
return 1;
}
@@ -893,7 +902,11 @@ static int _lockd_all_lvs(struct cmd_context *cmd, struct volume_group *vg)
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
int changing)
{
- /* Check that no LVs are active on other hosts. */
+ /*
+ * Check that no LVs are active on other hosts.
+ * When removing (not changing), each LV is locked
+ * when it is removed, they do not need checking here.
+ */
if (changing && !_lockd_all_lvs(cmd, vg)) {
log_error("Cannot change VG %s with active LVs", vg->name);
return 0;
@@ -1741,6 +1754,16 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
}
/*
+ * The VG has been removed. This will only happen with a dlm VG
+ * since a sanlock VG must be stopped everywhere before it's removed.
+ */
+ if (result == -EREMOVED) {
+ log_error("VG %s lock is removed", vg_name);
+ ret = 0;
+ goto out;
+ }
+
+ /*
* The lockspace for the VG is starting (the VG must not
* be local), and is not yet ready to do locking. Allow
* reading without a sh lock during this period.
8 years, 7 months
master - lvmlockd: fix to work around dlm lvb bug
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7c8fc4b842223c...
Commit: 7c8fc4b842223c96ed2a1b77ad774871dd34a2e2
Parent: d56ae01ebc0100af4caecd45c58f6e36f10bb173
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Aug 25 16:10:12 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Aug 26 15:26:09 2015 -0500
lvmlockd: fix to work around dlm lvb bug
Work around a dlm bug that fails to copy lvb
on a NL->EX conversion.
---
daemons/lvmlockd/lvmlockd-dlm.c | 35 +++++++++++++++++++++++++++++++++--
1 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c
index 1d7cfe6..e242685 100644
--- a/daemons/lvmlockd/lvmlockd-dlm.c
+++ b/daemons/lvmlockd/lvmlockd-dlm.c
@@ -67,6 +67,8 @@ int lm_data_size_dlm(void)
#define VG_LOCK_ARGS_MINOR 0
#define VG_LOCK_ARGS_PATCH 0
+static int dlm_has_lvb_bug;
+
static int cluster_name_from_args(char *vg_args, char *clustername)
{
return last_string_from_args(vg_args, clustername);
@@ -160,6 +162,7 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
{
char sys_clustername[MAX_ARGS+1];
char arg_clustername[MAX_ARGS+1];
+ uint32_t major = 0, minor = 0, patch = 0;
struct lm_dlm *lmd;
int rv;
@@ -170,6 +173,17 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
if (rv < 0)
return -EMANAGER;
+ rv = dlm_kernel_version(&major, &minor, &patch);
+ if (rv < 0) {
+ log_error("prepare_lockspace_dlm kernel_version not detected %d", rv);
+ dlm_has_lvb_bug = 1;
+ }
+
+ if ((major == 6) && (minor == 0) && (patch == 1)) {
+ log_debug("dlm kernel version %u.%u.%u has lvb bug", major, minor, patch);
+ dlm_has_lvb_bug = 1;
+ }
+
if (!ls->vg_args[0]) {
/* global lockspace has no vg args */
goto skip_args;
@@ -468,9 +482,27 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
return 0;
}
+ /*
+ * The dlm lvb bug means that converting NL->EX will not return
+ * the latest lvb, so we have to convert NL->PR->EX to reread it.
+ */
+ if (dlm_has_lvb_bug && (ld_mode == LD_LK_EX)) {
+ rv = dlm_ls_lock_wait(lmd->dh, LKM_PRMODE, lksb, flags,
+ r->name, strlen(r->name),
+ 0, NULL, NULL, NULL);
+ if (rv == -1) {
+ log_debug("S %s R %s lock_dlm acquire mode PR for %d rv %d",
+ ls->name, r->name, mode, rv);
+ goto lockrv;
+ }
+
+ /* Fall through to request EX. */
+ }
+
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
+lockrv:
if (rv == -1 && errno == EAGAIN) {
log_debug("S %s R %s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
@@ -584,8 +616,7 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
/* first time vb has been written */
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
}
- if (r_version)
- rdd->vb->r_version = cpu_to_le32(r_version);
+ rdd->vb->r_version = cpu_to_le32(r_version);
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
log_debug("S %s R %s unlock_dlm set r_version %u",
8 years, 7 months
master - lvmlockd: fix dlm EAGAIN checks
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d56ae01ebc0100...
Commit: d56ae01ebc0100af4caecd45c58f6e36f10bb173
Parent: b9ca9d73c1037657660bb3c966e9039ff75144c1
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Aug 24 15:54:25 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Aug 26 15:25:38 2015 -0500
lvmlockd: fix dlm EAGAIN checks
libdlm returns EAGAIN in errno
---
daemons/lvmlockd/lvmlockd-dlm.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c
index c96866b..1d7cfe6 100644
--- a/daemons/lvmlockd/lvmlockd-dlm.c
+++ b/daemons/lvmlockd/lvmlockd-dlm.c
@@ -384,7 +384,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
(void *)1, (void *)1, (void *)1,
NULL, NULL);
- if (rv == -EAGAIN) {
+ if (rv == -1 && errno == -EAGAIN) {
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
ls->name, r->name, ld_mode);
rv = -EUCLEAN;
@@ -471,12 +471,12 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
- if (rv == -EAGAIN) {
- log_error("S %s R %s lock_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
+ if (rv == -1 && errno == EAGAIN) {
+ log_debug("S %s R %s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
}
if (rv < 0) {
- log_error("S %s R %s lock_dlm error %d", ls->name, r->name, rv);
+ log_error("S %s R %s lock_dlm acquire error %d errno %d", ls->name, r->name, rv, errno);
return rv;
}
@@ -549,7 +549,7 @@ int lm_convert_dlm(struct lockspace *ls, struct resource *r,
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
- if (rv == -EAGAIN) {
+ if (rv == -1 && errno == EAGAIN) {
/* FIXME: When does this happen? Should something different be done? */
log_error("S %s R %s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
8 years, 7 months
master - lvmlockd: add full changing of lock type
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b9ca9d73c10376...
Commit: b9ca9d73c1037657660bb3c966e9039ff75144c1
Parent: 8740b7cb77699dbb78e80ed4e8bd6c742626558e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Aug 24 15:06:23 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Aug 26 15:22:31 2015 -0500
lvmlockd: add full changing of lock type
Remove the existing lock type using the same functions
used to remove the lockd components during vgremove.
This results in a "clean" VG and lvmlockd state after
the vgchange, i.e. no bits left over from previous
lock type.
---
lib/locking/lvmlockd.c | 45 +++++++++++++++++++++++++++++++--------------
lib/locking/lvmlockd.h | 2 +-
tools/vgchange.c | 41 ++++++++++++++++++++++++++---------------
tools/vgremove.c | 2 +-
4 files changed, 59 insertions(+), 31 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 5918de3..3f73cf3 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -868,10 +868,37 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
}
}
+static int _lockd_all_lvs(struct cmd_context *cmd, struct volume_group *vg)
+{
+ struct lv_list *lvl;
+
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ if (!lockd_lv(cmd, lvl->lv, "ex", 0)) {
+ log_error("LV %s/%s must be inactive on all hosts.",
+ vg->name, lvl->lv->name);
+ return 0;
+ }
+
+ if (!lockd_lv(cmd, lvl->lv, "un", 0)) {
+ log_error("Failed to unlock LV %s/%s.", vg->name, lvl->lv->name);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/* vgremove before the vg is removed */
-int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg)
+int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
+ int changing)
{
+ /* Check that no LVs are active on other hosts. */
+ if (changing && !_lockd_all_lvs(cmd, vg)) {
+ log_error("Cannot change VG %s with active LVs", vg->name);
+ return 0;
+ }
+
switch (get_lock_type_from_string(vg->lock_type)) {
case LOCK_TYPE_NONE:
case LOCK_TYPE_CLVM:
@@ -2374,7 +2401,6 @@ int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg)
{
- struct lv_list *lvl;
daemon_reply reply;
int result;
int ret;
@@ -2392,18 +2418,9 @@ int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg)
}
/* Check that no LVs are active on other hosts. */
-
- dm_list_iterate_items(lvl, &vg->lvs) {
- if (!lockd_lv(cmd, lvl->lv, "ex", 0)) {
- log_error("LV %s/%s must be inactive on all hosts before vgrename.",
- vg->name, lvl->lv->name);
- return 0;
- }
-
- if (!lockd_lv(cmd, lvl->lv, "un", 0)) {
- log_error("Failed to unlock LV %s/%s.", vg->name, lvl->lv->name);
- return 0;
- }
+ if (!_lockd_all_lvs(cmd, vg)) {
+ log_error("Cannot rename VG %s with active LVs", vg->name);
+ return 0;
}
/*
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index 64b3ce9..ec36ff8 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -54,7 +54,7 @@ void lvmlockd_disconnect(void);
/* vgcreate/vgremove use init/free */
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count);
-int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg);
+int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg, int changing);
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
/* vgrename */
diff --git a/tools/vgchange.c b/tools/vgchange.c
index cbdc29a..f57fa15 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -568,11 +568,17 @@ static int _vgchange_locktype(struct cmd_context *cmd,
}
if (!strcmp(vg->lock_type, lock_type)) {
- log_warn("New lock_type %s matches the current lock_type %s.",
+ log_warn("New lock type %s matches the current lock type %s.",
lock_type, vg->lock_type);
return 1;
}
+ if (is_lockd_type(vg->lock_type) && is_lockd_type(lock_type)) {
+ log_error("First change from lock type %s to none, then to lock type %s",
+ vg->lock_type, lock_type);
+ return 0;
+ }
+
/*
* When lvm is currently using clvm, this function is just an alternative
* to vgchange -c{y,n}, and can:
@@ -627,17 +633,19 @@ static int _vgchange_locktype(struct cmd_context *cmd,
/*
* lockd type to ..., first undo lockd type
- *
- * To allow this, we need to do:
- * lockd_stop_vg();
- * lockd_free_vg_before();
- * lockd_free_vg_after();
*/
if (is_lockd_type(vg->lock_type)) {
- /* FIXME: implement full undoing of the lock_type */
- log_error("Changing VG %s from lock type %s not yet allowed.",
- vg->name, vg->lock_type);
- return 0;
+ if (!lockd_free_vg_before(cmd, vg, 1))
+ return 0;
+
+ lockd_free_vg_final(cmd, vg);
+
+ vg->status &= ~CLUSTERED;
+ vg->lock_type = "none";
+ vg->lock_args = NULL;
+
+ dm_list_iterate_items(lvl, &vg->lvs)
+ lvl->lv->lock_args = NULL;
}
/* ... to clvm */
@@ -716,7 +724,14 @@ static int _vgchange_locktype(struct cmd_context *cmd,
return 1;
}
- log_error("Unknown lock type");
+ /* ... to none */
+ if (!strcmp(lock_type, "none")) {
+ vg->lock_type = NULL;
+ vg->system_id = cmd->system_id ? dm_pool_strdup(vg->vgmem, cmd->system_id) : NULL;
+ return 1;
+ }
+
+ log_error("Cannot change to unknown lock type %s", lock_type);
return 0;
}
@@ -791,10 +806,6 @@ static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg)
if (vg->lvm1_system_id)
*vg->lvm1_system_id = '\0';
- /* update system_id in lvmlockd's record for this vg */
- if (!lockd_start_vg(cmd, vg))
- log_debug("Failed to update lvmlockd.");
-
return 1;
}
diff --git a/tools/vgremove.c b/tools/vgremove.c
index 692d114..219149e 100644
--- a/tools/vgremove.c
+++ b/tools/vgremove.c
@@ -68,7 +68,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name,
}
}
- if (!lockd_free_vg_before(cmd, vg))
+ if (!lockd_free_vg_before(cmd, vg, 0))
return_ECMD_FAILED;
if (!force && !vg_remove_check(vg))
8 years, 7 months
master - vgdisplay: Drop error message for exported VGs.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8740b7cb77699d...
Commit: 8740b7cb77699dbb78e80ed4e8bd6c742626558e
Parent: 746b1bcf2ad08b0a15dbf6ea0e140c2eb71ff87a
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Aug 26 21:11:46 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Aug 26 21:11:46 2015 +0100
vgdisplay: Drop error message for exported VGs.
Originally when vgdisplay encountered an exported VG it issued a
WARNING. Commit d6b1de30 replaced this with an error message
but still exited with success (incorrect). A backtrace was recently
added in commit b19380998739b9971d27845a70a78511c2335cb0.
As vgdisplay already states that the VG is exported in its output,
just drop these messages completely.
---
WHATS_NEW | 1 +
tools/vgdisplay.c | 3 ---
2 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index d98bcc8..cac567f 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.129 -
===================================
+ Drop error message when vgdisplay encounters an exported VG. (2.02.27)
Fix shared library generation to stop exporting internal functions.(2.02.120)
Accept --cachemode with lvconvert.
Fix and improve reporting properties of cache-pool.
diff --git a/tools/vgdisplay.c b/tools/vgdisplay.c
index 0127e7c..1acb3ec 100644
--- a/tools/vgdisplay.c
+++ b/tools/vgdisplay.c
@@ -22,9 +22,6 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name,
if (arg_count(cmd, activevolumegroups_ARG) && !lvs_in_vg_activated(vg))
return ECMD_PROCESSED;
- if (!vg_check_status(vg, EXPORTED_VG))
- stack;
-
if (arg_count(cmd, colon_ARG)) {
vgdisplay_colons(vg);
return ECMD_PROCESSED;
8 years, 7 months
master - libdm: Drop ignored duplicate export designation.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=746b1bcf2ad08b...
Commit: 746b1bcf2ad08b0a15dbf6ea0e140c2eb71ff87a
Parent: 34c956afc19cd8a1023444ee333983e8b840e759
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Aug 26 17:30:36 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Aug 26 17:30:36 2015 +0100
libdm: Drop ignored duplicate export designation.
dm_stats_create_region is now assigned to DM_1_02_106 by default:
the DM_1_02_104 .exported_symbols file entry was moved into
libdm-stats.c as:
DM_EXPORT_SYMBOL(dm_stats_create_region, 1_02_104)
so delete it from .exported_symbols.DM_1_02_104.
---
libdm/.exported_symbols.DM_1_02_104 | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/libdm/.exported_symbols.DM_1_02_104 b/libdm/.exported_symbols.DM_1_02_104
index 712fcf2..f0a8ed9 100644
--- a/libdm/.exported_symbols.DM_1_02_104
+++ b/libdm/.exported_symbols.DM_1_02_104
@@ -6,7 +6,6 @@ dm_stats_bind_uuid
dm_stats_buffer_destroy
dm_stats_clear_region
dm_stats_create
-dm_stats_create_region
dm_stats_delete_region
dm_stats_destroy
dm_stats_get_area_start
8 years, 7 months
master - make.tmpl: Mark internal sharedlib symbols local.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=34c956afc19cd8...
Commit: 34c956afc19cd8a1023444ee333983e8b840e759
Parent: d0ff35c5a6665ef59a5ed86a6b7d920f909300a2
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Aug 26 13:36:23 2015 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Aug 26 13:36:23 2015 +0100
make.tmpl: Mark internal sharedlib symbols local.
Since commit 797c18d543947f4c2777b4dcf3ceff57cb55352b some internal symbols
have been exported in shared libraries by mistake because 'local: *' got
lost. Fix the shell script not to compare the whole filename with
'Base'
---
WHATS_NEW | 1 +
make.tmpl.in | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ea50997..d98bcc8 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.129 -
===================================
+ Fix shared library generation to stop exporting internal functions.(2.02.120)
Accept --cachemode with lvconvert.
Fix and improve reporting properties of cache-pool.
Enable usage of --cachepolicy and --cachesetting with lvconvert.
diff --git a/make.tmpl.in b/make.tmpl.in
index dbc839a..2ce2faf 100644
--- a/make.tmpl.in
+++ b/make.tmpl.in
@@ -505,7 +505,7 @@ else
for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | sort -rnt_ -k5 ); do\
echo "$${i##*.} {"; echo " global:";\
$(SED) "s/^/ /;s/$$/;/" $$i;\
- test "$$i" = Base && { echo " local:"; echo " *;"; };\
+ test "$${i##*.}" = Base && { echo " local:"; echo " *;"; };\
echo "};";\
done > $@
endif
8 years, 7 months
master - tests: update cache tests
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d0ff35c5a6665e...
Commit: d0ff35c5a6665ef59a5ed86a6b7d920f909300a2
Parent: 1307fafe0f72cea9b3f2e7e7fdb70b1b5d0a0670
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Aug 25 15:10:53 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Aug 26 11:24:41 2015 +0200
tests: update cache tests
---
test/shell/lvconvert-cache.sh | 25 ++++++++++++++++++++-----
1 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index 6ac62c4..3c94ee3 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
@@ -37,11 +37,25 @@ lvcreate -an -Zn -L 8 -n $lv3 $vg
lvcreate -an -Zn -L 8 -n $lv4 $vg
lvcreate -an -Zn -L 16 -n $lv5 $vg
-lvconvert --yes --type cache-pool --cachepool $vg/$lv1
+# check validation of cachemode arg works
+fail lvconvert --yes --type cache-pool --cachemode writethroughX --cachepool $vg/$lv1
+
+# by default no cache settings are attached to converted cache-pool
+lvconvert --yes --type cache-pool --chunksize 256 $vg/$lv1
check inactive $vg ${lv1}_cdata
-lvconvert --yes --type cache-pool --chunksize 256 $vg/$lv2
+check lv_field $vg/$lv1 cache_mode ""
+check lv_field $vg/$lv1 cache_policy ""
+check lv_field $vg/$lv1 cache_settings ""
+check lv_field $vg/$lv1 chunk_size "256.00k"
+
+# but allow to set them when specified explicitely on command line
+lvconvert --yes --type cache-pool --cachemode writeback --cachepolicy mq \
+ --cachesettings sequential_threshold=1234 --cachesettings random_threshold=56 \
+ --cachepool $vg/$lv2
check inactive $vg ${lv2}_cdata
-check lv_field $vg/$lv2 chunk_size "256.00k"
+check lv_field $vg/$lv2 cache_mode "writeback"
+check lv_field $vg/$lv2 cache_policy "mq"
+check lv_field $vg/$lv2 cache_settings "random_threshold=56,sequential_threshold=1234"
# Check swap of cache pool metadata
lvconvert --yes --type cache-pool --poolmetadata $lv4 $vg/$lv3
@@ -58,7 +72,8 @@ lvremove -ff $vg
lvcreate -L 2 -n $lv1 $vg
lvcreate --type cache-pool -l 1 -n ${lv1}_cachepool $vg
-lvconvert --cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
+lvconvert --cache --cachepool $vg/${lv1}_cachepool --cachemode writeback $vg/$lv1
+check lv_field $vg/$lv1 cache_mode "writeback"
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
#lvconvert --cachepool $vg/${lv1}_cachepool $vg/$lv1
8 years, 7 months