1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

Improve detection of external changes affecting internal cache.

This commit is contained in:
Alasdair Kergon 2005-03-21 22:40:35 +00:00
parent 162d85b97b
commit e5b836d2d6
14 changed files with 119 additions and 23 deletions

View File

@ -1,5 +1,6 @@
Version 2.01.08 - Version 2.01.08 -
================================ ================================
Improve detection of external changes affecting internal cache.
Add 'already in device cache' debug message. Add 'already in device cache' debug message.
Add -a to pvdisplay -C. Add -a to pvdisplay -C.
Avoid rmdir opendir error messsages when dir was already removed. Avoid rmdir opendir error messsages when dir was already removed.

25
lib/cache/lvmcache.c vendored
View File

@ -104,10 +104,30 @@ struct lvmcache_vginfo *vginfo_from_vgname(const char *vgname)
const struct format_type *fmt_from_vgname(const char *vgname) const struct format_type *fmt_from_vgname(const char *vgname)
{ {
struct lvmcache_vginfo *vginfo; struct lvmcache_vginfo *vginfo;
struct label *label;
struct list *ih, *devh, *tmp;
struct list devs;
struct device_list *devl;
if (!(vginfo = vginfo_from_vgname(vgname))) if (!(vginfo = vginfo_from_vgname(vgname)))
return NULL; return NULL;
/* This function is normally called before reading metadata so
* we check cached labels here. Unfortunately vginfo is volatile. */
list_init(&devs);
list_iterate(ih, &vginfo->infos) {
devl = malloc(sizeof(*devl));
devl->dev = list_item(ih, struct lvmcache_info)->dev;
list_add(&devs, &devl->list);
}
list_iterate_safe(devh, tmp, &devs) {
devl = list_item(devh, struct device_list);
label_read(devl->dev, &label);
list_del(&devl->list);
free(devl);
}
return vginfo->fmt; return vginfo->fmt;
} }
@ -403,6 +423,9 @@ int lvmcache_update_vgname(struct lvmcache_info *info, const char *vgname)
/* FIXME Check consistency of list! */ /* FIXME Check consistency of list! */
vginfo->fmt = info->fmt; vginfo->fmt = info->fmt;
log_debug("lvmcache: %s now %s%s", dev_name(info->dev),
*vgname ? "in VG " : "orphaned", vgname);
return 1; return 1;
} }
@ -551,6 +574,8 @@ static void _lvmcache_destroy_lockname(int present)
void lvmcache_destroy(void) void lvmcache_destroy(void)
{ {
log_verbose("Wiping internal VG cache");
_has_scanned = 0; _has_scanned = 0;
if (_vgid_hash) { if (_vgid_hash) {

View File

@ -21,6 +21,7 @@
#include "lvm-types.h" #include "lvm-types.h"
#include "btree.h" #include "btree.h"
#include "filter.h" #include "filter.h"
#include "filter-persistent.h"
#include <unistd.h> #include <unistd.h>
#include <sys/param.h> #include <sys/param.h>
@ -368,6 +369,7 @@ static void _full_scan(int dev_scan)
}; };
_cache.has_scanned = 1; _cache.has_scanned = 1;
init_full_scan_done(1);
} }
int dev_cache_has_scanned(void) int dev_cache_has_scanned(void)
@ -379,15 +381,14 @@ void dev_cache_scan(int do_scan)
{ {
if (!do_scan) if (!do_scan)
_cache.has_scanned = 1; _cache.has_scanned = 1;
else { else
_cache.has_scanned = 0;
_full_scan(1); _full_scan(1);
}
} }
int dev_cache_init(void) int dev_cache_init(void)
{ {
_cache.names = NULL; _cache.names = NULL;
_cache.has_scanned = 0;
if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) { if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
stack; stack;
@ -549,7 +550,14 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
return NULL; return NULL;
} }
_full_scan(dev_scan);
if (dev_scan) {
/* Flag gets reset between each command */
if (!full_scan_done())
persistent_filter_wipe(f); /* Calls _full_scan(1) */
} else
_full_scan(0);
di->current = btree_first(_cache.devices); di->current = btree_first(_cache.devices);
di->filter = f; di->filter = f;

View File

