summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2019-02-05 11:32:54 -0600
committerDavid Teigland <teigland@redhat.com>2019-04-11 12:03:04 -0500
commit4eff1da46f80eba498e4cf16e6a84046068a42da (patch)
treeae3b15758786525ce12a0a11b908215104f55908
parentd0b869e46a935003c8ed99dbbbd2d2e745315ff6 (diff)
downloadlvm2-4eff1da46f80eba498e4cf16e6a84046068a42da.tar.gz
separate code for setting devices from metadata parsing
Pull the code that sets devs for PVs out of the metadata parsing code and call it separately.
-rw-r--r--lib/format_text/archiver.c3
-rw-r--r--lib/format_text/import.c8
-rw-r--r--lib/format_text/import_vsn1.c39
-rw-r--r--lib/metadata/metadata.c75
-rw-r--r--lib/metadata/metadata.h2
-rw-r--r--tools/pvscan.c2
6 files changed, 87 insertions, 42 deletions
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 34eff55f5..052c2bd2b 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -320,6 +320,9 @@ struct volume_group *backup_read_vg(struct cmd_context *cmd,
break;
}
+ if (vg)
+ set_pv_devices(tf, vg);
+
if (!vg)
tf->fmt->ops->destroy_instance(tf);
diff --git a/lib/format_text/import.c b/lib/format_text/import.c
index d487100b9..64fbb08b9 100644
--- a/lib/format_text/import.c
+++ b/lib/format_text/import.c
@@ -229,9 +229,11 @@ static struct volume_group *_import_vg_from_config_tree(const struct dm_config_t
*/
if (!(vg = (*vsn)->read_vg(fid, cft, allow_lvmetad_extensions)))
stack;
- else if ((vg_missing = vg_missing_pv_count(vg))) {
- log_verbose("There are %d physical volumes missing.",
- vg_missing);
+ else {
+ set_pv_devices(fid, vg);
+
+ if ((vg_missing = vg_missing_pv_count(vg)))
+ log_verbose("There are %d physical volumes missing.", vg_missing);
vg_mark_partial_lvs(vg, 1);
/* FIXME: move this code inside read_vg() */
}
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index c9b927524..43ec10beb 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -206,21 +206,6 @@ static int _read_pv(struct format_instance *fid,
pv->is_labelled = 1; /* All format_text PVs are labelled. */
- /*
- * Convert the uuid into a device.
- */
- if (!(pv->dev = lvmcache_device_from_pvid(fid->fmt->cmd, &pv->id, &pv->label_sector))) {
- char buffer[64] __attribute__((aligned(8)));
-
- if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
- buffer[0] = '\0';
-
- if (fid->fmt->cmd && !fid->fmt->cmd->pvscan_cache_single)
- log_error_once("Couldn't find device with uuid %s.", buffer);
- else
- log_debug_metadata("Couldn't find device with uuid %s.", buffer);
- }
-
if (!(pv->vg_name = dm_pool_strdup(mem, vg->name)))
return_0;
@@ -231,15 +216,6 @@ static int _read_pv(struct format_instance *fid,
return 0;
}
- if (!pv->dev)
- pv->status |= MISSING_PV;
-
- if ((pv->status & MISSING_PV) && pv->dev && pv_mda_used_count(pv) == 0) {
- pv->status &= ~MISSING_PV;
- log_info("Recovering a previously MISSING PV %s with no MDAs.",
- pv_dev_name(pv));
- }
-
/* Late addition */
if (dm_config_has_node(pvn, "dev_size") &&
!_read_uint64(pvn, "dev_size", &pv->size)) {
@@ -292,21 +268,6 @@ static int _read_pv(struct format_instance *fid,
pv->pe_align = 0;
pv->fmt = fid->fmt;
- /* Fix up pv size if missing or impossibly large */
- if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
- if (!dev_get_size(pv->dev, &pv->size)) {
- log_error("%s: Couldn't get size.", pv_dev_name(pv));
- return 0;
- }
- log_verbose("Fixing up missing size (%s) "
- "for PV %s", display_size(fid->fmt->cmd, pv->size),
- pv_dev_name(pv));
- size = pv->pe_count * (uint64_t) vg->extent_size + pv->pe_start;
- if (size > pv->size)
- log_warn("WARNING: Physical Volume %s is too large "
- "for underlying device", pv_dev_name(pv));
- }
-
if (!alloc_pv_segment_whole_pv(mem, pv))
return_0;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index c50e63364..865f0d1c2 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3866,6 +3866,9 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
continue;
}
+ if (vg)
+ set_pv_devices(fid, vg);
+
/* Use previous VG because checksum matches */
if (!vg) {
vg = correct_vg;
@@ -4073,6 +4076,9 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
continue;
}
+ if (vg)
+ set_pv_devices(fid, vg);
+
/* Use previous VG because checksum matches */
if (!vg) {
vg = correct_vg;
@@ -4498,6 +4504,75 @@ bad:
return NULL;
}
+/*
+ * FIXME: we only want to print the warnings when this is called from
+ * vg_read, not from import_vg_from_metadata, so do the warnings elsewhere
+ * or avoid calling this from import_vg_from.
+ */
+static void _set_pv_device(struct format_instance *fid,
+ struct volume_group *vg,
+ struct physical_volume *pv)
+{
+ char buffer[64] __attribute__((aligned(8)));
+ uint64_t size;
+
+ if (!(pv->dev = lvmcache_device_from_pvid(fid->fmt->cmd, &pv->id, &pv->label_sector))) {
+ if (!id_write_format(&pv->id, buffer, sizeof(buffer)))
+ buffer[0] = '\0';
+
+ if (fid->fmt->cmd && !fid->fmt->cmd->pvscan_cache_single)
+ log_error_once("Couldn't find device with uuid %s.", buffer);
+ else
+ log_debug_metadata("Couldn't find device with uuid %s.", buffer);
+ }
+
+ /*
+ * A previous command wrote the VG while this dev was missing, so
+ * the MISSING flag was included in the PV.
+ */
+ if ((pv->status & MISSING_PV) && pv->dev)
+ log_warn("WARNING: VG %s was previously updated while PV %s was missing.", vg->name, dev_name(pv->dev));
+
+ /*
+ * If this command writes the VG, we want the MISSING flag to be
+ * written for this PV with no device.
+ */
+ if (!pv->dev)
+ pv->status |= MISSING_PV;
+
+ /* is this correct? */
+ if ((pv->status & MISSING_PV) && pv->dev && (pv_mda_used_count(pv) == 0)) {
+ pv->status &= ~MISSING_PV;
+ log_info("Found a previously MISSING PV %s with no MDAs.", pv_dev_name(pv));
+ }
+
+ /* Fix up pv size if missing or impossibly large */
+ if ((!pv->size || pv->size > (1ULL << 62)) && pv->dev) {
+ if (!dev_get_size(pv->dev, &pv->size)) {
+ log_error("%s: Couldn't get size.", pv_dev_name(pv));
+ return;
+ }
+ log_verbose("Fixing up missing size (%s) for PV %s", display_size(fid->fmt->cmd, pv->size),
+ pv_dev_name(pv));
+ size = pv->pe_count * (uint64_t) vg->extent_size + pv->pe_start;
+ if (size > pv->size)
+ log_warn("WARNING: Physical Volume %s is too large "
+ "for underlying device", pv_dev_name(pv));
+ }
+}
+
+/*
+ * Finds the 'struct device' that correponds to each PV in the metadata,
+ * and may make some adjustments to vg fields based on the dev properties.
+ */
+void set_pv_devices(struct format_instance *fid, struct volume_group *vg)
+{
+ struct pv_list *pvl;
+
+ dm_list_iterate_items(pvl, &vg->pvs)
+ _set_pv_device(fid, vg, pvl->pv);
+}
+
int get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids,
const char *only_this_vgname, int include_internal)
{
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 8e9c18a6c..a140c29f3 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -502,4 +502,6 @@ struct id pv_vgid(const struct physical_volume *pv);
uint64_t find_min_mda_size(struct dm_list *mdas);
char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tagsl);
+void set_pv_devices(struct format_instance *fid, struct volume_group *vg);
+
#endif
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 6a464907b..aeb2f0cfc 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -605,6 +605,8 @@ static int _online_pvscan_one(struct cmd_context *cmd, struct device *dev,
if (pvid_without_metadata)
*pvid_without_metadata = dm_pool_strdup(cmd->mem, dev->pvid);
fmt->ops->destroy_instance(baton.fid);
+ } else {
+ set_pv_devices(baton.fid, baton.vg);
}
if (baton.vg && vg_is_shared(baton.vg)) {