mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
persistent cache fully incorporated. Goodbye to scanning /dev/cdrom :-)
This commit is contained in:
parent
cc2124ce7d
commit
d2393d23ee
@ -181,6 +181,22 @@ void hash_iterate(struct hash_table *t, iterate_fn f)
|
||||
f(c->data);
|
||||
}
|
||||
|
||||
void hash_wipe(struct hash_table *t)
|
||||
{
|
||||
struct hash_node **c, *old;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < t->num_slots; i++) {
|
||||
c = &t->slots[i];
|
||||
while (*c) {
|
||||
old = *c;
|
||||
*c = (*c)->next;
|
||||
dbg_free(old);
|
||||
t->num_nodes--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *hash_get_key(struct hash_table *t, struct hash_node *n)
|
||||
{
|
||||
return n->key;
|
||||
|
@ -14,6 +14,7 @@ typedef void (*iterate_fn)(void *data);
|
||||
|
||||
struct hash_table *hash_create(unsigned size_hint);
|
||||
void hash_destroy(struct hash_table *t);
|
||||
void hash_wipe(struct hash_table *t);
|
||||
|
||||
void *hash_lookup(struct hash_table *t, const char *key);
|
||||
int hash_insert(struct hash_table *t, const char *key, void *data);
|
||||
|
@ -42,8 +42,8 @@ int persistent_filter_wipe(struct dev_filter *f)
|
||||
{
|
||||
struct pfilter *pf = (struct pfilter *) f->private;
|
||||
|
||||
hash_destroy(pf->devices);
|
||||
return _init_hash(pf);
|
||||
hash_wipe(pf->devices);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _read_array(struct pfilter *pf, struct config_file *cf,
|
||||
@ -53,8 +53,8 @@ static int _read_array(struct pfilter *pf, struct config_file *cf,
|
||||
struct config_value *cv;
|
||||
|
||||
if (!(cn = find_config_node(cf->root, path, '/'))) {
|
||||
log_verbose("Couldn't find 'valid_devices' array in '%s'",
|
||||
pf->file);
|
||||
log_very_verbose("Couldn't find %s array in '%s'",
|
||||
path, pf->file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ static int _read_array(struct pfilter *pf, struct config_file *cf,
|
||||
*/
|
||||
for (cv = cn->v; cv; cv = cv->next) {
|
||||
if (cv->type != CFG_STRING) {
|
||||
log_verbose("Valid_devices array contains a value "
|
||||
log_verbose("Devices array contains a value "
|
||||
"which is not a string ... ignoring");
|
||||
continue;
|
||||
}
|
||||
@ -93,8 +93,10 @@ int persistent_filter_load(struct dev_filter *f)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (_read_array(pf, cf, "/valid_devices", PF_GOOD_DEVICE) &&
|
||||
_read_array(pf, cf, "/invalid_devices", PF_BAD_DEVICE))
|
||||
_read_array(pf, cf, "persistent_filter_cache/valid_devices", PF_GOOD_DEVICE);
|
||||
_read_array(pf, cf, "persistent_filter_cache/invalid_devices", PF_BAD_DEVICE);
|
||||
|
||||
if (hash_get_num_entries(pf->devices))
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
@ -109,7 +111,6 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
int first = 1;
|
||||
struct hash_node *n;
|
||||
|
||||
fprintf(fp, "%s=[\n", path);
|
||||
for (n = hash_get_first(pf->devices); n;
|
||||
n = hash_get_next(pf->devices, n)) {
|
||||
d = hash_get_data(pf->devices, n);
|
||||
@ -119,13 +120,18 @@ static void _write_array(struct pfilter *pf, FILE *fp, const char *path,
|
||||
|
||||
if (!first)
|
||||
fprintf(fp, ",\n");
|
||||
else
|
||||
else {
|
||||
fprintf(fp, "\t%s=[\n", path);
|
||||
first = 0;
|
||||
|
||||
fprintf(fp, "\t\"%s\"", hash_get_key(pf->devices, n));
|
||||
}
|
||||
|
||||
fprintf(fp, "\n]\n");
|
||||
fprintf(fp, "\t\t\"%s\"", hash_get_key(pf->devices, n));
|
||||
}
|
||||
|
||||
if (!first)
|
||||
fprintf(fp, "\n\t]\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int persistent_filter_dump(struct dev_filter *f)
|
||||
@ -143,10 +149,12 @@ int persistent_filter_dump(struct dev_filter *f)
|
||||
}
|
||||
|
||||
fprintf(fp, "# This file is automatically maintained by lvm.\n\n");
|
||||
fprintf(fp, "persistent_filter_cache {\n");
|
||||
|
||||
_write_array(pf, fp, "valid_devices", PF_GOOD_DEVICE);
|
||||
_write_array(pf, fp, "invalid_devices", PF_BAD_DEVICE);
|
||||
|
||||
fprintf(fp, "}\n");
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
13
tools/lvm.c
13
tools/lvm.c
@ -49,6 +49,8 @@ static struct command *_commands;
|
||||
struct io_space *ios;
|
||||
|
||||
static struct dev_filter *_filter;
|
||||
/* Whether or not to dump persistent filter state */
|
||||
static int dump_filter;
|
||||
static struct config_file *_cf;
|
||||
|
||||
static int _interactive;
|
||||
@ -642,6 +644,8 @@ static struct dev_filter *filter_setup(void)
|
||||
struct dev_filter *f3, *f4;
|
||||
struct stat st;
|
||||
|
||||
dump_filter = 0;
|
||||
|
||||
if (!(f3 = filter_components_setup()))
|
||||
return 0;
|
||||
|
||||
@ -650,9 +654,13 @@ static struct dev_filter *filter_setup(void)
|
||||
|
||||
if (!(f4 = persistent_filter_create(f3, lvm_cache))) {
|
||||
log_error("Failed to create persistent device filter");
|
||||
return f3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Should we ever dump persistent filter state? */
|
||||
if (find_config_int(_cf->root, "devices/write_cache_state", '/', 1))
|
||||
dump_filter = 1;
|
||||
|
||||
if (!stat(lvm_cache, &st) && !persistent_filter_load(f4))
|
||||
log_verbose("Failed to load existing device cache from %s",
|
||||
lvm_cache);
|
||||
@ -728,6 +736,9 @@ static void __fin_commands(void)
|
||||
|
||||
static void fin(void)
|
||||
{
|
||||
if (dump_filter)
|
||||
persistent_filter_dump(_filter);
|
||||
|
||||
ios->destroy(ios);
|
||||
_filter->destroy(_filter);
|
||||
dev_cache_exit();
|
||||
|
@ -53,8 +53,10 @@ int pvscan(int argc, char **argv)
|
||||
arg_count(exported_ARG) ?
|
||||
"of exported volume group(s)" : "in no volume group");
|
||||
|
||||
log_verbose("Walking through all physical volumes");
|
||||
log_verbose("Wiping cache of LVM-capable devices");
|
||||
persistent_filter_wipe(ios->filter);
|
||||
|
||||
log_verbose("Walking through all physical volumes");
|
||||
if (!(pvs = ios->get_pvs(ios)))
|
||||
return ECMD_FAILED;
|
||||
|
||||
|
@ -29,6 +29,9 @@ int vgscan(int argc, char **argv)
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
log_verbose("Wiping cache of LVM-capable devices");
|
||||
persistent_filter_wipe(ios->filter);
|
||||
|
||||
log_print("Reading all physical volumes (this may take a while...)");
|
||||
|
||||
return process_each_vg(argc, argv, &vgscan_single);
|
||||
|
Loading…
Reference in New Issue
Block a user