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

Fix scanning of VGs without in-PV mdas.

Set cmd->independent_metadata_areas if metadata/dirs or disk_areas in use.
- Identify and record this state.

Don't skip full scan when independent mdas are present even if memlock is set.
- Clusters and OOM aren't supported, so no problem doing the proper scans.

Avoid revalidating the label cache immediately after scanning.
- A simple optimisation.

Support scanning for a single VG in independent mdas.
- Not used by the fix but I left it in anyway as later patches might use it.
This commit is contained in:
Alasdair Kergon 2010-12-10 22:39:52 +00:00
parent 706edf60d5
commit acb037657c
8 changed files with 59 additions and 31 deletions

View File

@ -1,5 +1,9 @@
Version 2.02.79 -
===================================
Avoid revalidating the label cache immediately after scanning.
Support scanning for a single VG in independent mdas.
Don't skip full scan when independent mdas are present even if memlock is set.
Set cmd->independent_metadata_areas if metadata/dirs or disk_areas in use.
Cope better with an undefined target_percent operation in _percent_run.
Fix write to released memory in vg_release and rename to free_vg. (2.02.78)

23
lib/cache/lvmcache.c vendored
View File

@ -366,7 +366,7 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname, const char *vgid)
return vginfo;
}
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid, unsigned revalidate_labels)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
@ -379,8 +379,16 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
if (!(vginfo = vginfo_from_vgname(vgname, vgid)))
return NULL;
/* This function is normally called before reading metadata so
* we check cached labels here. Unfortunately vginfo is volatile. */
/*
* If this function is called repeatedly, only the first one needs to revalidate.
*/
if (!revalidate_labels)
goto out;
/*
* This function is normally called before reading metadata so
* we check cached labels here. Unfortunately vginfo is volatile.
*/
dm_list_init(&devs);
dm_list_iterate_items(info, &vginfo->infos) {
if (!(devl = dm_malloc(sizeof(*devl)))) {
@ -405,6 +413,7 @@ const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid)
strncmp(vginfo->vgid, vgid_found, ID_LEN))
return NULL;
out:
return vginfo->fmt;
}
@ -588,10 +597,10 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
_has_scanned = 1;
/* Perform any format-specific scanning e.g. text files */
dm_list_iterate_items(fmt, &cmd->formats) {
if (fmt->ops->scan && !fmt->ops->scan(fmt))
goto out;
}
if (cmd->independent_metadata_areas)
dm_list_iterate_items(fmt, &cmd->formats)
if (fmt->ops->scan && !fmt->ops->scan(fmt, NULL))
goto out;
/*
* If we are a long-lived process, write out the updated persistent

View File

@ -88,7 +88,7 @@ void lvmcache_unlock_vgname(const char *vgname);
int lvmcache_verify_lock_order(const char *vgname);
/* Queries */
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid);
const struct format_type *fmt_from_vgname(const char *vgname, const char *vgid, unsigned revalidate_labels);
struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname,
const char *vgid);
struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid);

View File

@ -1138,6 +1138,7 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
cmd->is_long_lived = is_long_lived;
cmd->handles_missing_pvs = 0;
cmd->handles_unknown_segments = 0;
cmd->independent_metadata_areas = 0;
cmd->hosttags = 0;
dm_list_init(&cmd->arg_value_groups);
dm_list_init(&cmd->formats);
@ -1246,6 +1247,8 @@ static void _destroy_formats(struct cmd_context *cmd, struct dm_list *formats)
dlclose(lib);
#endif
}
cmd->independent_metadata_areas = 0;
}
static void _destroy_segtypes(struct dm_list *segtypes)

View File

