mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-08 08:58:50 +03:00
scan: add PV summary info to lvmcache
Expand the lvmcache info that is saved by the scan to include PV info from the metadata.
This commit is contained in:
parent
0c23d3fc84
commit
f3084ee2e5
16
lib/cache/lvmcache.c
vendored
16
lib/cache/lvmcache.c
vendored
@ -53,6 +53,7 @@ struct lvmcache_vginfo {
|
||||
struct dm_list list; /* Join these vginfos together */
|
||||
struct dm_list infos; /* List head for lvmcache_infos */
|
||||
struct dm_list outdated_infos; /* vg_read moves info from infos to outdated_infos */
|
||||
struct dm_list pvsummaries; /* pv_list taken directly from vgsummary */
|
||||
const struct format_type *fmt;
|
||||
char *vgname; /* "" == orphan */
|
||||
uint32_t status;
|
||||
@ -1295,6 +1296,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
}
|
||||
dm_list_init(&vginfo->infos);
|
||||
dm_list_init(&vginfo->outdated_infos);
|
||||
dm_list_init(&vginfo->pvsummaries);
|
||||
|
||||
/*
|
||||
* A different VG (different uuid) can exist with the same name.
|
||||
@ -1418,6 +1420,18 @@ int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
|
||||
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
|
||||
}
|
||||
|
||||
static void _lvmcache_update_pvsummaries(struct lvmcache_vginfo *vginfo, struct lvmcache_vgsummary *vgsummary)
|
||||
{
|
||||
struct pv_list *pvl, *safe;
|
||||
|
||||
dm_list_init(&vginfo->pvsummaries);
|
||||
|
||||
dm_list_iterate_items_safe(pvl, safe, &vgsummary->pvsummaries) {
|
||||
dm_list_del(&pvl->list);
|
||||
dm_list_add(&vginfo->pvsummaries, &pvl->list);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returning 0 causes the caller to remove the info struct for this
|
||||
* device from lvmcache, which will make it look like a missing device.
|
||||
@ -1582,6 +1596,8 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
|
||||
log_error("Failed to update VG %s info in lvmcache.", vgname);
|
||||
}
|
||||
|
||||
_lvmcache_update_pvsummaries(vginfo, vgsummary);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
12
lib/cache/lvmcache.h
vendored
12
lib/cache/lvmcache.h
vendored
@ -41,14 +41,9 @@ struct lvmcache_vginfo;
|
||||
|
||||
/*
|
||||
* vgsummary represents a summary of the VG that is read
|
||||
* without a lock. The info does not come through vg_read(),
|
||||
* but through reading mdas. It provides information about
|
||||
* the VG that is needed to lock the VG and then read it fully
|
||||
* with vg_read(), after which the VG summary should be checked
|
||||
* against the full VG metadata to verify it was correct (since
|
||||
* it was read without a lock.)
|
||||
*
|
||||
* Once read, vgsummary information is saved in lvmcache_vginfo.
|
||||
* without a lock during label scan. It's used to populate
|
||||
* basic lvmcache vginfo/info during label scan prior to
|
||||
* vg_read().
|
||||
*/
|
||||
struct lvmcache_vgsummary {
|
||||
const char *vgname;
|
||||
@ -63,6 +58,7 @@ struct lvmcache_vgsummary {
|
||||
int mda_num; /* 1 = summary from mda1, 2 = summary from mda2 */
|
||||
unsigned mda_ignored:1;
|
||||
unsigned zero_offset:1;
|
||||
struct dm_list pvsummaries;
|
||||
};
|
||||
|
||||
int lvmcache_init(struct cmd_context *cmd);
|
||||
|
@ -278,6 +278,8 @@ static struct raw_locn *_read_metadata_location_vg(struct device_area *dev_area,
|
||||
};
|
||||
int rlocn_was_ignored;
|
||||
|
||||
dm_list_init(&vgsummary_orphan.pvsummaries);
|
||||
|
||||
memcpy(&vgsummary_orphan.vgid, FMT_TEXT_ORPHAN_VG_NAME, sizeof(FMT_TEXT_ORPHAN_VG_NAME));
|
||||
|
||||
rlocn = mdah->raw_locns; /* Slot 0 */
|
||||
|
@ -31,10 +31,12 @@ typedef int (*section_fn) (struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid,
|
||||
struct dm_pool *mem,
|
||||
struct volume_group * vg, const struct dm_config_node * pvn,
|
||||
const struct dm_config_node * vgn,
|
||||
struct dm_hash_table * pv_hash,
|
||||
struct dm_hash_table * lv_hash);
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *pvn,
|
||||
const struct dm_config_node *vgn,
|
||||
struct dm_hash_table *pv_hash,
|
||||
struct dm_hash_table *lv_hash);
|
||||
|
||||
#define _read_int32(root, path, result) \
|
||||
dm_config_get_uint32(root, path, (uint32_t *) (result))
|
||||
@ -176,7 +178,9 @@ static int _read_pv(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid,
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, const struct dm_config_node *pvn,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *pvn,
|
||||
const struct dm_config_node *vgn __attribute__((unused)),
|
||||
struct dm_hash_table *pv_hash,
|
||||
struct dm_hash_table *lv_hash __attribute__((unused)))
|
||||
@ -289,6 +293,49 @@ static int _read_pv(struct cmd_context *cmd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_pvsummary(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid,
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *pvn,
|
||||
const struct dm_config_node *vgn __attribute__((unused)),
|
||||
struct dm_hash_table *pv_hash __attribute__((unused)),
|
||||
struct dm_hash_table *lv_hash __attribute__((unused)))
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct pv_list *pvl;
|
||||
const char *device_hint;
|
||||
|
||||
if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
|
||||
!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv))))
|
||||
return_0;
|
||||
|
||||
pv = pvl->pv;
|
||||
|
||||
if (!(pvn = pvn->child)) {
|
||||
log_error("Empty pv section.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_read_id(&pv->id, pvn, "id"))
|
||||
log_warn("Couldn't read uuid for physical volume.");
|
||||
|
||||
if (dm_config_has_node(pvn, "dev_size") &&
|
||||
!_read_uint64(pvn, "dev_size", &pv->size))
|
||||
log_warn("Couldn't read dev size for physical volume.");
|
||||
|
||||
if (dm_config_get_str(pvn, "device", &device_hint)) {
|
||||
if (!(pv->device_hint = dm_pool_strdup(mem, device_hint)))
|
||||
log_error("Failed to allocate memory for device hint in read_pv.");
|
||||
}
|
||||
|
||||
dm_list_add(&vgsummary->pvsummaries, &pvl->list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
|
||||
{
|
||||
struct lv_segment *comp;
|
||||
@ -538,7 +585,9 @@ static int _read_lvnames(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid __attribute__((unused)),
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, const struct dm_config_node *lvn,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *lvn,
|
||||
const struct dm_config_node *vgn __attribute__((unused)),
|
||||
struct dm_hash_table *pv_hash __attribute__((unused)),
|
||||
struct dm_hash_table *lv_hash)
|
||||
@ -695,7 +744,9 @@ static int _read_historical_lvnames(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid __attribute__((unused)),
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, const struct dm_config_node *hlvn,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *hlvn,
|
||||
const struct dm_config_node *vgn __attribute__((unused)),
|
||||
struct dm_hash_table *pv_hash __attribute__((unused)),
|
||||
struct dm_hash_table *lv_hash __attribute__((unused)))
|
||||
@ -766,7 +817,9 @@ static int _read_historical_lvnames_interconnections(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid __attribute__((unused)),
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, const struct dm_config_node *hlvn,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *hlvn,
|
||||
const struct dm_config_node *vgn __attribute__((unused)),
|
||||
struct dm_hash_table *pv_hash __attribute__((unused)),
|
||||
struct dm_hash_table *lv_hash __attribute__((unused)))
|
||||
@ -878,7 +931,9 @@ static int _read_lvsegs(struct cmd_context *cmd,
|
||||
struct format_type *fmt,
|
||||
struct format_instance *fid,
|
||||
struct dm_pool *mem,
|
||||
struct volume_group *vg, const struct dm_config_node *lvn,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *lvn,
|
||||
const struct dm_config_node *vgn __attribute__((unused)),
|
||||
struct dm_hash_table *pv_hash,
|
||||
struct dm_hash_table *lv_hash)
|
||||
@ -942,7 +997,9 @@ static int _read_sections(struct cmd_context *cmd,
|
||||
struct format_instance *fid,
|
||||
struct dm_pool *mem,
|
||||
const char *section, section_fn fn,
|
||||
struct volume_group *vg, const struct dm_config_node *vgn,
|
||||
struct volume_group *vg,
|
||||
struct lvmcache_vgsummary *vgsummary,
|
||||
const struct dm_config_node *vgn,
|
||||
struct dm_hash_table *pv_hash,
|
||||
struct dm_hash_table *lv_hash,
|
||||
int optional)
|
||||
@ -959,7 +1016,7 @@ static int _read_sections(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
for (n = n->child; n; n = n->sib) {
|
||||
if (!fn(cmd, fmt, fid, mem, vg, n, vgn, pv_hash, lv_hash))
|
||||
if (!fn(cmd, fmt, fid, mem, vg, vgsummary, n, vgn, pv_hash, lv_hash))
|
||||
return_0;
|
||||
}
|
||||
|
||||
@ -971,7 +1028,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
unsigned allow_lvmetad_extensions)
|
||||
{
|
||||
struct cmd_context *cmd = fid->fmt->cmd;
|
||||
struct format_type *fmt = fid->fmt;
|
||||
struct format_type *fmt = (struct format_type *)fid->fmt;
|
||||
struct dm_pool *mem;
|
||||
const struct dm_config_node *vgn;
|
||||
const struct dm_config_value *cv;
|
||||
@ -1126,7 +1183,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
vg->mda_copies = DEFAULT_VGMETADATACOPIES;
|
||||
}
|
||||
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg,
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "physical_volumes", _read_pv, vg, NULL,
|
||||
vgn, pv_hash, lv_hash, 0)) {
|
||||
log_error("Couldn't find all physical volumes for volume "
|
||||
"group %s.", vg->name);
|
||||
@ -1140,21 +1197,21 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg,
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvnames, vg, NULL,
|
||||
vgn, pv_hash, lv_hash, 1)) {
|
||||
log_error("Couldn't read all logical volume names for volume "
|
||||
"group %s.", vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg,
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames, vg, NULL,
|
||||
vgn, pv_hash, lv_hash, 1)) {
|
||||
log_error("Couldn't read all historical logical volumes for volume "
|
||||
"group %s.", vg->name);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg,
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "logical_volumes", _read_lvsegs, vg, NULL,
|
||||
vgn, pv_hash, lv_hash, 1)) {
|
||||
log_error("Couldn't read all logical volumes for "
|
||||
"volume group %s.", vg->name);
|
||||
@ -1162,7 +1219,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
|
||||
}
|
||||
|
||||
if (!_read_sections(cmd, fmt, fid, mem, "historical_logical_volumes", _read_historical_lvnames_interconnections,
|
||||
vg, vgn, pv_hash, lv_hash, 1)) {
|
||||
vg, NULL, vgn, pv_hash, lv_hash, 1)) {
|
||||
log_error("Couldn't read all removed logical volume interconnections "
|
||||
"for volume group %s.", vg->name);
|
||||
goto bad;
|
||||
@ -1270,6 +1327,11 @@ static int _read_vgsummary(const struct format_type *fmt, const struct dm_config
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_read_sections(fmt->cmd, NULL, NULL, mem, "physical_volumes", _read_pvsummary, NULL, vgsummary,
|
||||
vgn, NULL, NULL, 0)) {
|
||||
log_debug("Couldn't read pv summaries");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -498,6 +498,7 @@ static int _text_read(struct labeller *labeller, struct device *dev, void *label
|
||||
if (mda1) {
|
||||
log_debug_metadata("Scanning %s mda1 summary.", dev_name(dev));
|
||||
memset(&vgsummary, 0, sizeof(vgsummary));
|
||||
dm_list_init(&vgsummary.pvsummaries);
|
||||
bad_fields = 0;
|
||||
vgsummary.mda_num = 1;
|
||||
|
||||
@ -541,6 +542,7 @@ static int _text_read(struct labeller *labeller, struct device *dev, void *label
|
||||
if (mda2) {
|
||||
log_debug_metadata("Scanning %s mda2 summary.", dev_name(dev));
|
||||
memset(&vgsummary, 0, sizeof(vgsummary));
|
||||
dm_list_init(&vgsummary.pvsummaries);
|
||||
bad_fields = 0;
|
||||
vgsummary.mda_num = 2;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user