@ -53,7 +53,9 @@ int persistent_filter_wipe(struct dev_filter *f)
{ {
struct pfilter *pf = (struct pfilter *) f->private; struct pfilter *pf = (struct pfilter *) f->private;
log_verbose("Wiping cache of LVM-capable devices");
hash_wipe(pf->devices); hash_wipe(pf->devices);
/* Trigger complete device scan */ /* Trigger complete device scan */
dev_cache_scan(1); dev_cache_scan(1);

View File

@ -188,6 +188,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
size_t len; size_t len;
char vgnamebuf[NAME_LEN + 2]; char vgnamebuf[NAME_LEN + 2];
struct raw_locn *rlocn; struct raw_locn *rlocn;
struct lvmcache_info *info;
rlocn = mdah->raw_locns; rlocn = mdah->raw_locns;
@ -196,7 +197,7 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset, if (!dev_read(dev_area->dev, dev_area->start + rlocn->offset,
sizeof(vgnamebuf), vgnamebuf)) { sizeof(vgnamebuf), vgnamebuf)) {
stack; stack;
return NULL; goto error;
} }
if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) && if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) &&
(isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) { (isspace(vgnamebuf[len]) || vgnamebuf[len] == '{')) {
@ -205,6 +206,10 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
rlocn++; rlocn++;
} }
error:
if ((info = info_from_pvid(dev_area->dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
return NULL; return NULL;
} }
@ -264,7 +269,7 @@ static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
} }
if (!(rlocn = _vg_posn(fid, area, vgname))) { if (!(rlocn = _vg_posn(fid, area, vgname))) {
stack; log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
goto out; goto out;
} }
@ -1183,8 +1188,8 @@ static int _pv_read(const struct format_type *fmt, const char *pv_name,
return 1; return 1;
} }
/* Perform full scan and try again */ /* Perform full scan (just the first time) and try again */
if (!memlock()) { if (!memlock() && !full_scan_done()) {
lvmcache_label_scan(fmt->cmd, 2); lvmcache_label_scan(fmt->cmd, 2);
if (info->vginfo && info->vginfo->vgname && if (info->vginfo && info->vginfo->vgname &&

View File

@ -117,12 +117,17 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
struct labeller_i *li; struct labeller_i *li;
struct labeller *r = NULL; struct labeller *r = NULL;
struct label_header *lh; struct label_header *lh;
struct lvmcache_info *info;
uint64_t sector; uint64_t sector;
int found = 0; int found = 0;
char readbuf[LABEL_SCAN_SIZE]; char readbuf[LABEL_SCAN_SIZE];
if (!dev_open(dev)) { if (!dev_open(dev)) {
stack; stack;
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
return NULL; return NULL;
} }
@ -182,10 +187,13 @@ static struct labeller *_find_labeller(struct device *dev, char *buf,
} }
} }
if (!found)
log_very_verbose("%s: No label detected", dev_name(dev));
out: out:
if (!found) {
if ((info = info_from_pvid(dev->pvid)))
lvmcache_update_vgname(info, ORPHAN);
log_very_verbose("%s: No label detected", dev_name(dev));
}
if (!dev_close(dev)) if (!dev_close(dev))
stack; stack;

View File

@ -30,6 +30,7 @@ static int _test = 0;
static int _partial = 0; static int _partial = 0;
static int _md_filtering = 0; static int _md_filtering = 0;
static int _pvmove = 0; static int _pvmove = 0;
static int _full_scan_done = 0; /* Restrict to one full scan during each cmd */
static int _debug_level = 0; static int _debug_level = 0;
static int _syslog = 0; static int _syslog = 0;
static int _log_to_file = 0; static int _log_to_file = 0;
@ -149,6 +150,11 @@ void init_pvmove(int level)
_pvmove = level; _pvmove = level;
} }
void init_full_scan_done(int level)
{
_full_scan_done = level;
}
void init_ignorelockingfailure(int level) void init_ignorelockingfailure(int level)
{ {
_ignorelockingfailure = level; _ignorelockingfailure = level;
@ -203,6 +209,11 @@ int pvmove_mode()
return _pvmove; return _pvmove;
} }
int full_scan_done()
{
return _full_scan_done;
}
int ignorelockingfailure() int ignorelockingfailure()
{ {
return _ignorelockingfailure; return _ignorelockingfailure;

View File

@ -65,6 +65,7 @@ void init_test(int level);
void init_partial(int level); void init_partial(int level);
void init_md_filtering(int level); void init_md_filtering(int level);
void init_pvmove(int level); void init_pvmove(int level);
void init_full_scan_done(int level);
void init_debug(int level); void init_debug(int level);
void init_cmd_name(int status); void init_cmd_name(int status);
void init_msg_prefix(const char *prefix); void init_msg_prefix(const char *prefix);
@ -78,6 +79,7 @@ int test_mode(void);
int partial_mode(void); int partial_mode(void);
int md_filtering(void); int md_filtering(void);
int pvmove_mode(void); int pvmove_mode(void);
int full_scan_done(void);
int debug_level(void); int debug_level(void);
int ignorelockingfailure(void); int ignorelockingfailure(void);
int security_level(void); int security_level(void);

View File

@ -687,10 +687,46 @@ struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
} }
} }
/* Failed to find VG */ /* Failed to find VG where we expected it - full scan and retry */
if (!correct_vg) { if (!correct_vg) {
stack; inconsistent = 0;
return NULL;
lvmcache_label_scan(cmd, 2);
if (!(fmt = fmt_from_vgname(vgname))) {
stack;
return NULL;
}
/* create format instance with appropriate metadata area */
if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
log_error("Failed to create format instance");
return NULL;
}
/* Ensure contents of all metadata areas match - else recover */
list_iterate(mdah, &fid->metadata_areas) {
mda = list_item(mdah, struct metadata_area);
if (!(vg = mda->ops->vg_read(fid, vgname, mda))) {
inconsistent = 1;
continue;
}
if (!correct_vg) {
correct_vg = vg;
continue;
}
/* FIXME Also ensure contents same - checksums same? */
if (correct_vg->seqno != vg->seqno) {
inconsistent = 1;
if (vg->seqno > correct_vg->seqno)
correct_vg = vg;
}
}
/* Give up looking */
if (!correct_vg) {
stack;
return NULL;
}
} }
lvmcache_update_vg(correct_vg); lvmcache_update_vg(correct_vg);

