1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lib: reduce parsing in vgname_from_mda

Use similar logic as with text_vg_import_fd() and avoid repeated
parsing of same mda and its config tree for vgname_from_mda().

Remember last parsed vgname, vgid and creation_host in labeller
structure and if the  metadata have the same size and checksum,
return this stored info.

TODO: The reuse of labeller struct is not ideal, some lvmcache API for
this functionality would be nicer.
This commit is contained in:
Zdenek Kabelac 2015-03-06 10:24:26 +01:00
parent 7e7411966a
commit a9b28a4f21
7 changed files with 62 additions and 23 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.118 - Version 2.02.118 -
================================= =================================
Reduce number of VG metadata parsing when looking for vgname on a PV.
Avoid reparsing same metadata when reading same metadata from multiple PVs. Avoid reparsing same metadata when reading same metadata from multiple PVs.
Save extra device open/close when scanning device for size. Save extra device open/close when scanning device for size.
Fix seg_monitor field to report status also for mirrors and thick snapshots. Fix seg_monitor field to report status also for mirrors and thick snapshots.

View File

@ -1124,14 +1124,14 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)
} }
const char *vgname_from_mda(const struct format_type *fmt, const char *vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah, struct mda_header *mdah, struct device_area *dev_area,
struct device_area *dev_area, struct id *vgid, uint32_t *mda_checksum, size_t *mda_size,
const char *vgname, struct id *vgid,
uint64_t *vgstatus, char **creation_host, uint64_t *vgstatus, char **creation_host,
uint64_t *mda_free_sectors) uint64_t *mda_free_sectors)
{ {
struct raw_locn *rlocn; struct raw_locn *rlocn;
uint32_t wrap = 0; uint32_t wrap = 0;
const char *vgname = NULL;
unsigned int len = 0; unsigned int len = 0;
char buf[NAME_LEN + 1] __attribute__((aligned(8))); char buf[NAME_LEN + 1] __attribute__((aligned(8)));
char uuid[64] __attribute__((aligned(8))); char uuid[64] __attribute__((aligned(8)));
@ -1182,6 +1182,10 @@ const char *vgname_from_mda(const struct format_type *fmt,
return NULL; return NULL;
} }
/* Check if it could be the same VG */
if ((rlocn->checksum != *mda_checksum) || (rlocn->size != *mda_size))
vgname = NULL; /* nope, reset to NULL */
/* FIXME 64-bit */ /* FIXME 64-bit */
if (!(vgname = text_vgname_import(fmt, dev_area->dev, if (!(vgname = text_vgname_import(fmt, dev_area->dev,
(off_t) (dev_area->start + (off_t) (dev_area->start +
@ -1190,6 +1194,7 @@ const char *vgname_from_mda(const struct format_type *fmt,
(off_t) (dev_area->start + (off_t) (dev_area->start +
MDA_HEADER_SIZE), MDA_HEADER_SIZE),
wrap, calc_crc, rlocn->checksum, wrap, calc_crc, rlocn->checksum,
vgname,
vgid, vgstatus, creation_host))) vgid, vgstatus, creation_host)))
return_NULL; return_NULL;
@ -1217,6 +1222,9 @@ const char *vgname_from_mda(const struct format_type *fmt,
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT; *mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
} }
*mda_checksum = rlocn->checksum;
*mda_size = rlocn->size;
return vgname; return vgname;
} }
@ -1230,6 +1238,8 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
struct id vgid; struct id vgid;
uint64_t vgstatus; uint64_t vgstatus;
struct mda_header *mdah; struct mda_header *mdah;
uint32_t mda_checksum = 0;
size_t mda_size = 0;
raw_list = &((struct mda_lists *) fmt->private)->raws; raw_list = &((struct mda_lists *) fmt->private)->raws;
@ -1249,9 +1259,12 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
goto close_dev; goto close_dev;
} }
/* TODO: caching as in vgname_from_mda() (trigger this code?) */
if ((scanned_vgname = vgname_from_mda(fmt, mdah, if ((scanned_vgname = vgname_from_mda(fmt, mdah,
&rl->dev_area, &vgid, &vgstatus, &rl->dev_area,
NULL, NULL))) { &mda_checksum, &mda_size, NULL,
&vgid, &vgstatus,
NULL, NULL))) {
vg = _vg_read_raw_area(&fid, scanned_vgname, &rl->dev_area, 0, 0); vg = _vg_read_raw_area(&fid, scanned_vgname, &rl->dev_area, 0, 0);
if (vg) if (vg)
lvmcache_update_vg(vg, 0); lvmcache_update_vg(vg, 0);

View File

@ -79,10 +79,11 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
time_t *when, char **desc); time_t *when, char **desc);
const char *text_vgname_import(const struct format_type *fmt, const char *text_vgname_import(const struct format_type *fmt,
struct device *dev, struct device *dev,
off_t offset, uint32_t size, off_t offset, uint32_t size,
off_t offset2, uint32_t size2, off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn, uint32_t checksum, checksum_fn_t checksum_fn, uint32_t checksum,
struct id *vgid, uint64_t *vgstatus, const char *vgname,
struct id *vgid, uint64_t *vgstatus,
char **creation_host); char **creation_host);
#endif #endif

