mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
label: cache dm device list
Since we check for present DM devices - cache result for futher use of checking presence of such device. lvm2 uses cache result for label scan, but also when it tries to activate or deactivate LV - however only simple target 'striped' is reasonably supported. Use disable_dm_devs to be able to control when lv_info() get cache or uncached results. TODO: support more type, however this is getting very complicated.
This commit is contained in:
parent
0d67bc96fd
commit
04fbffb116
@ -1,5 +1,6 @@
|
|||||||
Version 2.03.15 -
|
Version 2.03.15 -
|
||||||
===================================
|
===================================
|
||||||
|
Use cache or active DM device when available with new kernels.
|
||||||
Introduce function to utilize UUIDs from DM_DEVICE_LIST.
|
Introduce function to utilize UUIDs from DM_DEVICE_LIST.
|
||||||
Increase some hash table size to better support large device sets.
|
Increase some hash table size to better support large device sets.
|
||||||
|
|
||||||
|
@ -2391,6 +2391,7 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
|||||||
static const struct lv_activate_opts laopts = { .skip_in_use = 1 };
|
static const struct lv_activate_opts laopts = { .skip_in_use = 1 };
|
||||||
struct dm_list *snh;
|
struct dm_list *snh;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
unsigned tmp_state;
|
||||||
|
|
||||||
if (!activation())
|
if (!activation())
|
||||||
return 1;
|
return 1;
|
||||||
@ -2463,12 +2464,17 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
|||||||
}
|
}
|
||||||
critical_section_dec(cmd, "deactivated");
|
critical_section_dec(cmd, "deactivated");
|
||||||
|
|
||||||
|
tmp_state = cmd->disable_dm_devs;
|
||||||
|
cmd->disable_dm_devs = 1;
|
||||||
|
|
||||||
if (!lv_info(cmd, lv, 0, &info, 0, 0) || info.exists) {
|
if (!lv_info(cmd, lv, 0, &info, 0, 0) || info.exists) {
|
||||||
/* Turn into log_error, but we do not log error */
|
/* Turn into log_error, but we do not log error */
|
||||||
log_debug_activation("Deactivated volume is still %s present.",
|
log_debug_activation("Deactivated volume is still %s present.",
|
||||||
display_lvname(lv));
|
display_lvname(lv));
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd->disable_dm_devs = tmp_state;
|
||||||
out:
|
out:
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -964,6 +964,16 @@ int dev_manager_info(struct cmd_context *cmd,
|
|||||||
if (!(dlid = build_dm_uuid(cmd->mem, lv, layer)))
|
if (!(dlid = build_dm_uuid(cmd->mem, lv, layer)))
|
||||||
goto_out;
|
goto_out;
|
||||||
|
|
||||||
|
if (!cmd->disable_dm_devs &&
|
||||||
|
cmd->cache_dm_devs &&
|
||||||
|
!dm_device_list_find_by_uuid(cmd->cache_dm_devs, dlid, NULL)) {
|
||||||
|
log_debug("Cached as inactive %s.", name);
|
||||||
|
if (dminfo)
|
||||||
|
memset(dminfo, 0, sizeof(*dminfo));
|
||||||
|
r = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(r = _info(cmd, name, dlid,
|
if (!(r = _info(cmd, name, dlid,
|
||||||
with_open_count, with_read_ahead, with_name_check,
|
with_open_count, with_read_ahead, with_name_check,
|
||||||
dminfo, read_ahead, seg_status)))
|
dminfo, read_ahead, seg_status)))
|
||||||
@ -2245,6 +2255,13 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
|||||||
if (!(dlid = build_dm_uuid(dm->track_pending_delete ? dm->cmd->pending_delete_mem : dm->mem, lv, layer)))
|
if (!(dlid = build_dm_uuid(dm->track_pending_delete ? dm->cmd->pending_delete_mem : dm->mem, lv, layer)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
if (!dm->cmd->disable_dm_devs &&
|
||||||
|
dm->cmd->cache_dm_devs &&
|
||||||
|
!dm_device_list_find_by_uuid(dm->cmd->cache_dm_devs, dlid, NULL)) {
|
||||||
|
log_debug("Cached as not present %s.", name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL))
|
if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
@ -2390,6 +2407,9 @@ static int _pool_callback(struct dm_tree_node *node,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dm_device_list_destroy(&cmd->cache_dm_devs); /* Cache no longer valid */
|
||||||
|
|
||||||
log_debug("Running check command on %s", mpath);
|
log_debug("Running check command on %s", mpath);
|
||||||
|
|
||||||
if (data->skip_zero) {
|
if (data->skip_zero) {
|
||||||
@ -3777,6 +3797,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
|||||||
struct dm_tree_node *root;
|
struct dm_tree_node *root;
|
||||||
char *dlid;
|
char *dlid;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
unsigned tmp_state;
|
||||||
|
|
||||||
if (action < DM_ARRAY_SIZE(_action_names))
|
if (action < DM_ARRAY_SIZE(_action_names))
|
||||||
log_debug_activation("Creating %s%s tree for %s.",
|
log_debug_activation("Creating %s%s tree for %s.",
|
||||||
@ -3796,9 +3817,17 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
|||||||
dm->suspend = (action == SUSPEND_WITH_LOCKFS) || (action == SUSPEND);
|
dm->suspend = (action == SUSPEND_WITH_LOCKFS) || (action == SUSPEND);
|
||||||
dm->track_external_lv_deps = 1;
|
dm->track_external_lv_deps = 1;
|
||||||
|
|
||||||
|
/* ATM do not use caching for anything else then striped target.
|
||||||
|
* And also skip for CLEAN action */
|
||||||
|
tmp_state = dm->cmd->disable_dm_devs;
|
||||||
|
if (!seg_is_striped_target(first_seg(lv)) || (action == CLEAN))
|
||||||
|
dm->cmd->disable_dm_devs = 1;
|
||||||
|
|
||||||
if (!(dtree = _create_partial_dtree(dm, lv, laopts->origin_only)))
|
if (!(dtree = _create_partial_dtree(dm, lv, laopts->origin_only)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
dm->cmd->disable_dm_devs = tmp_state;
|
||||||
|
|
||||||
if (!(root = dm_tree_find_node(dtree, 0, 0))) {
|
if (!(root = dm_tree_find_node(dtree, 0, 0))) {
|
||||||
log_error("Lost dependency tree root node.");
|
log_error("Lost dependency tree root node.");
|
||||||
goto out_no_root;
|
goto out_no_root;
|
||||||
|
@ -2052,6 +2052,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
|
|||||||
if (cmd->cft_def_hash)
|
if (cmd->cft_def_hash)
|
||||||
dm_hash_destroy(cmd->cft_def_hash);
|
dm_hash_destroy(cmd->cft_def_hash);
|
||||||
|
|
||||||
|
dm_device_list_destroy(&cmd->cache_dm_devs);
|
||||||
#ifndef VALGRIND_POOL
|
#ifndef VALGRIND_POOL
|
||||||
if (cmd->linebuffer) {
|
if (cmd->linebuffer) {
|
||||||
/* Reset stream buffering to defaults */
|
/* Reset stream buffering to defaults */
|
||||||
|
@ -203,6 +203,7 @@ struct cmd_context {
|
|||||||
unsigned event_activation:1; /* whether event_activation is set */
|
unsigned event_activation:1; /* whether event_activation is set */
|
||||||
unsigned udevoutput:1;
|
unsigned udevoutput:1;
|
||||||
unsigned online_vg_file_removed:1;
|
unsigned online_vg_file_removed:1;
|
||||||
|
unsigned disable_dm_devs:1; /* temporarily disable use of dm devs cache */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Devices and filtering.
|
* Devices and filtering.
|
||||||
@ -214,6 +215,8 @@ struct cmd_context {
|
|||||||
const char *devicesfile; /* from --devicesfile option */
|
const char *devicesfile; /* from --devicesfile option */
|
||||||
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */
|
struct dm_list deviceslist; /* from --devices option, struct dm_str_list */
|
||||||
|
|
||||||
|
struct dm_list *cache_dm_devs; /* cache with UUIDs from DM_DEVICE_LIST (when available) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configuration.
|
* Configuration.
|
||||||
*/
|
*/
|
||||||
|
@ -1719,6 +1719,41 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
|
||||||
|
{
|
||||||
|
struct dm_list *devs;
|
||||||
|
struct dm_active_device *dm_dev;
|
||||||
|
unsigned devs_features = 0;
|
||||||
|
struct device *dev;
|
||||||
|
struct lv_list *lvl;
|
||||||
|
dev_t devt;
|
||||||
|
|
||||||
|
if (get_device_list(NULL, &devs, &devs_features)) {
|
||||||
|
if (devs_features & DM_DEVICE_LIST_HAS_UUID) {
|
||||||
|
dm_list_iterate_items(dm_dev, devs)
|
||||||
|
if (dm_dev->uuid &&
|
||||||
|
strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) {
|
||||||
|
devt = MKDEV(dm_dev->major, dm_dev->minor);
|
||||||
|
if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL)))
|
||||||
|
label_scan_invalidate(dev);
|
||||||
|
}
|
||||||
|
/* ATM no further caching for any lvconvert command
|
||||||
|
* TODO: any other command to be skipped ??
|
||||||
|
*/
|
||||||
|
if (strcmp(cmd->name, "lvconvert")) {
|
||||||
|
dm_device_list_destroy(&cmd->cache_dm_devs);
|
||||||
|
cmd->cache_dm_devs = devs; /* cache to avoid unneeded checks */
|
||||||
|
devs = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dm_device_list_destroy(&devs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(devs_features & DM_DEVICE_LIST_HAS_UUID))
|
||||||
|
dm_list_iterate_items(lvl, lvs)
|
||||||
|
label_scan_invalidate_lv(cmd, lvl->lv);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Empty the bcache of all blocks and close all open fds,
|
* Empty the bcache of all blocks and close all open fds,
|
||||||
* but keep the bcache set up.
|
* but keep the bcache set up.
|
||||||
|
@ -110,6 +110,7 @@ int label_scan_devs_excl(struct cmd_context *cmd, struct dev_filter *f, struct d
|
|||||||
int label_scan_dev(struct cmd_context *cmd, struct device *dev);
|
int label_scan_dev(struct cmd_context *cmd, struct device *dev);
|
||||||
void label_scan_invalidate(struct device *dev);
|
void label_scan_invalidate(struct device *dev);
|
||||||
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv);
|
void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv);
|
||||||
|
void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs);
|
||||||
void label_scan_drop(struct cmd_context *cmd);
|
void label_scan_drop(struct cmd_context *cmd);
|
||||||
void label_scan_destroy(struct cmd_context *cmd);
|
void label_scan_destroy(struct cmd_context *cmd);
|
||||||
int label_scan_setup_bcache(void);
|
int label_scan_setup_bcache(void);
|
||||||
|
@ -330,6 +330,7 @@ int vg_write_lock_held(void)
|
|||||||
|
|
||||||
int sync_local_dev_names(struct cmd_context* cmd)
|
int sync_local_dev_names(struct cmd_context* cmd)
|
||||||
{
|
{
|
||||||
|
dm_device_list_destroy(&cmd->cache_dm_devs);
|
||||||
memlock_unlock(cmd);
|
memlock_unlock(cmd);
|
||||||
fs_unlock();
|
fs_unlock();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3122,8 +3122,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
* in bcache, and needs to be closed so the open fd doesn't
|
* in bcache, and needs to be closed so the open fd doesn't
|
||||||
* interfere with processing the LV.
|
* interfere with processing the LV.
|
||||||
*/
|
*/
|
||||||
dm_list_iterate_items(lvl, &final_lvs)
|
label_scan_invalidate_lvs(cmd, &final_lvs);
|
||||||
label_scan_invalidate_lv(cmd, lvl->lv);
|
|
||||||
|
|
||||||
dm_list_iterate_items(lvl, &final_lvs) {
|
dm_list_iterate_items(lvl, &final_lvs) {
|
||||||
lv_uuid[0] = '\0';
|
lv_uuid[0] = '\0';
|
||||||
|
Loading…
Reference in New Issue
Block a user