1
0
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:
Zdenek Kabelac 2021-12-15 11:45:22 +01:00
parent 0d67bc96fd
commit 04fbffb116
9 changed files with 78 additions and 2 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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.
*/ */

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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';