Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b64da4d8b52160be…
Commit: b64da4d8b52160be3ab5635b44d7bb06ef619f43
Parent: 3a7c47af0e8840f4f5b5c39294e9f378de386a50
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jan 14 14:38:05 2015 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jan 14 14:47:08 2015 -0600
toollib: search for duplicate PVs only when needed
A full search for duplicate PVs in the case of pvs -a
is only necessary when duplicates have previously been
detected in lvmcache. Use a global variable from lvmcache
to indicate that duplicate PVs exist, so we can skip the
search for duplicates when none exist.
---
lib/cache/lvmcache.c | 15 ++++++++++++++-
lib/cache/lvmcache.h | 2 ++
tools/toollib.c | 4 +---
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 6cdf766..6a9a05f 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -76,6 +76,7 @@ static int _scanning_in_progress = 0;
static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
+static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
int lvmcache_init(void)
{
@@ -402,6 +403,16 @@ int lvmcache_vgs_locked(void)
return _vgs_locked;
}
+/*
+ * When lvmcache sees a duplicate PV, this is set.
+ * process_each_pv() can avoid searching for duplicates
+ * by checking this and seeing that no duplicate PVs exist.
+ */
+int lvmcache_found_duplicate_pvs(void)
+{
+ return _found_duplicate_pvs;
+}
+
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
struct lvmcache_info *info)
{
@@ -1560,10 +1571,12 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
//dm_is_dm_major(MAJOR(dev->dev)))
//
- else if (!strcmp(pvid_s, existing->dev->pvid))
+ else if (!strcmp(pvid_s, existing->dev->pvid)) {
log_error("Found duplicate PV %s: using %s not "
"%s", pvid, dev_name(dev),
dev_name(existing->dev));
+ _found_duplicate_pvs = 1;
+ }
}
if (strcmp(pvid_s, existing->dev->pvid))
log_debug_cache("Updating pvid cache to %s (%s) from %s (%s)",
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 7a04917..0a7d898 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -160,4 +160,6 @@ uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info);
void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
struct device *dev);
+int lvmcache_found_duplicate_pvs(void);
+
#endif
diff --git a/tools/toollib.c b/tools/toollib.c
index 41e1581..17a9c71 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -2329,11 +2329,9 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
* duplicate devices are being displayed by pvs -a, and
* we want each of them to be displayed in the context
* of this VG, so that this VG name appears next to it.
- * FIXME: the repeated search through all devices is a
- * high cost to pay for a very rare benefit.
*/
- if (process_all_devices) {
+ if (process_all_devices && lvmcache_found_duplicate_pvs()) {
while ((dil = _device_list_find_pvid(all_devices, pv))) {
_device_list_remove(all_devices, dil->dev);
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3a7c47af0e8840f4…
Commit: 3a7c47af0e8840f4f5b5c39294e9f378de386a50
Parent: 57d74a45a05ef14655fbb575586738b6a4cfd4da
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jan 14 14:16:03 2015 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jan 14 14:16:03 2015 -0600
toollib: pvs -a should display VG name for each duplicate PV
Previously, 'pvs -a' displayed the VG name for only the device
associated with the cached PV (pv->dev), and other duplicate
devices would have a blank VG name. This commit displays the
VG name for each of the duplicate devices. The cost of doing
this is not small: for each PV processed, the list of all
devices must be searched for duplicates.
---
tools/toollib.c | 45 ++++++++++++++++++++++++++++++++++++++-------
1 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index 472e362..41e1581 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -2126,6 +2126,7 @@ static int _get_all_devices(struct cmd_context *cmd, struct dm_list *all_devices
goto out;
}
+ strncpy(dil->pvid, dev->pvid, ID_LEN);
dil->dev = dev;
dm_list_add(all_devices, &dil->list);
}
@@ -2213,7 +2214,8 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
struct dm_list *all_devices,
struct dm_list *arg_devices,
struct dm_list *arg_tags,
- int process_all,
+ int process_all_pvs,
+ int process_all_devices,
int skip,
void *handle,
process_single_pv_fn_t process_single_pv)
@@ -2235,7 +2237,7 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
pv = pvl->pv;
pv_name = pv_dev_name(pv);
- process_pv = process_all;
+ process_pv = process_all_pvs;
/* Remove each arg_devices entry as it is processed. */
@@ -2321,12 +2323,38 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
lvmcache_replace_dev(cmd, pv, dev_orig);
}
}
+
+ /*
+ * This is another rare and obscure case where multiple
+ * duplicate devices are being displayed by pvs -a, and
+ * we want each of them to be displayed in the context
+ * of this VG, so that this VG name appears next to it.
+ * FIXME: the repeated search through all devices is a
+ * high cost to pay for a very rare benefit.
+ */
+
+ if (process_all_devices) {
+ while ((dil = _device_list_find_pvid(all_devices, pv))) {
+ _device_list_remove(all_devices, dil->dev);
+
+ dev_orig = pv->dev;
+ lvmcache_replace_dev(cmd, pv, dil->dev);
+
+ ret = process_single_pv(cmd, vg, pv, handle);
+ if (ret != ECMD_PROCESSED)
+ stack;
+ if (ret > ret_max)
+ ret_max = ret;
+
+ lvmcache_replace_dev(cmd, pv, dev_orig);
+ }
+ }
}
/*
* When processing only specific PVs, we can quit once they've all been found.
*/
- if (!process_all && dm_list_empty(arg_tags) && dm_list_empty(arg_devices))
+ if (!process_all_pvs && dm_list_empty(arg_tags) && dm_list_empty(arg_devices))
break;
}
@@ -2349,7 +2377,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
struct dm_list *all_devices,
struct dm_list *arg_devices,
struct dm_list *arg_tags,
- int process_all,
+ int process_all_pvs,
+ int process_all_devices,
void *handle,
process_single_pv_fn_t process_single_pv)
{
@@ -2383,7 +2412,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
*/
ret = _process_pvs_in_vg(cmd, vg, all_devices, arg_devices, arg_tags,
- process_all, skip, handle, process_single_pv);
+ process_all_pvs, process_all_devices, skip,
+ handle, process_single_pv);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
@@ -2395,7 +2425,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
unlock_and_release_vg(cmd, vg, vg->name);
/* Quit early when possible. */
- if (!process_all && dm_list_empty(arg_tags) && dm_list_empty(arg_devices))
+ if (!process_all_pvs && dm_list_empty(arg_tags) && dm_list_empty(arg_devices))
return ret_max;
}
@@ -2470,7 +2500,8 @@ int process_each_pv(struct cmd_context *cmd,
}
ret = _process_pvs_in_vgs(cmd, flags, &all_vgnameids, &all_devices,
- &arg_devices, &arg_tags, process_all_pvs,
+ &arg_devices, &arg_tags,
+ process_all_pvs, process_all_devices,
handle, process_single_pv);
if (ret != ECMD_PROCESSED)
stack;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=57d74a45a05ef146…
Commit: 57d74a45a05ef14655fbb575586738b6a4cfd4da
Parent: c1f246fedfc349c25749da501e68a7f70bd122b0
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jan 13 16:16:22 2015 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Wed Jan 14 11:57:29 2015 -0600
toollib: override the PV device with duplicates
When multiple duplicate devices are specified on the
command line, the PV is processed once for each of them,
but pv->dev is the device used each time.
This overrides the PV device to reflect the duplicate
device that was specified on the command line. This is
done by hacking the lvmcache to replace pv->dev with the
device of the duplicate being processed. (It would be
preferable to override pv->dev without munging the content
of the cache, and without sprinkling special cases throughout
the code.)
This override only applies when multiple duplicate devices are
specified on the command line. When only a single duplicate
device of pv->dev is specified, the priority is to display the
cached pv->dev, so pv->dev is not overridden by the named
duplicate device.
In the examples below, loop3 is the cached device referenced
by pv->dev, and is given priority for processing. Only after
loop3 is processed/displayed, will other duplicate devices
loop0/loop1 appear (when requested on the command line.)
With two duplicate devices, loop0 and loop3:
# pvs
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
PV VG Fmt Attr PSize PFree
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m
# pvs /dev/loop3
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
PV VG Fmt Attr PSize PFree
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m
# pvs /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
PV VG Fmt Attr PSize PFree
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m
# pvs -o+dev_size /dev/loop0 /dev/loop3
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
PV VG Fmt Attr PSize PFree DevSize
/dev/loop0 loopa lvm2 a-- 12.00m 12.00m 16.00m
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
With three duplicate devices, loop0, loop1, loop3:
# pvs -o+dev_size
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop3
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop1
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop3 /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop0 loopa lvm2 a-- 12.00m 12.00m 16.00m
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop3 /dev/loop1
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop1 loopa lvm2 a-- 12.00m 12.00m 32.00m
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop0 /dev/loop1
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop1 loopa lvm2 a-- 12.00m 12.00m 32.00m
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
# pvs -o+dev_size /dev/loop0 /dev/loop1 /dev/loop3
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
PV VG Fmt Attr PSize PFree DevSize
/dev/loop0 loopa lvm2 a-- 12.00m 12.00m 16.00m
/dev/loop1 loopa lvm2 a-- 12.00m 12.00m 32.00m
/dev/loop3 loopa lvm2 a-- 12.00m 12.00m 32.00m
---
lib/cache/lvmcache.c | 21 +++++++++++++++++++++
lib/cache/lvmcache.h | 3 +++
tools/toollib.c | 15 +++++++++++----
3 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 932b1ca..6cdf766 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1467,6 +1467,27 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
return 1;
}
+/*
+ * Replace pv->dev with dev so that dev will appear for reporting.
+ */
+
+void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
+ struct device *dev)
+{
+ struct lvmcache_info *info;
+ char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
+
+ strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1);
+ pvid_s[sizeof(pvid_s) - 1] = '\0';
+
+ if (!(info = lvmcache_info_from_pvid(pvid_s, 0)))
+ return;
+
+ info->dev = dev;
+ info->label->dev = dev;
+ pv->dev = dev;
+}
+
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid,
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index d43866d..7a04917 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -157,4 +157,7 @@ unsigned lvmcache_mda_count(struct lvmcache_info *info);
int lvmcache_vgid_is_cached(const char *vgid);
uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info);
+void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
+ struct device *dev);
+
#endif
diff --git a/tools/toollib.c b/tools/toollib.c
index c534e89..472e362 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -2221,6 +2221,7 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
struct physical_volume *pv;
struct pv_list *pvl;
struct device_id_list *dil;
+ struct device *dev_orig;
const char *pv_name;
int process_pv;
int dev_found;
@@ -2298,11 +2299,14 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
_device_list_remove(arg_devices, dil->dev);
/*
- * This will simply display the same PV
- * multiple times. Further changes would
- * be needed to make this display the details
- * of dil->dev instead of pv->dev.
+ * Replace pv->dev with this dil->dev
+ * in lvmcache so the duplicate dev
+ * info will be reported. FIXME: it
+ * would be nicer to override pv->dev
+ * without munging lvmcache content.
*/
+ dev_orig = pv->dev;
+ lvmcache_replace_dev(cmd, pv, dil->dev);
log_very_verbose("Processing PV %s device %s in VG %s.",
pv_name, dev_name(dil->dev), vg->name);
@@ -2312,6 +2316,9 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
stack;
if (ret > ret_max)
ret_max = ret;
+
+ /* Put the cache state back as it was. */
+ lvmcache_replace_dev(cmd, pv, dev_orig);
}
}
}