summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2018-05-21 14:20:19 -0500
committerDavid Teigland <teigland@redhat.com>2018-05-21 16:48:02 -0500
commit3c9ed33f83c90aa15e57ba6dc12d8f1a80afab6d (patch)
tree1fbdd2aa2158be395d383dc9d486d6b27dfabe04 /lib
parent73ae68e1c4308c3391fe3b21f2c721f659343f98 (diff)
downloadlvm2-3c9ed33f83c90aa15e57ba6dc12d8f1a80afab6d.tar.gz
scan: move warnings about duplicate devices
We have been warning about duplicate devices (and disabling lvmetad) immediately when the dup was detected (during label_scan). Move the warnings (and the disabling) to happen later, after label_scan is finished. This lets us avoid an unwanted warning message about duplicates in the special case were md components are eliminated during the duplicate device resolution.
Diffstat (limited to 'lib')
-rw-r--r--lib/cache/lvmcache.c125
-rw-r--r--lib/cache/lvmcache.h2
-rw-r--r--lib/cache/lvmetad.c2
-rw-r--r--lib/device/device.h1
4 files changed, 113 insertions, 17 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 991299561..c306a3aa9 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -981,11 +981,25 @@ int lvmcache_dev_is_unchosen_duplicate(struct device *dev)
* The actual filters are evaluated too early, before a complete
* picture of all PVs is available, to eliminate these duplicates.
*
- * By removing the filtered duplicates from unused_duplicate_devs, we remove
+ * By removing some duplicates from unused_duplicate_devs here, we remove
* the restrictions that are placed on using duplicate devs or VGs with
* duplicate devs.
*
- * There may other kinds of duplicates that we want to ignore.
+ * In cases where we know that two duplicates refer to the same underlying
+ * storage, and we know which dev path to use, it's best for us to just
+ * use that one preferred device path and ignore the others. It is the cases
+ * where we are unsure whether dups refer to the same underlying storage where
+ * we need to keep the unused duplicate referenced in the
+ * unused_duplicate_devs list, and restrict what we allow done with it.
+ *
+ * In the case of md components, we usually filter these out in filter-md,
+ * but in the special case of md superblocks <= 1.0 where the superblock
+ * is at the end of the device, filter-md doesn't always eliminate them
+ * first, so we eliminate them here.
+ *
+ * There may other kinds of duplicates that we want to eliminate at
+ * this point (using the knowledge from the scan) that we couldn't
+ * eliminate in the filters prior to the scan.
*/
static void _filter_duplicate_devs(struct cmd_context *cmd)
@@ -1004,6 +1018,34 @@ static void _filter_duplicate_devs(struct cmd_context *cmd)
dm_free(devl);
}
}
+
+ if (dm_list_empty(&_unused_duplicate_devs))
+ _found_duplicate_pvs = 0;
+}
+
+static void _warn_duplicate_devs(struct cmd_context *cmd)
+{
+ char uuid[64] __attribute__((aligned(8)));
+ struct lvmcache_info *info;
+ struct device_list *devl, *devl2;
+
+ dm_list_iterate_items_safe(devl, devl2, &_unused_duplicate_devs) {
+ if (!id_write_format((const struct id *)devl->dev->pvid, uuid, sizeof(uuid)))
+ stack;
+
+ log_warn("WARNING: Not using device %s for PV %s.", dev_name(devl->dev), uuid);
+ }
+
+ dm_list_iterate_items_safe(devl, devl2, &_unused_duplicate_devs) {
+ /* info for the preferred device that we're actually using */
+ info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0);
+
+ if (!id_write_format((const struct id *)info->dev->pvid, uuid, sizeof(uuid)))
+ stack;
+
+ log_warn("WARNING: PV %s prefers device %s because %s.",
+ uuid, dev_name(info->dev), info->dev->duplicate_prefer_reason);
+ }
}
/*
@@ -1028,7 +1070,6 @@ static void _choose_preferred_devs(struct cmd_context *cmd,
struct dm_list *del_cache_devs,
struct dm_list *add_cache_devs)
{
- char uuid[64] __attribute__((aligned(8)));
const char *reason;
struct dm_list altdevs;
struct dm_list new_unused;
@@ -1229,9 +1270,7 @@ next:
alt = devl;
}
- if (!id_write_format((const struct id *)dev1->pvid, uuid, sizeof(uuid)))
- stack;
- log_warn("WARNING: PV %s prefers device %s because %s.", uuid, dev_name(dev1), reason);
+ dev1->duplicate_prefer_reason = reason;
}
if (dev1 != info->dev) {
@@ -1480,11 +1519,21 @@ int lvmcache_label_scan(struct cmd_context *cmd)
dm_list_splice(&_unused_duplicate_devs, &del_cache_devs);
/*
- * We might want to move the duplicate device warnings until
- * after this filtering so that we can skip warning about
- * duplicates that we are filtering out.
+ * This may remove some entries from the unused_duplicates list for
+ * devs that we know are the same underlying dev.
*/
_filter_duplicate_devs(cmd);
+
+ /*
+ * Warn about remaining duplicates that may actually be separate copies of
+ * the same device.
+ */
+ _warn_duplicate_devs(cmd);
+
+ if (!_found_duplicate_pvs && lvmetad_used()) {
+ log_warn("WARNING: Disabling lvmetad cache which does not support duplicate PVs.");
+ lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
+ }
}
/* Perform any format-specific scanning e.g. text files */
@@ -1509,6 +1558,53 @@ int lvmcache_label_scan(struct cmd_context *cmd)
return r;
}
+/*
+ * When not using lvmetad, lvmcache_label_scan() detects duplicates in
+ * the basic label_scan(), then filters out some dups, and chooses
+ * preferred duplicates to use.
+ *
+ * When using lvmetad, pvscan --cache does not use lvmcache_label_scan(),
+ * only label_scan() which detects the duplicates. This function is used
+ * after pvscan's label_scan() to filter out some dups, print any warnings,
+ * and disable lvmetad if any dups are left.
+ */
+
+void lvmcache_pvscan_duplicate_check(struct cmd_context *cmd)
+{
+ struct device_list *devl;
+
+ /* Check if label_scan() detected any dups. */
+ if (!_found_duplicate_pvs)
+ return;
+
+ /*
+ * Once all the dups are identified, they are moved from the
+ * "found" list to the "unused" list to sort out.
+ */
+ dm_list_splice(&_unused_duplicate_devs, &_found_duplicate_devs);
+
+ /*
+ * Remove items from the dups list that we know are the same
+ * underlying dev, e.g. md components, that we want to just ignore.
+ */
+ _filter_duplicate_devs(cmd);
+
+ /*
+ * If no more dups after ignoring some, then we can use lvmetad.
+ */
+ if (!_found_duplicate_pvs)
+ return;
+
+ /* Duplicates are found where we would have to pick one, so disable lvmetad. */
+
+ dm_list_iterate_items(devl, &_unused_duplicate_devs)
+ log_warn("WARNING: found device with duplicate %s", dev_name(devl->dev));
+
+ log_warn("WARNING: Disabling lvmetad cache which does not support duplicate PVs.");
+ lvmetad_set_disabled(cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
+ lvmetad_make_unused(cmd);
+}
+
int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
struct dm_list *vgnameids)
{
@@ -2303,14 +2399,8 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller,
*/
if (!created) {
if (info->dev != dev) {
- log_warn("WARNING: PV %s on %s was already found on %s.",
- uuid, dev_name(dev), dev_name(info->dev));
-
- if (!_found_duplicate_pvs && lvmetad_used()) {
- log_warn("WARNING: Disabling lvmetad cache which does not support duplicate PVs.");
- lvmetad_set_disabled(labeller->fmt->cmd, LVMETAD_DISABLE_REASON_DUPLICATES);
- }
- _found_duplicate_pvs = 1;
+ log_debug_cache("PV %s on %s was already found on %s.",
+ uuid, dev_name(dev), dev_name(info->dev));
strncpy(dev->pvid, pvid_s, sizeof(dev->pvid));
@@ -2328,6 +2418,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller,
devl->dev = dev;
dm_list_add(&_found_duplicate_devs, &devl->list);
+ _found_duplicate_pvs = 1;
return NULL;
}
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index a2a7f07e6..b988be66c 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -188,6 +188,8 @@ uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info);
int lvmcache_found_duplicate_pvs(void);
+void lvmcache_pvscan_duplicate_check(struct cmd_context *cmd);
+
int lvmcache_get_unused_duplicate_devs(struct cmd_context *cmd, struct dm_list *head);
int vg_has_duplicate_pvs(struct volume_group *vg);
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index 235f72b6f..a1ab41aab 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -2350,6 +2350,8 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait)
label_scan(cmd);
+ lvmcache_pvscan_duplicate_check(cmd);
+
if (lvmcache_found_duplicate_pvs()) {
log_warn("WARNING: Scan found duplicate PVs.");
return 0;
diff --git a/lib/device/device.h b/lib/device/device.h
index 42659cd0f..c8ccd73d9 100644
--- a/lib/device/device.h
+++ b/lib/device/device.h
@@ -75,6 +75,7 @@ struct device {
uint64_t size;
uint64_t end;
struct dev_ext ext;
+ const char *duplicate_prefer_reason;
const char *vgid; /* if device is an LV */
const char *lvid; /* if device is an LV */