@ -78,6 +78,8 @@ struct cmd_context {
unsigned si_unit_consistency:1;
unsigned metadata_read_only:1;
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
struct dev_filter *filter;
int dump_filter; /* Dump filter when exiting? */

View File

@ -1045,7 +1045,7 @@ static int _vg_remove_file(struct format_instance *fid __attribute__((unused)),
return 1;
}
static int _scan_file(const struct format_type *fmt)
static int _scan_file(const struct format_type *fmt, const char *vgname)
{
struct dirent *dirent;
struct dir_list *dl;
@ -1055,7 +1055,7 @@ static int _scan_file(const struct format_type *fmt)
struct volume_group *vg;
struct format_instance *fid;
char path[PATH_MAX];
char *vgname;
char *scanned_vgname;
dir_list = &((struct mda_lists *) fmt->private)->dirs;
@ -1070,18 +1070,23 @@ static int _scan_file(const struct format_type *fmt)
(!(tmp = strstr(dirent->d_name, ".tmp")) ||
tmp != dirent->d_name + strlen(dirent->d_name)
- 4)) {
vgname = dirent->d_name;
scanned_vgname = dirent->d_name;
/* If vgname supplied, only scan that one VG */
if (vgname && strcmp(vgname, scanned_vgname))
continue;
if (dm_snprintf(path, PATH_MAX, "%s/%s",
dl->dir, vgname) < 0) {
dl->dir, scanned_vgname) < 0) {
log_error("Name too long %s/%s",
dl->dir, vgname);
dl->dir, scanned_vgname);
break;
}
/* FIXME stat file to see if it's changed */
fid = _text_create_text_instance(fmt, NULL, NULL,
NULL);
if ((vg = _vg_read_file_name(fid, vgname,
if ((vg = _vg_read_file_name(fid, scanned_vgname,
path))) {
/* FIXME Store creation host in vg */
lvmcache_update_vg(vg, 0);
@ -1195,11 +1200,11 @@ const char *vgname_from_mda(const struct format_type *fmt,
return vgname;
}
static int _scan_raw(const struct format_type *fmt)
static int _scan_raw(const struct format_type *fmt, const char *vgname __attribute__((unused)))
{
struct raw_list *rl;
struct dm_list *raw_list;
const char *vgname;
const char *scanned_vgname;
struct volume_group *vg;
struct format_instance fid;
struct id vgid;
@ -1224,10 +1229,10 @@ static int _scan_raw(const struct format_type *fmt)
goto close_dev;
}
if ((vgname = vgname_from_mda(fmt, mdah,
if ((scanned_vgname = vgname_from_mda(fmt, mdah,
&rl->dev_area, &vgid, &vgstatus,
NULL, NULL))) {
vg = _vg_read_raw_area(&fid, vgname, &rl->dev_area, 0);
vg = _vg_read_raw_area(&fid, scanned_vgname, &rl->dev_area, 0);
if (vg)
lvmcache_update_vg(vg, 0);
@ -1240,9 +1245,9 @@ static int _scan_raw(const struct format_type *fmt)
return 1;
}
static int _text_scan(const struct format_type *fmt)
static int _text_scan(const struct format_type *fmt, const char *vgname)
{
return (_scan_file(fmt) & _scan_raw(fmt));
return (_scan_file(fmt, vgname) & _scan_raw(fmt, vgname));
}
/* For orphan, creates new mdas according to policy.
@ -2181,6 +2186,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
"metadata directory list ", cv->v.str);
goto err;
}
cmd->independent_metadata_areas = 1;
}
}
@ -2188,6 +2194,7 @@ struct format_type *create_text_format(struct cmd_context *cmd)
for (cn = cn->child; cn; cn = cn->sib) {
if (!_get_config_disk_area(cmd, cn, &mda_lists->raws))
goto err;
cmd->independent_metadata_areas = 1;
}
}

View File

@ -2706,13 +2706,14 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
/* Find the vgname in the cache */
/* If it's not there we must do full scan to be completely sure */
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
if (!(fmt = fmt_from_vgname(vgname, vgid, 1))) {
lvmcache_label_scan(cmd, 0);
if (!(fmt = fmt_from_vgname(vgname, vgid))) {
if (memlock())
if (!(fmt = fmt_from_vgname(vgname, vgid, 1))) {
/* Independent MDAs aren't supported under low memory */
if (!cmd->independent_metadata_areas && memlock())
return_NULL;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname, vgid)))
if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
return_NULL;
}
}
@ -2868,10 +2869,11 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
if (!correct_vg) {
inconsistent = 0;
if (memlock())
/* Independent MDAs aren't supported under low memory */
if (!cmd->independent_metadata_areas && memlock())
return_NULL;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname, vgid)))
if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
return_NULL;
if (precommitted && !(fmt->features & FMT_PRECOMMIT))
@ -3795,10 +3797,11 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
/* Find the vgname in the cache */
/* If it's not there we must do full scan to be completely sure */
if (!fmt_from_vgname(vgname, NULL)) {
if (!fmt_from_vgname(vgname, NULL, 1)) {
lvmcache_label_scan(cmd, 0);
if (!fmt_from_vgname(vgname, NULL)) {
if (memlock()) {
if (!fmt_from_vgname(vgname, NULL, 1)) {
/* Independent MDAs aren't supported under low memory */
if (!cmd->independent_metadata_areas && memlock()) {
/*
* FIXME: Disallow calling this function if
* memlock() is true.
@ -3807,7 +3810,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
return FAILED_LOCKING;
}
lvmcache_label_scan(cmd, 2);
if (!fmt_from_vgname(vgname, NULL)) {
if (!fmt_from_vgname(vgname, NULL, 0)) {
/* vgname not found after scanning */
return SUCCESS;
}

View File

@ -227,7 +227,7 @@ struct format_handler {
/*
* Scan any metadata areas that aren't referenced in PV labels
*/
int (*scan) (const struct format_type * fmt);
int (*scan) (const struct format_type * fmt, const char *vgname);
/*
* Return PV with given path.