master - tests: check cache stripe and raid behavior
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=54c982081fa661...
Commit: 54c982081fa6617c511e2a7d61dbe3b4e9c7d315
Parent: a631fa20d0f18d12a8dc564d9b2d53d38e2e4d43
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Sep 10 16:54:40 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Sep 10 17:28:47 2015 +0200
tests: check cache stripe and raid behavior
Somehow raid tests landed in plain cache - separte them out
so they properly check for have_raid.
Check we do not support strip option with cache-pool creation.
---
test/shell/lvcreate-cache-raid.sh | 34 ++++++++++++++++++++++++++++++++++
test/shell/lvcreate-cache.sh | 22 +++++++---------------
2 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/test/shell/lvcreate-cache-raid.sh b/test/shell/lvcreate-cache-raid.sh
new file mode 100644
index 0000000..1c3c327
--- /dev/null
+++ b/test/shell/lvcreate-cache-raid.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# Copyright (C) 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
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+# Exercise creation of cache and raids
+
+. lib/inittest
+
+test -e LOCAL_LVMPOLLD && skip
+
+aux have_cache 1 3 0 || skip
+aux have_raid 1 0 0 || skip
+
+# FIXME: parallel cache metadata allocator is crashing when used value 8000!
+aux prepare_vg 5 80000
+
+aux lvmconf 'global/cache_disabled_features = [ "policy_smq" ]'
+
+# Bug 1110026 & Bug 1095843
+# Create RAID1 origin, then cache pool and cache
+lvcreate -aey -l 2 --type raid1 -m1 -n $lv2 $vg
+lvcreate --cache -l 1 $vg/$lv2
+check lv_exists $vg/${lv2}_corig_rimage_0 # ensure images are properly renamed
+check active $vg ${lv2}_corig
+dmsetup table ${vg}-$lv2 | grep cache # ensure it is loaded in kernel
+
+vgremove -ff $vg
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index b921909..fce88f3 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -36,6 +36,8 @@ invalid lvcreate -H -l 1 --name $lv1 $vg
invalid lvcreate -l 1 --cache $vg
# Only cached volume could be created
invalid lvcreate -l 1 --type cache $vg
+# Striping is not supported with cache-pool creation
+invalid lvcreate -l 1 -i 2 --type cache-pool $vg
# Fails as it needs to see VG content
fail lvcreate -l 1 --type cache --cachepool $vg/pool1
fail lvcreate -l 1 --type cache --cachepool pool2 $vg
@@ -142,13 +144,6 @@ lvcreate -aey -l 2 -n $lv1 $vg
lvcreate --type cache -l 1 $vg/$lv1
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
-# Bug 1110026 & Bug 1095843
-# Create RAID1 origin, then cache pool and cache
-lvcreate -aey -l 2 --type raid1 -m1 -n $lv2 $vg
-lvcreate --cache -l 1 $vg/$lv2
-check lv_exists $vg/${lv2}_corig_rimage_0 # ensure images are properly renamed
-dmsetup table ${vg}-$lv2 | grep cache # ensure it is loaded in kernel
-
lvremove -f $vg
@@ -168,6 +163,8 @@ lvremove -f $vg
# writeable origin and 'default' => writable cache + origin
lvcreate -an -l1 -n $vg/$lv1
+# do not allow stripping for cache-pool
+fail lvcreate -H -i 2 -l1 -n cpool1 $vg/$lv1
lvcreate -H -l1 -n cpool1 $vg/$lv1
check lv_attr_bit perm $vg/cpool1 "w"
check lv_attr_bit perm $vg/${lv1}_corig "w"
@@ -211,8 +208,9 @@ lvremove -f $vg
lvcreate --type cache-pool -L10 --chunksize 256 --cachemode writeback $vg/cpool1
check lv_field $vg/cpool1 chunksize "256.00k"
check lv_field $vg/cpool1 cachemode "writeback"
-lvcreate -H -L10 -n $lv1 $vg/cpool1
-lvs -a -o+cachemode,chunksize $vg
+# check striping is supported when creating a cached LV
+lvcreate -H -L10 -i 2 -n $lv1 $vg/cpool1
+check lv_field $vg/${lv1}_corig stripes "2" -a
check lv_field $vg/$lv1 chunksize "256.00k"
check lv_field $vg/$lv1 cachemode "writeback"
@@ -264,10 +262,4 @@ grep "chunk size" out
# --poolmetadatasize
# --poolmetadataspare
-lvremove -f $vg
-lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
-lvcreate -n cpool -H $vg/corigin -l 10
-check active $vg corigin_corig
-dmsetup table | grep ^$PREFIX | grep corigin_corig
-
vgremove -ff $vg
8 years, 7 months
master - cache: disallow stripes/size for cache pool
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a631fa20d0f18d...
Commit: a631fa20d0f18d12a8dc564d9b2d53d38e2e4d43
Parent: 5911fa1d914220a182630a5f353b665478917df1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Sep 10 16:33:11 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Sep 10 17:28:15 2015 +0200
cache: disallow stripes/size for cache pool
ATM allocation can't handle stripping and cache pool allocation.
It's not yet even clear what should be actually result.
Until resolved, disable this option (it's been coredumping
inside allocation anyway).
---
WHATS_NEW | 1 +
tools/lvcreate.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3f897ce..6e23fcb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.131 -
=====================================
+ Disallow usage of --stripe and --stripsize when creating cache pool.
Warn user when caching raid or thin pool data LV.
When layering LV, move LV flags with segments.
Ignore persistent cache if configuration changed. (2.02.127)
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 364a16a..7bba761 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -770,7 +770,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
CACHE_POOL_ARGS,
LVCREATE_ARGS,
POOL_ARGS,
- SIZE_ARGS,
+ extents_ARG,
+ size_ARG,
cache_ARG,
chunksize_ARG,
-1))
@@ -1096,6 +1097,8 @@ static int _determine_cache_argument(struct volume_group *vg,
}
/* FIXME How to handle skip flag? */
if (arg_from_list_is_set(cmd, "is unsupported with cache conversion",
+ stripes_ARG,
+ stripesize_ARG,
setactivationskip_ARG,
ignoreactivationskip_ARG,
-1))
8 years, 7 months
master - cache: warn if caching causes troubles
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5911fa1d914220...
Commit: 5911fa1d914220a182630a5f353b665478917df1
Parent: e1edb5676e3ee6f84a3451fcbfe5d5be0d349188
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Sep 10 15:07:59 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Sep 10 17:27:30 2015 +0200
cache: warn if caching causes troubles
Certain stacks of cached LVs may have unexpected consequences.
So add a warning function called when LV is cached to detect
such caces and WARN user about them - the best we could do ATM.
---
WHATS_NEW | 1 +
lib/metadata/cache_manip.c | 19 ++++++++++++++++++-
lib/metadata/lv_manip.c | 2 ++
lib/metadata/metadata-exported.h | 1 +
test/shell/lvconvert-cache-raid.sh | 14 ++++++++------
tools/lvconvert.c | 2 ++
6 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3119f12..3f897ce 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.131 -
=====================================
+ Warn user when caching raid or thin pool data LV.
When layering LV, move LV flags with segments.
Ignore persistent cache if configuration changed. (2.02.127)
Fix devices/filter to be applied before disk-accessing filters. (2.02.112)
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 30d890c..04b8308 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -101,6 +101,23 @@ int cache_set_mode(struct lv_segment *seg, const char *str)
return 1;
}
+/*
+ * At least warn a user if certain cache stacks may present some problems
+ */
+void cache_check_for_warns(const struct lv_segment *seg)
+{
+ struct logical_volume *origin_lv = seg_lv(seg, 0);
+
+ if (lv_is_raid(origin_lv) &&
+ first_seg(seg->pool_lv)->feature_flags & DM_CACHE_FEATURE_WRITEBACK)
+ log_warn("WARNING: Data redundancy is lost with writeback "
+ "caching of raid logical volume!");
+
+ if (lv_is_thin_pool_data(seg->lv))
+ log_warn("WARNING: Cached thin pool's data cannot be currently "
+ "resized and require manual uncache before resize!");
+}
+
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 7412da7..f43d281 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7516,6 +7516,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (!cache_set_policy(first_seg(lv), lp->policy_name, lp->policy_settings))
return_NULL; /* revert? */
+ cache_check_for_warns(first_seg(lv));
+
if (!lv_update_and_reload(lv)) {
/* FIXME Do a better revert */
log_error("Aborting. Manual intervention required.");
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index fff24f0..25320fd 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1158,6 +1158,7 @@ int cache_mode_is_set(const struct lv_segment *seg);
int cache_set_mode(struct lv_segment *cache_seg, const char *str);
int cache_set_policy(struct lv_segment *cache_seg, const char *name,
const struct dm_config_tree *settings);
+void cache_check_for_warns(const struct lv_segment *seg);
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,
diff --git a/test/shell/lvconvert-cache-raid.sh b/test/shell/lvconvert-cache-raid.sh
index 5f51fee..284ffbe 100644
--- a/test/shell/lvconvert-cache-raid.sh
+++ b/test/shell/lvconvert-cache-raid.sh
@@ -24,7 +24,7 @@ aux prepare_vg 5 80
# Bug 1095843
# lvcreate RAID1 origin, lvcreate cache-pool, and lvconvert to cache
-lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
+lvcreate --type raid1 -m 1 --nosync -l 2 -n $lv1 $vg
lvcreate --type cache-pool -l 1 -n ${lv1}_cachepool $vg
lvconvert --cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
@@ -33,17 +33,19 @@ lvremove -f $vg
# lvcreate RAID1 origin, lvcreate RAID1 cache-pool, and lvconvert to cache
-lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
-lvcreate --type raid1 -m 1 -l 2 -n ${lv1}_cachepool $vg
+lvcreate --type raid1 -m 1 --nosync -l 2 -n $lv1 $vg
+lvcreate --type raid1 -m 1 --nosync -l 2 -n ${lv1}_cachepool $vg
#should lvs -a $vg/${lv1}_cdata_rimage_0 # ensure images are properly renamed
-lvconvert --yes --type cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
+lvconvert --yes --type cache --cachemode writeback --cachepool $vg/${lv1}_cachepool $vg/$lv1 2>&1 | tee out
+grep "WARNING: Data redundancy is lost" out
check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
lvremove -f $vg
-lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
-lvcreate -n cpool --type cache $vg/corigin -l 10
+lvcreate -n corigin -m 1 --type raid1 --nosync -l 10 $vg
+lvcreate -n cpool --type cache $vg/corigin --cachemode writeback -l 10 2>&1 | tee out
+grep "WARNING: Data redundancy is lost" out
lvconvert --splitmirrors 1 --name split $vg/corigin "$dev1"
lvremove -f $vg
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 2bffb07..237de2d 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3191,6 +3191,8 @@ static int _lvconvert_cache(struct cmd_context *cmd,
if (!cache_set_policy(first_seg(cache_lv), lp->policy_name, lp->policy_settings))
return_0;
+ cache_check_for_warns(first_seg(cache_lv));
+
if (!lv_update_and_reload(cache_lv))
return_0;
8 years, 7 months
master - lib: when moving segtypes, move LV bits
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e1edb5676e3ee6...
Commit: e1edb5676e3ee6f84a3451fcbfe5d5be0d349188
Parent: 3670f095c7d13a8052b129b3a264bb5a06e8b26e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Sep 10 15:08:29 2015 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Sep 10 17:25:28 2015 +0200
lib: when moving segtypes, move LV bits
When we insert layer we also move status flag-bits for certain LV types,
so internal volume_group structure remains consistent.
(Perhaps it's misuse of 'insert_layer' function and we should have
another similar function for this.)
Basically we aim to maintain the same state as after reading fresh
metadata out of volume group.
Currently we when i.e. cache 'raid' LV - this should transfer 'raidLV' flag
to _corigin LV and cache is no longer a raid.
TODO: bits for stacked devices needs more exact rules.
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 11 +++++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 184eb19..3119f12 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.131 -
=====================================
+ When layering LV, move LV flags with segments.
Ignore persistent cache if configuration changed. (2.02.127)
Fix devices/filter to be applied before disk-accessing filters. (2.02.112)
Make tags only when requested via 'make tags'.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 832a190..7412da7 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6254,6 +6254,7 @@ int move_lv_segments(struct logical_volume *lv_to,
struct logical_volume *lv_from,
uint64_t set_status, uint64_t reset_status)
{
+ const uint64_t MOVE_BITS = (RAID | MIRROR | THIN_VOLUME);
struct lv_segment *seg;
dm_list_iterate_items(seg, &lv_to->segments)
@@ -6271,6 +6272,16 @@ int move_lv_segments(struct logical_volume *lv_to,
seg->status |= set_status;
}
+ /*
+ * Move LV status bits for selected types with their segments
+ * i.e. when inserting layer to cache LV, we move raid segments
+ * to a new place, thus 'raid' LV property now belongs to this LV.
+ *
+ * Bits should match to those which appears after read from disk.
+ */
+ lv_to->status |= lv_from->status & MOVE_BITS;
+ lv_from->status &= ~MOVE_BITS;
+
lv_to->le_count = lv_from->le_count;
lv_to->size = lv_from->size;
8 years, 7 months
master - lvmlockd: check all variations of lvb values
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3670f095c7d13a...
Commit: 3670f095c7d13a8052b129b3a264bb5a06e8b26e
Parent: f11d690967c9d352cb19076a99de81661ee43343
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 9 14:40:48 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Sep 10 09:47:26 2015 -0500
lvmlockd: check all variations of lvb values
The dlm will often lose the lvb content, so we need to
check quite a few possibilities for lvb values that
were not being checked before.
Refactoring was required to pass the entire lvb value
back to the core code instead of the single value.
The only functional change should be detecting new
lvb states where metadata is now invalidated where
it wasn't before.
---
daemons/lvmlockd/lvmlockd-core.c | 313 ++++++++++++++++++++++++----------
daemons/lvmlockd/lvmlockd-dlm.c | 97 ++++++-----
daemons/lvmlockd/lvmlockd-internal.h | 10 +-
daemons/lvmlockd/lvmlockd-sanlock.c | 32 ++--
4 files changed, 297 insertions(+), 155 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 8b78af3..0b0161a 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -873,14 +873,14 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
}
static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct action *act,
- uint32_t *r_version, int *retry, int adopt)
+ struct val_blk *vb_out, int *retry, int adopt)
{
int rv;
if (ls->lm_type == LD_LM_DLM)
- rv = lm_lock_dlm(ls, r, mode, r_version, adopt);
+ rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
else if (ls->lm_type == LD_LM_SANLOCK)
- rv = lm_lock_sanlock(ls, r, mode, r_version, retry, adopt);
+ rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
else
return -1;
@@ -1022,8 +1022,12 @@ static void add_work_action(struct action *act)
static int res_lock(struct lockspace *ls, struct resource *r, struct action *act, int *retry)
{
struct lock *lk;
- uint32_t r_version = 0;
- int rv;
+ struct val_blk vb;
+ uint32_t new_version = 0;
+ int inval_meta;
+ int rv = 0;
+
+ memset(&vb, 0, sizeof(vb));
if (r->type == LD_RT_LV)
log_debug("S %s R %s res_lock mode %s (%s)", ls->name, r->name, mode_str(act->mode), act->lv_name);
@@ -1036,114 +1040,245 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
if (r->type == LD_RT_LV && act->lv_args[0])
memcpy(r->lv_args, act->lv_args, MAX_ARGS);
- rv = lm_lock(ls, r, act->mode, act, &r_version, retry, act->flags & LD_AF_ADOPT);
- if (rv == -EAGAIN)
- return rv;
- if (rv < 0) {
- log_error("S %s R %s res_lock lm error %d", ls->name, r->name, rv);
- return rv;
- }
+ rv = lm_lock(ls, r, act->mode, act, &vb, retry, act->flags & LD_AF_ADOPT);
+
+ if (r->use_vb)
+ log_debug("S %s R %s res_lock %d read vb %x %x %u",
+ ls->name, r->name, rv, vb.version, vb.flags, vb.r_version);
+ else
+ log_debug("S %s R %s res_lock %d", ls->name, r->name, rv);
- log_debug("S %s R %s res_lock lm done r_version %u",
- ls->name, r->name, r_version);
+ if (rv < 0)
+ return rv;
if (sanlock_gl_dup && ls->sanlock_gl_enabled)
act->flags |= LD_AF_DUP_GL_LS;
- /* lm_lock() reads new r_version */
+ /*
+ * Check new lvb values to decide if lvmetad cache should
+ * be invalidated. When we need to invalidate the lvmetad
+ * cache, but don't have a usable r_version from the lvb,
+ * send lvmetad new_version 0 which causes it to invalidate
+ * the VG metdata without comparing against the currently
+ * cached VG seqno.
+ */
+
+ inval_meta = 0;
- if ((r_version != r->version) || (!r->version && !r->version_zero_valid)) {
+ if (!r->use_vb) {
+ /* LV locks don't use an lvb. */
+
+ } else if (vb.version && ((vb.version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
+ log_error("S %s R %s res_lock invalid val_blk version %x flags %x r_version %u",
+ ls->name, r->name, vb.version, vb.flags, vb.r_version);
+ inval_meta = 1;
+ new_version = 0;
+ rv = -EINVAL;
+
+ } else if (vb.r_version && (vb.r_version == r->version)) {
+ /*
+ * Common case when the version hasn't changed.
+ * Do nothing.
+ */
+ } else if (r->version && vb.r_version && (vb.r_version > r->version)) {
+ /*
+ * Common case when the version has changed. Another host
+ * has changed the data protected by the lock since we last
+ * acquired it, and increased r_version so we know that our
+ * cache is invalid.
+ */
+ log_debug("S %s R %s res_lock got version %u our %u",
+ ls->name, r->name, vb.r_version, r->version);
+ r->version = vb.r_version;
+ new_version = vb.r_version;
+ r->version_zero_valid = 0;
+ inval_meta = 1;
+
+ } else if (r->version_zero_valid && !vb.r_version) {
+ /*
+ * The lvb is in a persistent zero state, which will end
+ * once someone uses the lock and writes a new lvb value.
+ * Do nothing.
+ */
+ log_debug("S %s R %s res_lock version_zero_valid still zero", ls->name, r->name);
+ } else if (r->version_zero_valid && vb.r_version) {
/*
- * r_version only increases, so if it goes down, it means the
- * dlm lvb became invalid (happens during recovery if the
- * resource master leaves).
+ * Someone has written to the lvb after it was in a
+ * persistent zero state. Begin tracking normal
+ * non-zero changes. We may or may not have known
+ * about a previous non-zero version (in r->version).
+ * If we did, it means the lvb content was lost and
+ * has now been reinitialized.
+ *
+ * If the new reinitialized value is less than the
+ * previous non-zero value in r->version, then something
+ * unusual has happened. For a VG lock, it probably
+ * means the VG was removed and recreated. Invalidate
+ * our cache and begin using the new VG version. For
+ * a GL lock, another host may have reinitialized a
+ * lost/zero lvb with a value less than we'd seen
+ * before. Invalidate the cache, and begin using
+ * the lower version (or continue using our old
+ * larger version?)
*/
- 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);
+ if (r->version && (r->version >= vb.r_version)) {
+ log_debug("S %s R %s res_lock version_zero_valid got version %u less than our %u",
+ ls->name, r->name, vb.r_version, r->version);
+ new_version = 0;
+ } else {
+ log_debug("S %s R %s res_lock version_zero_valid got version %u our %u",
+ ls->name, r->name, vb.r_version, r->version);
+ new_version = vb.r_version;
}
+ r->version = vb.r_version;
+ r->version_zero_valid = 0;
+ inval_meta = 1;
+ } else if (!r->version && vb.r_version) {
/*
- * New r_version of the lock: means that another
- * host has changed data protected by this lock
- * since the last time we acquired it. We
- * should invalidate any local cache of the data
- * protected by this lock and reread it from disk.
+ * The first time we've acquired the lock and seen the lvb.
*/
- r->version = r_version;
+ log_debug("S %s R %s res_lock initial version %u", ls->name, r->name, vb.r_version);
+ r->version = vb.r_version;
+ inval_meta = 1;
+ new_version = vb.r_version;
+ r->version_zero_valid = 0;
+ } else if (!r->version && !vb.r_version) {
/*
- * When a new global lock is enabled in a new vg,
- * it will have version zero, and the first time
- * we use it we need to validate the global cache
- * since we don't have any version history to know
- * the state of the cache. The version could remain
- * zero for a long time if no global state is changed
- * to cause the GL version to be incremented to 1.
+ * The lock may have never been used to change something.
+ * (e.g. a new sanlock GL?)
*/
+ log_debug("S %s R %s res_lock all versions zero", ls->name, r->name);
+ if (!r->version_zero_valid) {
+ inval_meta = 1;
+ new_version = 0;
+ }
r->version_zero_valid = 1;
+ } else if (r->version && !vb.r_version) {
/*
- * r is vglk: tell lvmetad to set the vg invalid
- * flag, and provide the new r_version. If lvmetad finds
- * that its cached vg has seqno less than the value
- * we send here, it will set the vg invalid flag.
- * lvm commands that read the vg from lvmetad, will
- * see the invalid flag returned, will reread the
- * vg from disk, update the lvmetad copy, and go on.
+ * The lvb content has been lost or never been initialized.
+ * It can be lost during dlm recovery when the master node
+ * is removed.
+ *
+ * If we're the next to write the lvb, reinitialze it to the
+ * new VG seqno, or a new GL counter larger than was seen by
+ * any hosts before (how to estimate that?)
*
- * r is global: tell lvmetad to set the global invalid
- * flag. When commands see this flag returned from lvmetad,
- * they will reread metadata from disk, update the lvmetad
- * caches, and tell lvmetad to set global invalid to 0.
+ * If we see non-zero values before we next write to it, use
+ * those values.
+ *
+ * While the lvb values remain zero, the data for the lock
+ * is unchanged and we don't need to invalidate metadata.
*/
+ if ((ls->lm_type == LD_LM_DLM) && !vb.version && !vb.flags)
+ log_debug("S %s R %s res_lock all lvb content is blank",
+ ls->name, r->name);
+ log_debug("S %s R %s res_lock our version %u got vb %x %x %u",
+ ls->name, r->name, r->version, vb.version, vb.flags, vb.r_version);
+ r->version_zero_valid = 1;
+ inval_meta = 1;
+ new_version = 0;
- if ((r->type == LD_RT_VG) && lvmetad_connected) {
- daemon_reply reply;
- char *uuid;
+ } else if (r->version && vb.r_version && (vb.r_version < r->version)) {
+ /*
+ * The lvb value has gone backwards, which shouldn't generally happen,
+ * but could when the dlm lvb is lost and reinitialized, or the VG
+ * is removed and recreated.
+ *
+ * If this is a VG lock, it probably means the VG has been removed
+ * and recreated while we had the dlm lockspace running.
+ * FIXME: how does the cache validation and replacement in lvmetad
+ * work in this case?
+ */
+ log_debug("S %s R %s res_lock got version %u less than our version %u",
+ ls->name, r->name, vb.r_version, r->version);
+ r->version = vb.r_version;
+ inval_meta = 1;
+ new_version = 0;
+ r->version_zero_valid = 0;
+ } else {
+ log_debug("S %s R %s res_lock undefined vb condition vzv %d our version %u vb %x %x %u",
+ ls->name, r->name, r->version_zero_valid, r->version,
+ vb.version, vb.flags, vb.r_version);
+ }
- log_debug("S %s R %s res_lock set lvmetad vg version %u",
- ls->name, r->name, r_version);
+ if (vb.version && vb.r_version && (vb.flags & VBF_REMOVED)) {
+ /* Should we set ls->thread_stop = 1 ? */
+ log_debug("S %s R %s res_lock vb flag REMOVED",
+ ls->name, r->name);
+ rv = -EREMOVED;
+ }
+
+ if (!lvmetad_connected && inval_meta)
+ log_debug("S %s R %s res_lock no lvmetad connection to invalidate",
+ ls->name, r->name);
+
+ /*
+ * r is vglk: tell lvmetad to set the vg invalid
+ * flag, and provide the new r_version. If lvmetad finds
+ * that its cached vg has seqno less than the value
+ * we send here, it will set the vg invalid flag.
+ * lvm commands that read the vg from lvmetad, will
+ * see the invalid flag returned, will reread the
+ * vg from disk, update the lvmetad copy, and go on.
+ *
+ * r is global: tell lvmetad to set the global invalid
+ * flag. When commands see this flag returned from lvmetad,
+ * they will reread metadata from disk, update the lvmetad
+ * caches, and tell lvmetad to set global invalid to 0.
+ */
+
+ if (lvmetad_connected && inval_meta && (r->type == LD_RT_VG)) {
+ daemon_reply reply;
+ char *uuid;
+
+ log_debug("S %s R %s res_lock set lvmetad vg version %u",
+ ls->name, r->name, new_version);
- if (!ls->vg_uuid[0] || !strcmp(ls->vg_uuid, "none"))
- uuid = (char *)"none";
- else
- uuid = ls->vg_uuid;
+ if (!ls->vg_uuid[0] || !strcmp(ls->vg_uuid, "none"))
+ uuid = (char *)"none";
+ else
+ uuid = ls->vg_uuid;
- pthread_mutex_lock(&lvmetad_mutex);
- reply = daemon_send_simple(lvmetad_handle, "set_vg_info",
- "token = %s", "skip",
- "uuid = %s", uuid,
- "name = %s", ls->vg_name,
- "version = %d", (int)r_version,
- NULL);
+ pthread_mutex_lock(&lvmetad_mutex);
+ reply = daemon_send_simple(lvmetad_handle, "set_vg_info",
+ "token = %s", "skip",
+ "uuid = %s", uuid,
+ "name = %s", ls->vg_name,
+ "version = %d", (int)new_version,
+ NULL);
pthread_mutex_unlock(&lvmetad_mutex);
- if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
- log_error("set_vg_info in lvmetad failed %d", reply.error);
- daemon_reply_destroy(reply);
- }
+ if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
+ log_error("set_vg_info in lvmetad failed %d", reply.error);
+ daemon_reply_destroy(reply);
+ }
- if ((r->type == LD_RT_GL) && lvmetad_connected) {
- daemon_reply reply;
+ if (lvmetad_connected && inval_meta && (r->type == LD_RT_GL)) {
+ daemon_reply reply;
- log_debug("S %s R %s res_lock set lvmetad global invalid",
- ls->name, r->name);
+ log_debug("S %s R %s res_lock set lvmetad global invalid",
+ ls->name, r->name);
- pthread_mutex_lock(&lvmetad_mutex);
- reply = daemon_send_simple(lvmetad_handle, "set_global_info",
+ pthread_mutex_lock(&lvmetad_mutex);
+ reply = daemon_send_simple(lvmetad_handle, "set_global_info",
"token = %s", "skip",
"global_invalid = %d", 1,
NULL);
- pthread_mutex_unlock(&lvmetad_mutex);
+ pthread_mutex_unlock(&lvmetad_mutex);
- if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
- log_error("set_global_info in lvmetad failed %d", reply.error);
- daemon_reply_destroy(reply);
- }
+ if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
+ log_error("set_global_info in lvmetad failed %d", reply.error);
+ daemon_reply_destroy(reply);
}
+ /*
+ * Record the new lock state.
+ */
+
r->mode = act->mode;
add_lk:
@@ -1163,7 +1298,7 @@ add_lk:
list_add_tail(&lk->list, &r->locks);
- return 0;
+ return rv;
}
static int res_convert(struct lockspace *ls, struct resource *r,
@@ -1320,12 +1455,14 @@ do_unlock:
r->version++;
lk->version = r->version;
r_version = r->version;
+ r->version_zero_valid = 0;
log_debug("S %s R %s res_unlock r_version inc %u", ls->name, r->name, r_version);
} else if ((r->type == LD_RT_VG) && (r->mode == LD_LK_EX) && (lk->version > r->version)) {
r->version = lk->version;
r_version = r->version;
+ r->version_zero_valid = 0;
log_debug("S %s R %s res_unlock r_version new %u",
ls->name, r->name, r_version);
@@ -1967,15 +2104,18 @@ static struct resource *find_resource_act(struct lockspace *ls,
return NULL;
r->type = act->rt;
-
r->mode = LD_LK_UN;
- if (r->type == LD_RT_GL)
+ if (r->type == LD_RT_GL) {
strncpy(r->name, R_NAME_GL, MAX_NAME);
- else if (r->type == LD_RT_VG)
+ r->use_vb = 1;
+ } else if (r->type == LD_RT_VG) {
strncpy(r->name, R_NAME_VG, MAX_NAME);
- else if (r->type == LD_RT_LV)
+ r->use_vb = 1;
+ } else if (r->type == LD_RT_LV) {
strncpy(r->name, act->lv_uuid, MAX_NAME);
+ r->use_vb = 0;
+ }
list_add_tail(&r->list, &ls->resources);
@@ -2502,14 +2642,10 @@ static int add_lockspace_thread(const char *ls_name,
{
struct lockspace *ls, *ls2;
struct resource *r;
- uint32_t version = 0;
int rv;
- if (act)
- version = act->version;
-
log_debug("add_lockspace_thread %s %s version %u",
- lm_str(lm_type), ls_name, version);
+ lm_str(lm_type), ls_name, act ? act->version : 0);
if (!(ls = alloc_lockspace()))
return -ENOMEM;
@@ -2539,7 +2675,7 @@ static int add_lockspace_thread(const char *ls_name,
r->type = LD_RT_VG;
r->mode = LD_LK_UN;
- r->version = version;
+ r->use_vb = 1;
strncpy(r->name, R_NAME_VG, MAX_NAME);
list_add_tail(&r->list, &ls->resources);
@@ -4634,6 +4770,7 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
goto next;
}
+ r->use_vb = 0;
r->type = LD_RT_LV;
strncpy(r->name, lv_uuid, MAX_NAME);
if (lock_args)
diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c
index 6640821..7f65abc 100644
--- a/daemons/lvmlockd/lvmlockd-dlm.c
+++ b/daemons/lvmlockd/lvmlockd-dlm.c
@@ -343,7 +343,7 @@ static int to_dlm_mode(int ld_mode)
}
static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version)
+ struct val_blk *vb_out)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
@@ -352,7 +352,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
int mode;
int rv;
- *r_version = 0;
+ memset(vb_out, 0, sizeof(struct val_blk));
if (!r->lm_init) {
rv = lm_add_resource_dlm(ls, r, 0);
@@ -431,15 +431,13 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
*/
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version, int adopt)
+ struct val_blk *vb_out, int adopt)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
struct dlm_lksb *lksb;
struct val_blk vb;
uint32_t flags = 0;
- uint16_t vb_version;
- uint16_t vb_flags;
int mode;
int rv;
@@ -447,7 +445,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
/* When adopting, we don't follow the normal method
of acquiring a NL lock then converting it to the
desired mode. */
- return lm_adopt_dlm(ls, r, ld_mode, r_version);
+ return lm_adopt_dlm(ls, r, ld_mode, vb_out);
}
if (!r->lm_init) {
@@ -475,7 +473,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
log_debug("S %s R %s lock_dlm", ls->name, r->name);
if (daemon_test) {
- *r_version = 0;
+ memset(vb_out, 0, sizeof(struct val_blk));
return 0;
}
@@ -513,35 +511,22 @@ lockrv:
if (lksb->sb_flags & DLM_SBF_VALNOTVALID) {
log_debug("S %s R %s lock_dlm VALNOTVALID", ls->name, r->name);
memset(rdd->vb, 0, sizeof(struct val_blk));
- *r_version = 0;
+ memset(vb_out, 0, sizeof(struct val_blk));
goto out;
}
+ /*
+ * 'vb' contains disk endian values, not host endian.
+ * It is copied directly to rdd->vb which is also kept
+ * in disk endian form.
+ * vb_out is returned to the caller in host endian form.
+ */
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",
- ls->name, r->name, vb_version);
- *r_version = 0;
- free(rdd->vb);
- rdd->vb = NULL;
- lksb->sb_lvbptr = NULL;
- goto out;
- }
-
- *r_version = le32_to_cpu(vb.r_version);
- memcpy(rdd->vb, &vb, sizeof(vb)); /* rdd->vb saved as le */
+ memcpy(rdd->vb, &vb, sizeof(vb));
- 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;
- }
+ vb_out->version = le16_to_cpu(vb.version);
+ vb_out->flags = le16_to_cpu(vb.flags);
+ vb_out->r_version = le32_to_cpu(vb.r_version);
}
out:
return 0;
@@ -602,12 +587,12 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
struct dlm_lksb *lksb = &rdd->lksb;
+ struct val_blk vb_prev;
+ struct val_blk vb_next;
uint32_t flags = 0;
+ int new_vb = 0;
int rv;
- log_debug("S %s R %s unlock_dlm r_version %u flags %x",
- ls->name, r->name, r_version, lmu_flags);
-
/*
* Do not set PERSISTENT, because we don't need an orphan
* NL lock to protect anything.
@@ -616,22 +601,45 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
flags |= LKF_CONVERT;
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);
+
+ /* vb_prev and vb_next are in disk endian form */
+ memcpy(&vb_prev, rdd->vb, sizeof(struct val_blk));
+ memcpy(&vb_next, rdd->vb, sizeof(struct val_blk));
+
+ if (!vb_prev.version) {
+ vb_next.version = cpu_to_le16(VAL_BLK_VERSION);
+ new_vb = 1;
}
- 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);
+ if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG)) {
+ vb_next.flags = cpu_to_le16(VBF_REMOVED);
+ new_vb = 1;
+ }
- memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
+ if (r_version) {
+ vb_next.r_version = cpu_to_le32(r_version);
+ new_vb = 1;
+ }
- log_debug("S %s R %s unlock_dlm set r_version %u",
- ls->name, r->name, r_version);
+ if (new_vb) {
+ memcpy(rdd->vb, &vb_next, sizeof(struct val_blk));
+ memcpy(lksb->sb_lvbptr, &vb_next, sizeof(struct val_blk));
+
+ log_debug("S %s R %s unlock_dlm vb old %x %x %u new %x %x %u",
+ ls->name, r->name,
+ le16_to_cpu(vb_prev.version),
+ le16_to_cpu(vb_prev.flags),
+ le32_to_cpu(vb_prev.r_version),
+ le16_to_cpu(vb_next.version),
+ le16_to_cpu(vb_next.flags),
+ le32_to_cpu(vb_next.r_version));
+ } else {
+ log_debug("S %s R %s unlock_dlm vb unchanged", ls->name, r->name);
+ }
flags |= LKF_VALBLK;
+ } else {
+ log_debug("S %s R %s unlock_dlm", ls->name, r->name);
}
if (daemon_test)
@@ -700,3 +708,4 @@ int lm_is_running_dlm(void)
return 0;
return 1;
}
+
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
index a58976f..6bdd4c7 100644
--- a/daemons/lvmlockd/lvmlockd-internal.h
+++ b/daemons/lvmlockd/lvmlockd-internal.h
@@ -143,9 +143,9 @@ struct resource {
unsigned int lm_init : 1; /* lm_data is initialized */
unsigned int adopt : 1; /* temp flag in remove_inactive_lvs */
unsigned int version_zero_valid : 1;
+ unsigned int use_vb : 1;
struct list_head locks;
struct list_head actions;
- struct val_blk *vb;
char lv_args[MAX_ARGS+1];
char lm_data[0]; /* lock manager specific data */
};
@@ -356,7 +356,7 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls);
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version, int adopt);
+ struct val_blk *vb_out, int adopt);
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
@@ -394,7 +394,7 @@ static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
}
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version, int adopt)
+ struct val_blk *vb_out, int adopt)
{
return -1;
}
@@ -448,7 +448,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls);
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version, int *retry, int adopt);
+ struct val_blk *vb_out, int *retry, int adopt);
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
@@ -506,7 +506,7 @@ static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
}
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version, int *retry, int adopt)
+ struct val_blk *vb_out, int *retry, int adopt)
{
return -1;
}
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
index 4317aad..1e691eb 100644
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
@@ -1300,7 +1300,7 @@ int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
}
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
- uint32_t *r_version, int *retry, int adopt)
+ struct val_blk *vb_out, int *retry, int adopt)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
@@ -1308,7 +1308,6 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
uint64_t lock_lv_offset;
uint32_t flags = 0;
struct val_blk vb;
- uint16_t vb_version;
int added = 0;
int rv;
@@ -1384,7 +1383,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
(unsigned long long)rs->disks[0].offset);
if (daemon_test) {
- *r_version = 0;
+ memset(vb_out, 0, sizeof(struct val_blk));
return 0;
}
@@ -1501,26 +1500,23 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
rv = sanlock_get_lvb(0, rs, (char *)&vb, sizeof(vb));
if (rv < 0) {
log_error("S %s R %s lock_san get_lvb error %d", ls->name, r->name, rv);
- *r_version = 0;
+ memset(rds->vb, 0, sizeof(struct val_blk));
+ memset(vb_out, 0, sizeof(struct val_blk));
goto out;
}
- vb_version = le16_to_cpu(vb.version);
-
- if (vb_version && ((vb_version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
- log_error("S %s R %s lock_san ignore vb_version %x",
- ls->name, r->name, vb_version);
- *r_version = 0;
- free(rds->vb);
- rds->vb = NULL;
- goto out;
- }
+ /*
+ * 'vb' contains disk endian values, not host endian.
+ * It is copied directly to rrs->vb which is also kept
+ * in disk endian form.
+ * vb_out is returned to the caller in host endian form.
+ */
- *r_version = le32_to_cpu(vb.r_version);
- memcpy(rds->vb, &vb, sizeof(vb)); /* rds->vb saved as le */
+ memcpy(rds->vb, &vb, sizeof(vb));
- log_debug("S %s R %s lock_san get r_version %u",
- ls->name, r->name, *r_version);
+ vb_out->version = le16_to_cpu(vb.version);
+ vb_out->flags = le16_to_cpu(vb.flags);
+ vb_out->r_version = le32_to_cpu(vb.r_version);
}
out:
return rv;
8 years, 7 months
master - lvmlockd: flag for internal actions
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f11d690967c9d3...
Commit: f11d690967c9d352cb19076a99de81661ee43343
Parent: 15ae237d2c029116395e5436826f896a5a00d6c4
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 9 13:33:10 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Sep 10 09:47:26 2015 -0500
lvmlockd: flag for internal actions
When an action is created by lvmlockd for itself,
there is no client to send the result to. Add
the NO_CLIENT flag to the action to skip sending
the result to a client.
---
daemons/lvmlockd/lvmlockd-core.c | 7 +++++++
daemons/lvmlockd/lvmlockd-internal.h | 2 +-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 9b79131..8b78af3 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -959,6 +959,13 @@ static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset)
static void add_client_result(struct action *act)
{
+ if (act->flags & LD_AF_NO_CLIENT) {
+ log_debug("internal action done op %s mode %s result %d vg %s",
+ op_str(act->op), mode_str(act->mode), act->result, act->vg_name);
+ free_action(act);
+ return;
+ }
+
pthread_mutex_lock(&client_mutex);
if (act->flags & LD_AF_ADOPT)
list_add_tail(&act->list, &adopt_results);
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
index 68dcd9d..a58976f 100644
--- a/daemons/lvmlockd/lvmlockd-internal.h
+++ b/daemons/lvmlockd/lvmlockd-internal.h
@@ -89,7 +89,7 @@ struct client {
};
#define LD_AF_PERSISTENT 0x00000001
-#define LD_AF_UNUSED 0x00000002 /* use me */
+#define LD_AF_NO_CLIENT 0x00000002
#define LD_AF_UNLOCK_CANCEL 0x00000004
#define LD_AF_NEXT_VERSION 0x00000008
#define LD_AF_WAIT 0x00000010
8 years, 7 months
master - lvmlockd: rename ADOPT_CLIENT_ID
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=15ae237d2c0291...
Commit: 15ae237d2c029116395e5436826f896a5a00d6c4
Parent: 36d16fed1fe883cf2c2756212fd0e6b2f1f99e6b
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 9 13:25:39 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Sep 10 09:47:26 2015 -0500
lvmlockd: rename ADOPT_CLIENT_ID
to INTERNAL_CLIENT_ID since it will be
used for more than adopting locks.
---
daemons/lvmlockd/lvmlockd-core.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index af1a3a9..9b79131 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -197,11 +197,11 @@ static pthread_mutex_t client_mutex;
static pthread_cond_t client_cond;
static struct list_head client_list; /* connected clients */
static struct list_head client_results; /* actions to send back to clients */
-static uint32_t client_ids; /* 0 and ADOPT_CLIENT_ID are skipped */
+static uint32_t client_ids; /* 0 and INTERNAL_CLIENT_ID are skipped */
static int client_stop; /* stop the thread */
static int client_work; /* a client on client_list has work to do */
-#define ADOPT_CLIENT_ID 0xFFFFFFFF /* special client_id for adopt actions */
+#define INTERNAL_CLIENT_ID 0xFFFFFFFF /* special client_id for internal actions */
static struct list_head adopt_results; /* special start actions from adopt_locks() */
/*
@@ -5047,7 +5047,7 @@ static void adopt_locks(void)
act->flags = (LD_AF_ADOPT | LD_AF_WAIT);
act->rt = LD_RT_GL;
act->lm_type = LD_LM_DLM;
- act->client_id = ADOPT_CLIENT_ID;
+ act->client_id = INTERNAL_CLIENT_ID;
add_dlm_global_lockspace(act);
count_start++;
}
@@ -5059,7 +5059,7 @@ static void adopt_locks(void)
act->flags = (LD_AF_ADOPT | LD_AF_WAIT);
act->rt = LD_RT_VG;
act->lm_type = ls->lm_type;
- act->client_id = ADOPT_CLIENT_ID;
+ act->client_id = INTERNAL_CLIENT_ID;
strncpy(act->vg_name, ls->vg_name, MAX_NAME);
memcpy(act->vg_uuid, ls->vg_uuid, 64);
memcpy(act->vg_args, ls->vg_args, MAX_ARGS);
@@ -5151,7 +5151,7 @@ static void adopt_locks(void)
act->rt = LD_RT_LV;
act->mode = LD_LK_EX;
act->flags = (LD_AF_ADOPT | LD_AF_PERSISTENT);
- act->client_id = ADOPT_CLIENT_ID;
+ act->client_id = INTERNAL_CLIENT_ID;
act->lm_type = ls->lm_type;
strncpy(act->vg_name, ls->vg_name, MAX_NAME);
strncpy(act->lv_uuid, r->name, MAX_NAME);
@@ -5179,7 +5179,7 @@ static void adopt_locks(void)
act->rt = LD_RT_VG;
act->mode = LD_LK_SH;
act->flags = LD_AF_ADOPT;
- act->client_id = ADOPT_CLIENT_ID;
+ act->client_id = INTERNAL_CLIENT_ID;
act->lm_type = ls->lm_type;
strncpy(act->vg_name, ls->vg_name, MAX_NAME);
@@ -5205,7 +5205,7 @@ static void adopt_locks(void)
act->rt = LD_RT_GL;
act->mode = LD_LK_SH;
act->flags = LD_AF_ADOPT;
- act->client_id = ADOPT_CLIENT_ID;
+ act->client_id = INTERNAL_CLIENT_ID;
act->lm_type = (gl_use_sanlock ? LD_LM_SANLOCK : LD_LM_DLM);
log_debug("adopt lock for gl");
@@ -5444,7 +5444,7 @@ static void process_listener(int poll_fd)
pthread_mutex_lock(&client_mutex);
client_ids++;
- if (client_ids == ADOPT_CLIENT_ID)
+ if (client_ids == INTERNAL_CLIENT_ID)
client_ids++;
if (!client_ids)
client_ids++;
8 years, 7 months
master - lockd: add start_init arg to lockd_start_vg
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=36d16fed1fe883...
Commit: 36d16fed1fe883cf2c2756212fd0e6b2f1f99e6b
Parent: 30e489db5e05296e22037bd885d074d395ab46f4
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 9 13:20:37 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Sep 10 09:47:26 2015 -0500
lockd: add start_init arg to lockd_start_vg
Add a new arg to lockd_start_vg() that indicates
it is being called for a new lockd VG, so that
lvmlockd knows the lockspace being started is new.
(Will be used by a following commit.)
---
lib/locking/lvmlockd.c | 15 ++++++++++-----
lib/locking/lvmlockd.h | 4 ++--
tools/vgchange.c | 2 +-
tools/vgcreate.c | 2 +-
4 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index a726d87..597a964 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -921,9 +921,13 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
* for starting the lockspace. To use the vg after starting
* the lockspace, follow the standard method which is:
* lock the vg, read/use/write the vg, unlock the vg.
+ *
+ * start_init is 1 when the VG is being started after the
+ * command has done lockd_init_vg(). This tells lvmlockd
+ * that the VG lockspace being started is new.
*/
-int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
+int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init)
{
char uuid[64] __attribute__((aligned(8)));
daemon_reply reply;
@@ -945,8 +949,8 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
return 0;
}
- log_debug("lockd start VG %s lock_type %s",
- vg->name, vg->lock_type ? vg->lock_type : "empty");
+ log_debug("lockd start VG %s lock_type %s init %d",
+ vg->name, vg->lock_type ? vg->lock_type : "empty", start_init);
if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
return_0;
@@ -973,6 +977,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
"vg_uuid = %s", uuid[0] ? uuid : "none",
"version = %d", (int64_t)vg->seqno,
"host_id = %d", host_id,
+ "opts = %s", start_init ? "start_init" : "none",
NULL);
if (!_lockd_result(reply, &result, NULL)) {
@@ -2461,7 +2466,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
* Depending on the problem that caused the rename to
* fail, it may make sense to not restart the VG here.
*/
- if (!lockd_start_vg(cmd, vg))
+ if (!lockd_start_vg(cmd, vg, 0))
log_error("Failed to restart VG %s lockspace.", vg->name);
return 1;
}
@@ -2501,7 +2506,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
}
}
- if (!lockd_start_vg(cmd, vg))
+ if (!lockd_start_vg(cmd, vg, 1))
log_error("Failed to start VG %s lockspace.", vg->name);
return 1;
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index 51c2905..7e6505d 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -62,7 +62,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
/* start and stop the lockspace for a vg */
-int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg);
+int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init);
int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
int lockd_start_wait(struct cmd_context *cmd);
@@ -147,7 +147,7 @@ static inline int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_g
return 1;
}
-static inline int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
+static inline int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init)
{
return 0;
}
diff --git a/tools/vgchange.c b/tools/vgchange.c
index a80b678..81e4bf3 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -878,7 +878,7 @@ static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg
}
do_start:
- return lockd_start_vg(cmd, vg);
+ return lockd_start_vg(cmd, vg, 0);
}
static int _vgchange_lock_stop(struct cmd_context *cmd, struct volume_group *vg)
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 67b593d..fd79563 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -157,7 +157,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
if (is_lockd_type(vg->lock_type)) {
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
- if (!lockd_start_vg(cmd, vg)) {
+ if (!lockd_start_vg(cmd, vg, 1)) {
log_error("Failed to start locking");
goto out;
}
8 years, 7 months
master - vgchange: lock-stop only needs shared lock
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=30e489db5e0529...
Commit: 30e489db5e05296e22037bd885d074d395ab46f4
Parent: 2296999cf6922b2be0c6dc38abae0c6766996060
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Sep 9 13:09:17 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu Sep 10 09:47:26 2015 -0500
vgchange: lock-stop only needs shared lock
lock-stop is one of the vgchange options that
doesn't change the VG so we can override the
default ex lock and use sh.
---
tools/vgchange.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 1d3c64a..a80b678 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -1044,6 +1044,9 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
cmd->lockd_vg_enforce_sh = 1;
}
+ if (arg_is_set(cmd, lockstop_ARG))
+ cmd->lockd_vg_default_sh = 1;
+
/* Starting a vg lockspace means there are no locks available yet. */
if (arg_is_set(cmd, lockstart_ARG))
8 years, 7 months
master - dev-cache: ignore persistent cache if configuration changed
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2296999cf6922b...
Commit: 2296999cf6922b2be0c6dc38abae0c6766996060
Parent: d323acdfec8aaab1161aa5f80ae67622e396a632
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Sep 10 16:00:14 2015 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Sep 10 16:13:39 2015 +0200
dev-cache: ignore persistent cache if configuration changed
Commit f6473baffc2d0b486b2aa941cf2681683026b3a5 introduced a new
cmd->initialized variable to keep info about which parts of the
cmd_context have been initialized.
A part of this patch was also a change in refresh_filters fn
which checks for cmd->initialized.filters variable and it does
the filter refresh *only* if the filter has already been initialized
before otherwise it's a NOOP (before, the refresh_filters also
initialized filters as a side effect in case it had not been
initialized before which was not quite correct).
However, the commit f6473baffc2d0b486b2aa941cf2681683026b3a5
did not handle the case in which configuration changes
either via --config argument or when configuration file changed
and its timestamp was higher than the timestamp of the persistent
cache file - the /etc/lvm/cache/.cache.
This patch fixes this issue and it causes the init_filters fn
in lvm_run_command fn to be called with proper value of
"load_persistent_cache" switch even if the configuration changes,
hence causing the persistent cache file to be ignored in this
case.
---
WHATS_NEW | 1 +
tools/lvmcmdline.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 43fbb56..184eb19 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.131 -
=====================================
+ Ignore persistent cache if configuration changed. (2.02.127)
Fix devices/filter to be applied before disk-accessing filters. (2.02.112)
Make tags only when requested via 'make tags'.
Configure supports --disable-dependency-tracking for one-time builds.
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index b7809c7..d3bace7 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1478,6 +1478,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
char *arg_new, *arg;
int i;
int skip_hyphens;
+ int refresh_done = 0;
init_error_message_produced(0);
@@ -1554,6 +1555,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
log_error("Updated config file invalid. Aborting.");
return ECMD_FAILED;
}
+ refresh_done = 1;
}
if (!_prepare_profiles(cmd))
@@ -1562,7 +1564,11 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
if (!cmd->initialized.connections && !_cmd_no_meta_proc(cmd) && !init_connections(cmd))
return_ECMD_FAILED;
- if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) && !init_filters(cmd, 1))
+ /* Note: Load persistent cache only if we haven't refreshed toolcontext!
+ * If toolcontext has been refreshed, it means config has changed
+ * and we can't rely on persistent cache anymore.
+ */
+ if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) && !init_filters(cmd, !refresh_done))
return_ECMD_FAILED;
if (arg_count(cmd, readonly_ARG))
8 years, 7 months