View File

@ -32,17 +32,22 @@ static void _init_text_import(void)
_text_import_initialised = 1; _text_import_initialised = 1;
} }
/*
* Find out vgname on a given device.
* If the checksum and metadata size is matching the vgname discovered in last read
* (multi PVs VG) could be passed back and it may skip parsing of such metadata.
*/
const char *text_vgname_import(const struct format_type *fmt, const char *text_vgname_import(const struct format_type *fmt,
struct device *dev, struct device *dev,
off_t offset, uint32_t size, off_t offset, uint32_t size,
off_t offset2, uint32_t size2, off_t offset2, uint32_t size2,
checksum_fn_t checksum_fn, uint32_t checksum, checksum_fn_t checksum_fn, uint32_t checksum,
const char *vgname,
struct id *vgid, uint64_t *vgstatus, struct id *vgid, uint64_t *vgstatus,
char **creation_host) char **creation_host)
{ {
struct dm_config_tree *cft; struct dm_config_tree *cft;
struct text_vg_version_ops **vsn; struct text_vg_version_ops **vsn;
const char *vgname = NULL;
_init_text_import(); _init_text_import();
@ -51,11 +56,15 @@ const char *text_vgname_import(const struct format_type *fmt,
if ((!dev && !config_file_read(cft)) || if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size, (dev && !config_file_read_fd(cft, dev, offset, size,
offset2, size2, checksum_fn, checksum, 0))) { offset2, size2, checksum_fn, checksum,
(vgname != NULL)))) {
log_error("Couldn't read volume group metadata."); log_error("Couldn't read volume group metadata.");
goto out; goto out;
} }
if (vgname)
goto out; /* Everything is matching from the last call */
/* /*
* Find a set of version functions that can read this file * Find a set of version functions that can read this file
*/ */

View File

@ -100,7 +100,9 @@ struct mda_context {
const char *vgname_from_mda(const struct format_type *fmt, const char *vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah, struct mda_header *mdah,
struct device_area *dev_area, struct id *vgid, struct device_area *dev_area,
uint32_t *mda_checksum, size_t *mda_size,
const char *vgname, struct id *vgid,
uint64_t *vgstatus, char **creation_host, uint64_t *vgstatus, char **creation_host,
uint64_t *mda_free_sectors); uint64_t *mda_free_sectors);

View File

@ -319,10 +319,14 @@ static int _update_mda(struct metadata_area *mda, void *baton)
const struct format_type *fmt = p->label->labeller->fmt; const struct format_type *fmt = p->label->labeller->fmt;
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn; struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
struct mda_header *mdah; struct mda_header *mdah;
const char *vgname = NULL; struct labeller *l = p->label->labeller;
struct id vgid;
uint64_t vgstatus; /*
char *creation_host; * Using the labeller struct to preserve info about
* the last parsed vgname, vgid, creation host
*
* TODO: make lvmcache smarter and move this cache logic there
*/
if (!dev_open_readonly(mdac->area.dev)) { if (!dev_open_readonly(mdac->area.dev)) {
mda_set_ignored(mda, 1); mda_set_ignored(mda, 1);
@ -346,17 +350,18 @@ static int _update_mda(struct metadata_area *mda, void *baton)
return 1; return 1;
} }
if ((vgname = vgname_from_mda(fmt, mdah, if ((l->vgname = vgname_from_mda(fmt, mdah, &mdac->area,
&mdac->area, &l->mda_checksum, &l->mda_size, l->vgname,
&vgid, &vgstatus, &creation_host, &l->vgid, &l->vgstatus, &l->creation_host,
&mdac->free_sectors)) && &mdac->free_sectors)) &&
!lvmcache_update_vgname_and_id(p->info, vgname, !lvmcache_update_vgname_and_id(p->info, l->vgname,
(char *) &vgid, vgstatus, (char *) &l->vgid, l->vgstatus,
creation_host)) { l->creation_host)) {
if (!dev_close(mdac->area.dev)) if (!dev_close(mdac->area.dev))
stack; stack;
return_0; return_0;
} }
close_dev: close_dev:
if (!dev_close(mdac->area.dev)) if (!dev_close(mdac->area.dev))
stack; stack;

View File

@ -89,6 +89,14 @@ struct label_ops {
struct labeller { struct labeller {
struct label_ops *ops; struct label_ops *ops;
const struct format_type *fmt; const struct format_type *fmt;
/* Caching info */
const char *vgname;
struct id vgid;
uint64_t vgstatus;
char *creation_host;
uint32_t mda_checksum;
size_t mda_size;
}; };
int label_init(void); int label_init(void);