1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-02-25 21:57:45 +03:00

lvmetad: use new label_scan for update from lvmlockd

When lvmlockd indicates that the lvmetad cache is out of
date because of changes by another node, lvmetad_pvscan_vg()
rescans the devices in the VG to update lvmetad.  Use the
new label_scan in this function to use the common code and
take advantage of the new aio and reduced reads.
This commit is contained in:
David Teigland 2017-10-26 10:58:23 -05:00
parent 098c843c50
commit 9c71fa0214

437
lib/cache/lvmetad.c vendored
View File

@ -39,7 +39,7 @@ static int64_t _lvmetad_update_timeout;
static int _found_lvm1_metadata = 0; static int _found_lvm1_metadata = 0;
static struct volume_group *_lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg); static struct volume_group *_lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg, const char *vgid, struct format_type *fmt);
static uint64_t _monotonic_seconds(void) static uint64_t _monotonic_seconds(void)
{ {
@ -1093,14 +1093,17 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
* invalidated the cached vg. * invalidated the cached vg.
*/ */
if (rescan) { if (rescan) {
if (!(vg2 = _lvmetad_pvscan_vg(cmd, vg))) { if (!(vg2 = _lvmetad_pvscan_vg(cmd, vg, vgid, fmt))) {
log_debug_lvmetad("VG %s from lvmetad not found during rescan.", vgname); log_debug_lvmetad("VG %s from lvmetad not found during rescan.", vgname);
fid = NULL; fid = NULL;
release_vg(vg); release_vg(vg);
vg = NULL; vg = NULL;
goto out; goto out;
} }
fid->ref_count++;
release_vg(vg); release_vg(vg);
fid->ref_count--;
fmt->ops->destroy_instance(fid);
vg = vg2; vg = vg2;
fid = vg2->fid; fid = vg2->fid;
} }
@ -1108,14 +1111,14 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
dm_list_iterate_items(pvl, &vg->pvs) { dm_list_iterate_items(pvl, &vg->pvs) {
if (!_pv_update_struct_pv(pvl->pv, fid)) { if (!_pv_update_struct_pv(pvl->pv, fid)) {
vg = NULL; vg = NULL;
goto_out; /* FIXME error path */ goto_out; /* FIXME: use an error path that disables lvmetad */
} }
} }
dm_list_iterate_items(pvl, &vg->pvs_outdated) { dm_list_iterate_items(pvl, &vg->pvs_outdated) {
if (!_pv_update_struct_pv(pvl->pv, fid)) { if (!_pv_update_struct_pv(pvl->pv, fid)) {
vg = NULL; vg = NULL;
goto_out; /* FIXME error path */ goto_out; /* FIXME: use an error path that disables lvmetad */
} }
} }
@ -1761,6 +1764,7 @@ int lvmetad_pv_gone_by_dev(struct device *dev)
*/ */
struct _lvmetad_pvscan_baton { struct _lvmetad_pvscan_baton {
struct cmd_context *cmd;
struct volume_group *vg; struct volume_group *vg;
struct format_instance *fid; struct format_instance *fid;
}; };
@ -1771,7 +1775,7 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
struct volume_group *vg; struct volume_group *vg;
if (mda_is_ignored(mda) || if (mda_is_ignored(mda) ||
!(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1))) !(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL)))
return 1; return 1;
/* FIXME Also ensure contents match etc. */ /* FIXME Also ensure contents match etc. */
@ -1783,6 +1787,33 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
return 1; return 1;
} }
/*
* FIXME: handle errors and do proper comparison of metadata from each area
* like vg_read and fall back to real vg_read from disk if there's any problem.
*/
static int _lvmetad_pvscan_vg_single(struct metadata_area *mda, void *baton)
{
struct _lvmetad_pvscan_baton *b = baton;
struct volume_group *vg = NULL;
if (mda_is_ignored(mda))
return 1;
if (!(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL)))
return 1;
if (!b->vg)
b->vg = vg;
else if (vg->seqno > b->vg->seqno) {
release_vg(b->vg);
b->vg = vg;
} else
release_vg(vg);
return 1;
}
/* /*
* The lock manager may detect that the vg cached in lvmetad is out of date, * The lock manager may detect that the vg cached in lvmetad is out of date,
* due to something like an lvcreate from another host. * due to something like an lvcreate from another host.
@ -1792,41 +1823,41 @@ static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
* the VG, and that PV may have been reused for another VG. * the VG, and that PV may have been reused for another VG.
*/ */
static struct volume_group *_lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg) static struct volume_group *_lvmetad_pvscan_vg(struct cmd_context *cmd, struct volume_group *vg,
const char *vgid, struct format_type *fmt)
{ {
char pvid_s[ID_LEN + 1] __attribute__((aligned(8))); char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
char uuid[64] __attribute__((aligned(8))); char uuid[64] __attribute__((aligned(8)));
struct label *label;
struct volume_group *vg_ret = NULL;
struct dm_config_tree *vgmeta_ret = NULL;
struct dm_config_tree *vgmeta; struct dm_config_tree *vgmeta;
struct pv_list *pvl, *pvl_new; struct pv_list *pvl, *pvl_new;
struct device_list *devl, *devl_new, *devlsafe; struct device_list *devl, *devlsafe;
struct dm_list pvs_scan; struct dm_list pvs_scan;
struct dm_list pvs_drop; struct dm_list pvs_drop;
struct dm_list pvs_new; struct lvmcache_vginfo *vginfo = NULL;
struct lvmcache_info *info = NULL; struct lvmcache_info *info = NULL;
struct format_instance *fid; struct format_instance *fid;
struct format_instance_ctx fic = { .type = 0 }; struct format_instance_ctx fic = { .type = 0 };
struct _lvmetad_pvscan_baton baton; struct _lvmetad_pvscan_baton baton;
struct volume_group *save_vg;
struct dm_config_tree *save_meta;
struct device *save_dev = NULL; struct device *save_dev = NULL;
uint32_t save_seqno = 0; uint32_t save_seqno = 0;
int missing_devs = 0; int found_new_pvs = 0;
int check_new_pvs = 0; int retried_reads = 0;
int found; int found;
save_vg = NULL;
save_meta = NULL;
save_dev = NULL;
save_seqno = 0;
dm_list_init(&pvs_scan); dm_list_init(&pvs_scan);
dm_list_init(&pvs_drop); dm_list_init(&pvs_drop);
dm_list_init(&pvs_new);
log_debug_lvmetad("Rescanning VG %s (seqno %u).", vg->name, vg->seqno); log_debug_lvmetad("Rescan VG %s to update lvmetad (seqno %u).", vg->name, vg->seqno);
/* /*
* Another host may have added a PV to the VG, and some * Make sure this command knows about all PVs from lvmetad.
* commands do not always populate their lvmcache with
* all devs from lvmetad, so they would fail to find
* the new PV when scanning the VG. So make sure this
* command knows about all PVs from lvmetad.
*/ */
lvmcache_seed_infos_from_lvmetad(cmd); lvmcache_seed_infos_from_lvmetad(cmd);
@ -1841,54 +1872,111 @@ static struct volume_group *_lvmetad_pvscan_vg(struct cmd_context *cmd, struct v
dm_list_add(&pvs_scan, &devl->list); dm_list_add(&pvs_scan, &devl->list);
} }
scan_more: /*
* Rescan labels/metadata only from devs that we previously
* saw in the VG. If we find below that there are new PVs
* in the VG, we'll have to rescan all devices to find which
* device(s) are now being used.
*/
log_debug_lvmetad("Rescan VG %s scanning data from devs in previous metadata.", vg->name);
label_scan_devs(cmd, &pvs_scan);
/* /*
* Run the equivalent of lvmetad_pvscan_single on each dev in the VG. * Check if any pvs_scan entries are no longer PVs.
* In that case, label_read/_find_label_header will have
* found no label_header, and would have dropped the
* info struct for the device from lvmcache. So, if
* we look up the info struct here and don't find it,
* we can infer it's no longer a PV.
*
* FIXME: we should record specific results from the
* label_read and then check specifically for whatever
* result means "no label was found", rather than going
* about this indirectly via the lvmcache side effects.
*/
dm_list_iterate_items_safe(devl, devlsafe, &pvs_scan) {
if (!(info = lvmcache_info_from_pvid(devl->dev->pvid, devl->dev, 0))) {
/* Another host removed this PV from the VG. */
log_debug_lvmetad("Rescan VG %s from %s dropping dev (no label).",
vg->name, dev_name(devl->dev));
dm_list_move(&pvs_drop, &devl->list);
}
}
fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = vg->name;
fic.context.vg_ref.vg_id = vgid;
retry_reads:
if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
/* FIXME: are there only internal reasons for failures here? */
log_error("Reading VG %s failed to create format instance.", vg->name);
return NULL;
}
/* FIXME: not sure if this is necessary */
fid->ref_count++;
baton.fid = fid;
baton.cmd = cmd;
/*
* FIXME: this vg_read path does not have the ability to repair
* any problems with the VG, e.g. VG on one dev has an older
* seqno. When vg_read() is reworked, we need to fall back
* to using that from here (and vg_read's from lvmetad) when
* there is a problem. Perhaps by disabling lvmetad when a
* VG problem is detected, causing commands to fully fall
* back to disk, which will repair the VG. Then lvmetad can
* be repopulated and re-enabled (possibly automatically.)
*/
/*
* Do a low level vg_read on each dev, verify the vg returned
* from metadata on each device is for the VG being read
* (the PV may have been removed from the VG being read and
* added to a different one), and return this vg to the caller
* as the current vg to use.
*
* The label scan above will have saved in lvmcache which
* vg each device is used in, so we could figure that part
* out without doing the vg_read.
*/ */
dm_list_iterate_items_safe(devl, devlsafe, &pvs_scan) { dm_list_iterate_items_safe(devl, devlsafe, &pvs_scan) {
if (!devl->dev) if (!devl->dev)
continue; continue;
log_debug_lvmetad("Rescan VG %s scanning %s.", vg->name, dev_name(devl->dev)); log_debug_lvmetad("Rescan VG %s getting metadata from %s.",
vg->name, dev_name(devl->dev));
if (!label_read(devl->dev, &label, 0)) {
/* Another host removed this PV from the VG. */
log_debug_lvmetad("Rescan VG %s found %s was removed.", vg->name, dev_name(devl->dev));
if ((info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0)))
lvmcache_del(info);
/*
* The info struct for this dev knows what and where
* the mdas are for this dev (the label scan saved
* the mda locations for this dev on the lvmcache info struct).
*/
if (!(info = lvmcache_info_from_pvid(devl->dev->pvid, devl->dev, 0))) {
log_debug_lvmetad("Rescan VG %s from %s dropping dev (no info).",
vg->name, dev_name(devl->dev));
dm_list_move(&pvs_drop, &devl->list); dm_list_move(&pvs_drop, &devl->list);
continue; continue;
} }
info = (struct lvmcache_info *) label->info;
baton.vg = NULL; baton.vg = NULL;
baton.fid = lvmcache_fmt(info)->ops->create_instance(lvmcache_fmt(info), &fic);
if (!baton.fid)
return_NULL;
if (baton.fid->fmt->features & FMT_OBSOLETE) {
log_debug_lvmetad("Ignoring obsolete format on PV %s in VG %s.", dev_name(devl->dev), vg->name);
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
dm_list_move(&pvs_drop, &devl->list);
continue;
}
/* /*
* Read VG metadata from this dev's mdas. * Read VG metadata from this dev's mdas.
*/ */
lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton); lvmcache_foreach_mda(info, _lvmetad_pvscan_vg_single, &baton);
/* /*
* The PV may have been removed from the VG by another host * The PV may have been removed from the VG by another host
* since we last read the VG. * since we last read the VG.
*/ */
if (!baton.vg) { if (!baton.vg) {
log_debug_lvmetad("Rescan VG %s did not find %s.", vg->name, dev_name(devl->dev)); log_debug_lvmetad("Rescan VG %s from %s dropping dev (no metadata).",
lvmcache_fmt(info)->ops->destroy_instance(baton.fid); vg->name, dev_name(devl->dev));
dm_list_move(&pvs_drop, &devl->list); dm_list_move(&pvs_drop, &devl->list);
continue; continue;
} }
@ -1898,10 +1986,15 @@ scan_more:
* different VG since we last read the VG. * different VG since we last read the VG.
*/ */
if (strcmp(baton.vg->name, vg->name)) { if (strcmp(baton.vg->name, vg->name)) {
log_debug_lvmetad("Rescan VG %s found different VG %s on PV %s.", log_debug_lvmetad("Rescan VG %s from %s dropping dev (other VG %s).",
vg->name, baton.vg->name, dev_name(devl->dev)); vg->name, dev_name(devl->dev), baton.vg->name);
release_vg(baton.vg);
continue;
}
if (!(vgmeta = export_vg_to_config_tree(baton.vg))) {
log_error("VG export to config tree failed");
release_vg(baton.vg); release_vg(baton.vg);
dm_list_move(&pvs_drop, &devl->list);
continue; continue;
} }
@ -1911,20 +2004,35 @@ scan_more:
* read from each other dev. * read from each other dev.
*/ */
if (!save_seqno) if (save_vg && (save_seqno != baton.vg->seqno)) {
save_seqno = baton.vg->seqno; /* FIXME: fall back to vg_read to correct this. */
log_warn("WARNING: inconsistent metadata for VG %s on devices %s seqno %u and %s seqno %u.",
vg->name, dev_name(save_dev), save_seqno,
dev_name(devl->dev), baton.vg->seqno);
log_warn("WARNING: temporarily disable lvmetad to repair metadata.");
if (!(vgmeta = export_vg_to_config_tree(baton.vg))) { /* Use the most recent */
log_error("VG export to config tree failed"); if (save_seqno < baton.vg->seqno) {
release_vg(baton.vg); release_vg(save_vg);
return NULL; dm_config_destroy(save_meta);
save_vg = baton.vg;
save_meta = vgmeta;
save_seqno = baton.vg->seqno;
save_dev = devl->dev;
} else {
release_vg(baton.vg);
dm_config_destroy(vgmeta);
}
continue;
} }
if (!vgmeta_ret) { if (!save_vg) {
vgmeta_ret = vgmeta; save_vg = baton.vg;
save_meta = vgmeta;
save_seqno = baton.vg->seqno;
save_dev = devl->dev; save_dev = devl->dev;
} else { } else {
struct dm_config_node *meta1 = vgmeta_ret->root; struct dm_config_node *meta1 = save_meta->root;
struct dm_config_node *meta2 = vgmeta->root; struct dm_config_node *meta2 = vgmeta->root;
struct dm_config_node *sib1 = meta1->sib; struct dm_config_node *sib1 = meta1->sib;
struct dm_config_node *sib2 = meta2->sib; struct dm_config_node *sib2 = meta2->sib;
@ -1949,73 +2057,128 @@ scan_more:
meta2->sib = NULL; meta2->sib = NULL;
if (compare_config(meta1, meta2)) { if (compare_config(meta1, meta2)) {
/* FIXME: fall back to vg_read to correct this. */
log_warn("WARNING: inconsistent metadata for VG %s on devices %s seqno %u and %s seqno %u.",
vg->name, dev_name(save_dev), save_seqno,
dev_name(devl->dev), baton.vg->seqno);
log_warn("WARNING: temporarily disable lvmetad to repair metadata.");
log_error("VG %s metadata comparison failed for device %s vs %s", log_error("VG %s metadata comparison failed for device %s vs %s",
vg->name, dev_name(devl->dev), save_dev ? dev_name(save_dev) : "none"); vg->name, dev_name(devl->dev), save_dev ? dev_name(save_dev) : "none");
_log_debug_inequality(vg->name, vgmeta_ret->root, vgmeta->root); _log_debug_inequality(vg->name, save_meta->root, vgmeta->root);
meta1->sib = sib1; meta1->sib = sib1;
meta2->sib = sib2; meta2->sib = sib2;
dm_config_destroy(vgmeta);
dm_config_destroy(vgmeta_ret); /* no right choice, just use the previous copy */
release_vg(baton.vg); release_vg(baton.vg);
return NULL; dm_config_destroy(vgmeta);
} }
meta1->sib = sib1; meta1->sib = sib1;
meta2->sib = sib2; meta2->sib = sib2;
release_vg(baton.vg);
dm_config_destroy(vgmeta); dm_config_destroy(vgmeta);
} }
}
/* /* FIXME: see above */
* Look for any new PVs in the VG metadata that were not in our fid->ref_count--;
* previous version of the VG. Add them to pvs_new to be
* scanned in this loop just like the old PVs. /*
*/ * Look for any new PVs in the VG metadata that were not in our
if (!check_new_pvs) { * previous version of the VG.
check_new_pvs = 1; *
dm_list_iterate_items(pvl_new, &baton.vg->pvs) { * (Don't look for new PVs after a rescan and retry.)
found = 0; */
dm_list_iterate_items(pvl, &vg->pvs) { found_new_pvs = 0;
if (pvl_new->pv->dev != pvl->pv->dev)
continue; if (save_vg && !retried_reads) {
found = 1; dm_list_iterate_items(pvl_new, &save_vg->pvs) {
break; found = 0;
} dm_list_iterate_items(pvl, &vg->pvs) {
if (found) if (pvl_new->pv->dev != pvl->pv->dev)
continue; continue;
if (!pvl_new->pv->dev) { found = 1;
strncpy(pvid_s, (char *) &pvl_new->pv->id, sizeof(pvid_s) - 1); break;
if (!id_write_format((const struct id *)&pvid_s, uuid, sizeof(uuid))) }
stack;
log_error("Device not found for PV %s in VG %s", uuid, vg->name); /*
missing_devs++; * PV in new VG metadata not found in old VG metadata.
continue; * There's a good chance we don't know about this new
} * PV or what device it's on; a label scan is needed
if (!(devl_new = dm_pool_zalloc(cmd->mem, sizeof(*devl_new)))) * of all devices so we know which device the VG is
return_NULL; * now using.
devl_new->dev = pvl_new->pv->dev; */
dm_list_add(&pvs_new, &devl_new->list); if (!found) {
log_debug_lvmetad("Rescan VG %s found %s was added.", vg->name, dev_name(devl_new->dev)); found_new_pvs++;
strncpy(pvid_s, (char *) &pvl_new->pv->id, sizeof(pvid_s) - 1);
if (!id_write_format((const struct id *)&pvid_s, uuid, sizeof(uuid)))
stack;
log_debug_lvmetad("Rescan VG %s found new PV %s.", vg->name, uuid);
} }
} }
}
release_vg(baton.vg); if (!save_vg && retried_reads) {
log_error("VG %s not found after rescanning devices.", vg->name);
goto out;
} }
/* /*
* Do the same scanning above for any new PVs. * Do a full rescan of devices, then look up which devices the
* scan found for this VG name, and select those devices to
* read metadata from in the loop above (rather than the list
* of devices we created from our last copy of the vg metadata.)
*
* Case 1: VG we knew is no longer on any of the devices we knew it
* to be on (save_vg is NULL, which means the metadata wasn't found
* when reading mdas on each of the initial pvs_scan devices).
* Rescan all devs and then retry reading metadata from the devs that
* the scan finds associated with this VG.
*
* Case 2: VG has new PVs but we don't know what devices they are
* so rescan all devs and then retry reading metadata from the devs
* that the scan finds associated with this VG.
*
* (N.B. after a retry, we don't check for found_new_pvs.)
*/ */
if (!dm_list_empty(&pvs_new)) { if (!save_vg || found_new_pvs) {
dm_list_init(&pvs_scan); if (!save_vg)
dm_list_splice(&pvs_scan, &pvs_new); log_debug_lvmetad("Rescan VG %s did not find VG on previous devs.", vg->name);
dm_list_init(&pvs_new); if (found_new_pvs)
log_debug_lvmetad("Rescan VG %s found new PVs to scan.", vg->name); log_debug_lvmetad("Rescan VG %s scanning all devs to find new PVs.", vg->name);
goto scan_more;
}
if (missing_devs) { label_scan(cmd);
if (vgmeta_ret)
dm_config_destroy(vgmeta_ret); if (!(vginfo = lvmcache_vginfo_from_vgname(vg->name, NULL))) {
return_NULL; log_error("VG %s vg info not found after rescanning devices.", vg->name);
goto out;
}
/*
* Set pvs_scan to devs that the label scan found
* in the VG and retry the metadata reading loop.
*/
dm_list_init(&pvs_scan);
if (!lvmcache_get_vg_devs(cmd, vginfo, &pvs_scan)) {
log_error("VG %s info devs not found after rescanning devices.", vg->name);
goto out;
}
log_debug_lvmetad("Rescan VG %s has %d PVs after label scan.",
vg->name, dm_list_size(&pvs_scan));
if (save_vg)
release_vg(save_vg);
if (save_meta)
dm_config_destroy(save_meta);
save_vg = NULL;
save_meta = NULL;
save_dev = NULL;
save_seqno = 0;
found_new_pvs = 0;
retried_reads = 1;
goto retry_reads;
} }
/* /*
@ -2024,52 +2187,50 @@ scan_more:
dm_list_iterate_items(devl, &pvs_drop) { dm_list_iterate_items(devl, &pvs_drop) {
if (!devl->dev) if (!devl->dev)
continue; continue;
log_debug_lvmetad("Rescan VG %s dropping %s.", vg->name, dev_name(devl->dev)); log_debug_lvmetad("Rescan VG %s removing %s from lvmetad.", vg->name, dev_name(devl->dev));
if (!lvmetad_pv_gone_by_dev(devl->dev)) if (!lvmetad_pv_gone_by_dev(devl->dev)) {
return_NULL; /* FIXME: use an error path that disables lvmetad */
log_error("Failed to remove %s from lvmetad.", dev_name(devl->dev));
}
} }
/* /*
* Update the VG in lvmetad. * Update lvmetad with the newly read version of the VG.
* When the seqno is unchanged the cached VG can be left.
*/ */
if (vgmeta_ret) { if (save_vg && (save_seqno != vg->seqno)) {
fid = lvmcache_fmt(info)->ops->create_instance(lvmcache_fmt(info), &fic); dm_list_iterate_items(devl, &pvs_scan) {
if (!(vg_ret = import_vg_from_config_tree(vgmeta_ret, fid))) { if (!devl->dev)
log_error("VG import from config tree failed"); continue;
lvmcache_fmt(info)->ops->destroy_instance(fid); log_debug_lvmetad("Rescan VG %s removing %s from lvmetad to replace.",
goto out; vg->name, dev_name(devl->dev));
if (!lvmetad_pv_gone_by_dev(devl->dev)) {
/* FIXME: use an error path that disables lvmetad */
log_error("Failed to remove %s from lvmetad.", dev_name(devl->dev));
}
} }
log_debug_lvmetad("Rescan VG %s updating lvmetad from seqno %u to seqno %u.",
vg->name, vg->seqno, save_seqno);
/* /*
* Update lvmetad with the newly read version of the VG. * If this vg_update fails the cached metadata in
* When the seqno is unchanged the cached VG can be left. * lvmetad will remain invalid.
*/ */
if (save_seqno != vg->seqno) { save_vg->lvmetad_update_pending = 1;
dm_list_iterate_items(devl, &pvs_scan) { if (!lvmetad_vg_update_finish(save_vg)) {
if (!devl->dev) /* FIXME: use an error path that disables lvmetad */
continue; log_error("Failed to update lvmetad with new VG meta");
log_debug_lvmetad("Rescan VG %s dropping to replace %s.", vg->name, dev_name(devl->dev));
if (!lvmetad_pv_gone_by_dev(devl->dev))
return_NULL;
}
log_debug_lvmetad("Rescan VG %s updating lvmetad from seqno %u to seqno %u.",
vg->name, vg->seqno, save_seqno);
/*
* If this vg_update fails the cached metadata in
* lvmetad will remain invalid.
*/
vg_ret->lvmetad_update_pending = 1;
if (!lvmetad_vg_update_finish(vg_ret))
log_error("Failed to update lvmetad with new VG meta");
} }
dm_config_destroy(vgmeta_ret);
} }
out: out:
if (vg_ret) if (!save_vg && fid)
log_debug_lvmetad("Rescan VG %s done (seqno %u).", vg_ret->name, vg_ret->seqno); fmt->ops->destroy_instance(fid);
return vg_ret; if (save_meta)
dm_config_destroy(save_meta);
if (save_vg)
log_debug_lvmetad("Rescan VG %s done (new seqno %u).", save_vg->name, save_vg->seqno);
return save_vg;
} }
int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev, int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,