1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

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.
This commit is contained in:
David Teigland 2019-02-05 11:32:54 -06:00
parent ef2d61fea8
commit 645dd27604
6 changed files with 87 additions and 54 deletions

View File

@ -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);

View File

@ -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() */
}

View File

@ -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,33 +268,6 @@ static int _read_pv(struct format_instance *fid,
pv->pe_align = 0;
pv->fmt = fid->fmt;
/*
* It would be nice to check this earlier, e.g. in or after label scan,
* but this is first time we get far enough through the vg metadata to
* see the PV size, and can finally compare it with the device size.
*/
if (pv->dev && (pv->size != pv->dev->size)) {
if (dev_is_md_component(pv->dev, NULL, 1)) {
log_warn("WARNING: device %s is an md component, ignoring PV.", dev_name(pv->dev));
return_0;
}
}
/* 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;

View File

@ -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)
{

View File

@ -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

View File

@ -617,6 +617,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)) {