Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=772b54a08bae19f5…
Commit: 772b54a08bae19f59d93ca456691e3ce3cbb00da
Parent: e593213b875e96a3de77594f7ce8dd1809a930a0
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 24 10:06:58 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jul 29 14:27:32 2015 -0500
vgcreate: improve checks for existing global lock
This tries harder to avoid creating duplicate global locks in
sanlock VGs by refusing to create a new sanlock VG with a
global lock if other sanlock VGs exist that may have a gl.
---
daemons/lvmlockd/lvmlockd-core.c | 6 -----
lib/cache/lvmcache.c | 13 +++++++++++
lib/cache/lvmcache.h | 2 +
lib/locking/lvmlockd.c | 45 +++++++++++++++++++++++++++++--------
4 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index 7375d9e..1361569 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -3341,12 +3341,6 @@ static void client_send_result(struct client *cl, struct action *act)
* or if lockspaces exist, but not one with the global lock.
* Given this detail, it may be able to procede without
* the lock.
- *
- * FIXME: it would also help the caller to know if there
- * are other sanlock VGs that have not been started.
- * If there are, then one of them might have a global
- * lock enabled. In that case, vgcreate may not want
- * to create a new sanlock vg with gl enabled.
*/
pthread_mutex_lock(&lockspaces_mutex);
if (list_empty(&lockspaces))
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 36926f2..cfa1d5f 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -2345,3 +2345,16 @@ int lvmcache_lookup_mda(struct lvmcache_vgsummary *vgsummary)
return 0;
}
+
+int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd)
+{
+ struct lvmcache_vginfo *vginfo;
+
+ dm_list_iterate_items(vginfo, &_vginfos) {
+ if (vginfo->lock_type && !strcmp(vginfo->lock_type, "sanlock"))
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 008b194..76b9b10 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -188,4 +188,6 @@ int lvmcache_found_duplicate_pvs(void);
void lvmcache_set_preferred_duplicates(const char *vgid);
+int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
+
#endif
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index e9d7882..84eb861 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -1177,23 +1177,48 @@ int lockd_gl_create(struct cmd_context *cmd, const char *def_mode, const char *v
* skip acquiring the global lock when creating this initial
* VG, and enable the global lock in this VG.
*
- * Here we assume that this is an initial bootstrap condition
- * based on the fact that lvmlockd has seen no lockd VGs.
- * (A commmand line option could be added to allow the user
- * to make this initial bootstrap condition explicit.)
+ * This initial bootstrap condition is identified based on
+ * two things:
*
- * That assumption might be wrong. It is possible that a global
- * lock does exist in a VG that has not yet been seen. If that
- * VG appears after this creates a new VG with a new enabled
- * global lock, then there will be two VGs containing enabled
- * global locks, and one will need to be disabled by the user.
+ * 1. No sanlock VGs have been started in lvmlockd, causing
+ * lvmlockd to return NO_GL_LS/NO_LOCKSPACES.
+ *
+ * 2. No sanlock VGs are seen in lvmcache after the disk
+ * scan performed in lvmetad_validate_global_cache().
+ *
+ * If both of those are true, we go ahead and create this new
+ * VG which will have the global lock enabled. However, this
+ * has a shortcoming: another sanlock VG may exist that hasn't
+ * appeared to the system yet. If that VG has its global lock
+ * enabled, then when it appears later, duplicate global locks
+ * will be seen, and a warning will indicate that one of them
+ * should be disabled.
+ *
+ * The two bootstrap conditions have another shortcoming to the
+ * opposite effect: other sanlock VGs may be visible to the
+ * system, but none of them have a global lock enabled.
+ * In that case, it would make sense to create this new VG with
+ * an enabled global lock. (FIXME: we could detect that none
+ * of the existing sanlock VGs have a gl enabled and allow this
+ * vgcreate to go ahead.) Enabling the global lock in one of
+ * the existing sanlock VGs is currently the simplest solution.
*/
if ((lockd_flags & LD_RF_NO_GL_LS) &&
(lockd_flags & LD_RF_NO_LOCKSPACES) &&
!strcmp(vg_lock_type, "sanlock")) {
- log_print_unless_silent("Enabling sanlock global lock");
lvmetad_validate_global_cache(cmd, 1);
+ /*
+ * lvmcache holds provisional VG lock_type info because
+ * lvmetad_validate_global_cache did a disk scan.
+ */
+ if (lvmcache_contains_lock_type_sanlock(cmd)) {
+ /* FIXME: we could check that all are started, and then check that none have gl enabled. */
+ log_error("Global lock failed: start existing sanlock VGs to access global lock.");
+ log_error("(If all sanlock VGs are started, enable global lock with lvmlockctl.)");
+ return 0;
+ }
+ log_print_unless_silent("Enabling sanlock global lock");
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e593213b875e96a3…
Commit: e593213b875e96a3de77594f7ce8dd1809a930a0
Parent: 3cd644aeb5cac432a92ad50584973a3430168ed6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jul 24 15:20:37 2015 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jul 29 14:27:32 2015 -0500
lvmcache: add lock_type to VG summary and info structs
vgsummary information contains provisional VG information
that is obtained without holding the VG lock. This info
can be used to lock the VG, and then read it with vg_read().
After the VG is read properly, the vgsummary info should
be verified.
Add the VG lock_type to the vgsummary. It needs to be
known before the VG can be locked and read.
---
lib/cache/lvmcache.c | 30 +++++++++++++++++++++++++-----
lib/cache/lvmcache.h | 12 ++++++++++++
lib/format_text/import_vsn1.c | 7 +++++++
3 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 9f5b83a..36926f2 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -56,6 +56,7 @@ struct lvmcache_vginfo {
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
+ char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
size_t vgmetadata_size;
@@ -1447,7 +1448,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
}
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
- const char *creation_host)
+ const char *creation_host, const char *lock_type)
{
if (!info || !info->vginfo)
return 1;
@@ -1460,11 +1461,11 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
info->vginfo->status = vgstatus;
if (!creation_host)
- return 1;
+ goto set_lock_type;
if (info->vginfo->creation_host && !strcmp(creation_host,
info->vginfo->creation_host))
- return 1;
+ goto set_lock_type;
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
@@ -1478,6 +1479,24 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
log_debug_cache("lvmcache: %s: VG %s: Set creation host to %s.",
dev_name(info->dev), info->vginfo->vgname, creation_host);
+set_lock_type:
+
+ if (!lock_type)
+ goto out;
+
+ if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
+ goto out;
+
+ if (info->vginfo->lock_type)
+ dm_free(info->vginfo->lock_type);
+
+ if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
+ log_error("cache creation host alloc failed for %s",
+ lock_type);
+ return 0;
+ }
+
+out:
return 1;
}
@@ -1546,7 +1565,7 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
vgsummary->creation_host, info->fmt) ||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
- !_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host) ||
+ !_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type) ||
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
return_0;
@@ -1561,7 +1580,8 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
struct lvmcache_vgsummary vgsummary = {
.vgname = vg->name,
.vgstatus = vg->status,
- .vgid = vg->id
+ .vgid = vg->id,
+ .lock_type = vg->lock_type
};
pvid_s[sizeof(pvid_s) - 1] = '\0';
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 780325a..008b194 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -39,11 +39,23 @@ struct disk_locn;
struct lvmcache_vginfo;
+/*
+ * vgsummary represents a summary of the VG that is read
+ * without a lock. The info does not come through vg_read(),
+ * but through reading mdas. It provides information about
+ * the VG that is needed to lock the VG and then read it fully
+ * with vg_read(), after which the VG summary should be checked
+ * against the full VG metadata to verify it was correct (since
+ * it was read without a lock.)
+ *
+ * Once read, vgsummary information is saved in lvmcache_vginfo.
+ */
struct lvmcache_vgsummary {
const char *vgname;
struct id vgid;
uint64_t vgstatus;
char *creation_host;
+ const char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
};
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index a4dcdf1..7888695 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -1031,6 +1031,11 @@ static void _read_desc(struct dm_pool *mem,
*when = u;
}
+/*
+ * It would be more accurate to call this _read_vgsummary().
+ * It is used to read vgsummary information about a VG
+ * before locking and reading the VG via vg_read().
+ */
static int _read_vgname(const struct format_type *fmt, const struct dm_config_tree *cft,
struct lvmcache_vgsummary *vgsummary)
{
@@ -1067,6 +1072,8 @@ static int _read_vgname(const struct format_type *fmt, const struct dm_config_tr
return 0;
}
+ dm_config_get_str(vgn, "lock_type", &vgsummary->lock_type);
+
return 1;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ca0d9a70d15ca44c…
Commit: ca0d9a70d15ca44c1d0d6f65a277c5e2ac7dd161
Parent: cf700151eba483aeedbf790fd66ce1c44e19c707
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 29 13:10:31 2015 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 29 13:16:09 2015 +0200
dmsetup: remove dead code that covered "info -c -o help" case once
The "-o help" is now handled as implicit field and it gets processed
just like any other field - all handled by libdevmapper now.
---
tools/dmsetup.c | 11 ++---------
1 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index e6cc44f..7a26db1 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -3857,15 +3857,8 @@ unknown:
goto out;
}
- if (_switches[COLS_ARG]) {
- if (!_report_init(cmd))
- goto out;
- if (!_report) {
- if (!strcmp(cmd->name, "info"))
- r = 0; /* info -c -o help */
- goto out;
- }
- }
+ if (_switches[COLS_ARG] && !_report_init(cmd))
+ goto out;
#ifdef UDEV_SYNC_SUPPORT
if (!_set_up_udev_support(dev_dir))
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=cf700151eba483ae…
Commit: cf700151eba483aeedbf790fd66ce1c44e19c707
Parent: af1c7bf0c71f9cc132e9cf211eb1512078af0081
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 29 09:43:03 2015 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 29 10:19:12 2015 +0200
cache: fix regression causing some PVs to bypass filters
This is a regression introduced by commit
6c0e44d5a2e82aa160d48e83992e7ca342bc4bdf which changed
the way dev_cache_get fn works - before this patch, when a
device was not found, it fired a full rescan to correct the
cache. However, the change coming with that commit missed
this full_rescan call, causing the lvmcache to still contain
info about PVs which should be filtered now.
Such situation may have happened by coincidence of using
old persistent cache (/etc/lvm/cache/.cache) which does not
reflect the actual state anymore, a device name/symlink which
now points to a device which should be filtered and a fact we
keep info about usable DM devices in .cache no matter what
the filter setting is.
This bug could be hidden though by changes introduced in
commit f1a000a477558e157532d5f2cd2f9c9139d4f87c as it
calls full_rescan earlier before this problem is hit.
But we need to fix this anyway for the dev_cache_get
to be correct if we happen to use the same code path
again somewhere sometime.
For example, simple reproducer was (before commit
1a000a477558e157532d5f2cd2f9c9139d4f87c):
- /dev/sda contains a PV header with UUID y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M
- lvm.conf: filter = [ "r|.*|" ]
- rm -f .cache (to start with clean state)
- dmsetup create test --table "0 8388608 linear /dev/sda 0" (8388608 is
just the size of the /dev/sda device I use in the reproducer)
- pvs (this will create .cache file which contains
"/dev/disk/by-id/lvm-pv-uuid-y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M"
as well as "/dev/mapper/test" and the target node "/dev/dm-1" - all the
usable DM mappings (and their symlinks) get into the .cache file even
though the filter "is set to "ignore all" - we do this - so far it's OK)
- dmsetup remove test (so we end up with /dev/disk/by-id/lvm-pv-uuid-...
pointing to the /dev/sda now since it's the underlying device
containing the actual PV header)
- now calling "pvs" with such .cache file and we get:
$ pvs
PV VG Fmt Attr PSize PFree
/dev/disk/by-id/lvm-pv-uuid-y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M vg lvm2 a-- 4.00g 0
Even though we have set filter = [ "r|.*|" ] in the lvm.conf file!
---
WHATS_NEW | 1 +
lib/device/dev-cache.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index df2a730..436d1d9 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.127 -
=================================
+ Fix regression in cache causing some PVs to bypass filters (2.02.105).
Version 2.02.126 - 24th July 2015
=================================
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index d854e2b..e58ac0f 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -945,7 +945,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
if (d)
dm_hash_remove(_cache.names, name);
log_sys_very_verbose("stat", name);
- return NULL;
+ d = NULL;
}
if (d && (buf.st_rdev != d->dev)) {