View File

@ -753,6 +753,7 @@ static void _apply_settings(struct cmd_context *cmd)
init_debug(cmd->current_settings.debug); init_debug(cmd->current_settings.debug);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL); init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
init_test(cmd->current_settings.test); init_test(cmd->current_settings.test);
init_full_scan_done(0);
init_msg_prefix(cmd->default_settings.msg_prefix); init_msg_prefix(cmd->default_settings.msg_prefix);
init_cmd_name(cmd->default_settings.cmd_name); init_cmd_name(cmd->default_settings.cmd_name);

View File

@ -138,8 +138,11 @@ static int _wait_for_single_mirror(struct cmd_context *cmd, const char *name,
while (!finished) { while (!finished) {
/* FIXME Also needed in vg/lvchange -ay? */ /* FIXME Also needed in vg/lvchange -ay? */
/* FIXME Use alarm for regular intervals instead */ /* FIXME Use alarm for regular intervals instead */
if (parms->interval && !parms->aborting) if (parms->interval && !parms->aborting) {
sleep(parms->interval); sleep(parms->interval);
/* Devices might have changed while we slept */
init_full_scan_done(0);
}
/* Locks the (possibly renamed) VG again */ /* Locks the (possibly renamed) VG again */
if (!(vg = parms->poll_fns->get_copy_vg(cmd, name))) { if (!(vg = parms->poll_fns->get_copy_vg(cmd, name))) {

View File

@ -63,10 +63,10 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
/* Is there an md superblock here? */ /* Is there an md superblock here? */
if (!dev && md_filtering()) { if (!dev && md_filtering()) {
unlock_vg(cmd, ""); unlock_vg(cmd, "");
log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter); persistent_filter_wipe(cmd->filter);
log_verbose("Wiping internal cache");
lvmcache_destroy(); lvmcache_destroy();
init_md_filtering(0); init_md_filtering(0);
if (!lock_vol(cmd, "", LCK_VG_WRITE)) { if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs"); log_error("Can't get lock for orphan PVs");

View File

@ -123,10 +123,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, exported_ARG) ? arg_count(cmd, exported_ARG) ?
"of exported volume group(s)" : "in no volume group"); "of exported volume group(s)" : "in no volume group");
log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter); persistent_filter_wipe(cmd->filter);
log_verbose("Wiping internal cache");
lvmcache_destroy(); lvmcache_destroy();
log_verbose("Walking through all physical volumes"); log_verbose("Walking through all physical volumes");

View File

@ -48,10 +48,7 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE; return EINVALID_CMD_LINE;
} }
log_verbose("Wiping cache of LVM-capable devices");
persistent_filter_wipe(cmd->filter); persistent_filter_wipe(cmd->filter);
log_verbose("Wiping internal cache");
lvmcache_destroy(); lvmcache_destroy();
log_print("Reading all physical volumes. This may take a while..."); log_print("Reading all physical volumes. This may take a while...");