summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-01-09 16:11:27 -0600
committerDavid Teigland <teigland@redhat.com>2015-01-09 16:17:41 -0600
commitb84326cca4d9c3102385a22b09f994fc4a1ac015 (patch)
tree378f99681afb1c76a65a1433ce22c29cdb6e83f4
parent927d082fe3ae4dd2074b24edbe56fc5d1e197f89 (diff)
downloadlvm2-dev-dct-fix-dup-pv.tar.gz
toollib: munge duplicate pvs for reportingdev-dct-fix-dup-pv
Munge the lvmcache/device/pv info so duplicates can be reported with device-specific info, i.e. different device names and sizes can be seen. There should be better management of duplicate PVs so that hacks like this can be avoided and cleaned up. /dev/loop0 and /dev/loop1 are duplicates dev_size of loop0 is 16m dev_size of loop1 is 32m # pvs -o+dev_size Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0 PV VG Fmt Attr PSize PFree DevSize /dev/loop1 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 PV VG Fmt Attr PSize PFree DevSize /dev/loop1 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 PV /dev/loop1 is selected by duplicate device. PV VG Fmt Attr PSize PFree DevSize /dev/loop1 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 Repeat device /dev/loop1 as duplicate /dev/loop0 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
-rw-r--r--lib/cache/lvmcache.c16
-rw-r--r--lib/cache/lvmcache.h3
-rw-r--r--tools/toollib.c28
3 files changed, 45 insertions, 2 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 746d58cd2..d93494879 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1467,6 +1467,22 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
return 1;
}
+void lvmcache_change_pv_dev(struct cmd_context *cmd, const char *pvid,
+ struct device *dev)
+{
+ struct lvmcache_info *info;
+ char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
+
+ strncpy(pvid_s, pvid, 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;
+}
+
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 d43866dca..d1d131326 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_change_pv_dev(struct cmd_context *cmd, const char *pvid,
+ struct device *dev);
+
#endif
diff --git a/tools/toollib.c b/tools/toollib.c
index 542ac8b39..3aecfbd3d 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -2224,6 +2224,18 @@ static int _device_list_match_pvid(struct dm_list *devices, struct physical_volu
return 0;
}
+static struct device *_device_list_find_pvid(struct dm_list *devices, struct physical_volume *pv)
+{
+ struct device_list *devl;
+
+ dm_list_iterate_items(devl, devices) {
+ if (id_equal((struct id *) devl->dev->pvid, &pv->id))
+ return devl->dev;
+ }
+
+ return 0;
+}
+
static int _process_device_list(struct cmd_context *cmd, struct dm_list *all_devices,
void *handle, process_single_pv_fn_t process_single_pv)
{
@@ -2349,15 +2361,27 @@ static int _process_pvs_in_vg(struct cmd_context *cmd,
*/
if (!skip && !dm_list_empty(arg_devices) && !dm_list_empty(arg_duplicates) &&
_device_list_match_pvid(arg_devices, pv)) {
- log_warn("PV %s is repeated for duplicate command arg.", pv_name);
+ struct device *dev_dup;
- _device_list_remove_pvid(arg_devices, pv);
+ /* Munge things so PV now looks like it's on dev_dup. */
+
+ dev_dup = _device_list_find_pvid(arg_devices, pv);
+ if (dev_dup) {
+ log_warn("Repeat device %s as duplicate %s",
+ dev_name(pv->dev), dev_name(dev_dup));
+
+ lvmcache_change_pv_dev(cmd, (const char *)&pv->id, dev_dup);
+ pv->dev = dev_dup;
+ /* Swap things back after process_single? */
+ }
ret = process_single_pv(cmd, vg, pv, handle);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
ret_max = ret;
+
+ _device_list_remove_pvid(arg_devices, pv);
}
}