mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-30 17:18:21 +03:00
toollib: avoid repeated lvmetad vg_lookup
In process_each_{vg,lv,pv} when no vgname args are given, the first step is to get a list of all vgid/vgname on the system. This is exactly what lvmetad returns from a vg_list request. The current code is doing a vg_lookup on each VG after the vg_list and populating lvmcache with the info for each VG. These preliminary vg_lookup's are unnecessary, because they will be done again when the processing functions call vg_read. This patch eliminates the initial round of vg_lookup's, which can roughly cut in half the number of lvmetad requests and save a lot of extra work.
This commit is contained in:
parent
f25132b354
commit
8e509b5dd5
31
lib/cache/lvmcache.c
vendored
31
lib/cache/lvmcache.c
vendored
@ -905,6 +905,37 @@ int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo
|
||||
}
|
||||
// #endif
|
||||
|
||||
int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
|
||||
struct dm_list *vgnameids)
|
||||
{
|
||||
struct vgnameid_list *vgnl;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
|
||||
dm_list_iterate_items(vginfo, &_vginfos) {
|
||||
if (!include_internal && is_orphan_vg(vginfo->vgname))
|
||||
continue;
|
||||
|
||||
if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
|
||||
log_error("vgnameid_list allocation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vgnl->vgid = dm_pool_strdup(cmd->mem, vginfo->vgid);
|
||||
vgnl->vg_name = dm_pool_strdup(cmd->mem, vginfo->vgname);
|
||||
|
||||
if (!vgnl->vgid || !vgnl->vg_name) {
|
||||
log_error("vgnameid_list member allocation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dm_list_add(vgnameids, &vgnl->list);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
|
||||
int include_internal)
|
||||
{
|
||||
|
3
lib/cache/lvmcache.h
vendored
3
lib/cache/lvmcache.h
vendored
@ -107,6 +107,9 @@ struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
|
||||
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
|
||||
int include_internal);
|
||||
|
||||
int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
|
||||
struct dm_list *vgnameids);
|
||||
|
||||
/* Returns list of struct dm_str_list containing pool-allocated copy of pvids */
|
||||
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
|
||||
const char *vgid);
|
||||
|
50
lib/cache/lvmetad.c
vendored
50
lib/cache/lvmetad.c
vendored
@ -673,6 +673,56 @@ int lvmetad_pv_list_to_lvmcache(struct cmd_context *cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lvmetad_get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids)
|
||||
{
|
||||
struct vgnameid_list *vgnl;
|
||||
struct id vgid;
|
||||
const char *vgid_txt;
|
||||
const char *vg_name;
|
||||
daemon_reply reply;
|
||||
struct dm_config_node *cn;
|
||||
|
||||
log_debug_lvmetad("Asking lvmetad for complete list of known VG ids/names");
|
||||
reply = _lvmetad_send("vg_list", NULL);
|
||||
if (!_lvmetad_handle_reply(reply, "list VGs", "", NULL)) {
|
||||
daemon_reply_destroy(reply);
|
||||
return_0;
|
||||
}
|
||||
|
||||
if ((cn = dm_config_find_node(reply.cft->root, "volume_groups"))) {
|
||||
for (cn = cn->child; cn; cn = cn->sib) {
|
||||
vgid_txt = cn->key;
|
||||
if (!id_read_format(&vgid, vgid_txt)) {
|
||||
stack;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
|
||||
log_error("vgnameid_list allocation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(vg_name = dm_config_find_str(cn->child, "name", NULL))) {
|
||||
log_error("vg_list no name found.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vgnl->vgid = dm_pool_strdup(cmd->mem, (char *)&vgid);
|
||||
vgnl->vg_name = dm_pool_strdup(cmd->mem, vg_name);
|
||||
|
||||
if (!vgnl->vgid || !vgnl->vg_name) {
|
||||
log_error("vgnameid_list member allocation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dm_list_add(vgnameids, &vgnl->list);
|
||||
}
|
||||
}
|
||||
|
||||
daemon_reply_destroy(reply);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd)
|
||||
{
|
||||
struct volume_group *tmp;
|
||||
|
6
lib/cache/lvmetad.h
vendored
6
lib/cache/lvmetad.h
vendored
@ -142,6 +142,12 @@ int lvmetad_pv_lookup_by_dev(struct cmd_context *cmd, struct device *dev, int *f
|
||||
*/
|
||||
int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd);
|
||||
|
||||
/*
|
||||
* Request a list of vgid/vgname pairs for all VGs known to lvmetad.
|
||||
* Does not do vg_lookup's on each VG, and does not populate lvmcache.
|
||||
*/
|
||||
int lvmetad_get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids);
|
||||
|
||||
/*
|
||||
* Find a VG by its ID or its name in the lvmetad cache. Gives NULL if the VG is
|
||||
* not found.
|
||||
|
@ -494,6 +494,12 @@ struct vg_list {
|
||||
struct volume_group *vg;
|
||||
};
|
||||
|
||||
struct vgnameid_list {
|
||||
struct dm_list list;
|
||||
const char *vg_name;
|
||||
const char *vgid;
|
||||
};
|
||||
|
||||
#define PV_PE_START_CALC ((uint64_t) -1) /* Calculate pe_start value */
|
||||
|
||||
struct pvcreate_restorable_params {
|
||||
@ -606,6 +612,8 @@ void lv_set_hidden(struct logical_volume *lv);
|
||||
|
||||
struct dm_list *get_vgnames(struct cmd_context *cmd, int include_internal);
|
||||
struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal);
|
||||
int get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids,
|
||||
const char *only_this_vgname, int include_internal);
|
||||
int scan_vgs_for_pvs(struct cmd_context *cmd, uint32_t warn_flags);
|
||||
|
||||
int pv_write(struct cmd_context *cmd, struct physical_volume *pv, int allow_non_orphan);
|
||||
|
@ -4017,6 +4017,54 @@ struct dm_list *get_vgids(struct cmd_context *cmd, int include_internal)
|
||||
return lvmcache_get_vgids(cmd, include_internal);
|
||||
}
|
||||
|
||||
int get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids,
|
||||
const char *only_this_vgname, int include_internal)
|
||||
{
|
||||
struct vgnameid_list *vgnl;
|
||||
struct format_type *fmt;
|
||||
|
||||
if (only_this_vgname) {
|
||||
if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
|
||||
log_error("vgnameid_list allocation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vgnl->vg_name = dm_pool_strdup(cmd->mem, only_this_vgname);
|
||||
vgnl->vgid = NULL;
|
||||
dm_list_add(vgnameids, &vgnl->list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lvmetad_active()) {
|
||||
/*
|
||||
* This just gets the list of names/ids from lvmetad
|
||||
* and does not populate lvmcache.
|
||||
*/
|
||||
lvmetad_get_vgnameids(cmd, vgnameids);
|
||||
|
||||
if (include_internal) {
|
||||
dm_list_iterate_items(fmt, &cmd->formats) {
|
||||
if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
|
||||
log_error("vgnameid_list allocation failed.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vgnl->vg_name = dm_pool_strdup(cmd->mem, fmt->orphan_vg_name);
|
||||
vgnl->vgid = NULL;
|
||||
dm_list_add(vgnameids, &vgnl->list);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The non-lvmetad case. This function begins by calling
|
||||
* lvmcache_label_scan() to populate lvmcache.
|
||||
*/
|
||||
lvmcache_get_vgnameids(cmd, include_internal, vgnameids);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _get_pvs(struct cmd_context *cmd, uint32_t warn_flags,
|
||||
struct dm_list *pvslist, struct dm_list *vgslist)
|
||||
{
|
||||
|
@ -1515,12 +1515,6 @@ int validate_restricted_lvname_param(struct cmd_context *cmd, const char **vg_na
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct vgnameid_list {
|
||||
struct dm_list list;
|
||||
const char *vg_name;
|
||||
const char *vgid;
|
||||
};
|
||||
|
||||
/*
|
||||
* Extract list of VG names and list of tags from command line arguments.
|
||||
*/
|
||||
@ -1584,67 +1578,6 @@ static int _get_arg_vgnames(struct cmd_context *cmd,
|
||||
return ret_max;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME Add arg to include (or not) entries with duplicate vg names?
|
||||
*
|
||||
* Obtain complete list of VG name/vgid pairs known on the system.
|
||||
*/
|
||||
static int _get_vgnameids_on_system(struct cmd_context *cmd,
|
||||
struct dm_list *vgnameids_on_system,
|
||||
const char *only_this_vgname, int include_internal)
|
||||
{
|
||||
struct vgnameid_list *vgnl;
|
||||
struct dm_list *vgids;
|
||||
struct dm_str_list *sl;
|
||||
const char *vgid;
|
||||
|
||||
if (only_this_vgname) {
|
||||
vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl));
|
||||
if (!vgnl) {
|
||||
log_error("name_id_list allocation failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
vgnl->vg_name = dm_pool_strdup(cmd->mem, only_this_vgname);
|
||||
vgnl->vgid = NULL;
|
||||
|
||||
dm_list_add(vgnameids_on_system, &vgnl->list);
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
log_verbose("Finding all volume groups.");
|
||||
|
||||
if (!lvmetad_vg_list_to_lvmcache(cmd))
|
||||
stack;
|
||||
|
||||
/*
|
||||
* Start with complete vgid list because multiple VGs might have same name.
|
||||
*/
|
||||
vgids = get_vgids(cmd, include_internal);
|
||||
if (!vgids || dm_list_empty(vgids)) {
|
||||
stack;
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
/* FIXME get_vgids() should provide these pairings directly */
|
||||
dm_list_iterate_items(sl, vgids) {
|
||||
if (!(vgid = sl->str))
|
||||
continue;
|
||||
|
||||
if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
|
||||
log_error("vgnameid_list allocation failed.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
vgnl->vgid = dm_pool_strdup(cmd->mem, vgid);
|
||||
vgnl->vg_name = lvmcache_vgname_from_vgid(cmd->mem, vgid);
|
||||
|
||||
dm_list_add(vgnameids_on_system, &vgnl->list);
|
||||
}
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
struct processing_handle *init_processing_handle(struct cmd_context *cmd)
|
||||
{
|
||||
struct processing_handle *handle;
|
||||
@ -1903,7 +1836,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
|
||||
* no VG names were given and the command defaults to processing all VGs.
|
||||
*/
|
||||
if (((dm_list_empty(&arg_vgnames) && enable_all_vgs) || !dm_list_empty(&arg_tags)) &&
|
||||
((ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, NULL, 0)) != ECMD_PROCESSED))
|
||||
!get_vgnameids(cmd, &vgnameids_on_system, NULL, 0))
|
||||
goto_out;
|
||||
|
||||
if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
|
||||
@ -2304,6 +2237,7 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
|
||||
struct dm_list vgnameids_to_process; /* vgnameid_list */
|
||||
|
||||
int enable_all_vgs = (cmd->command->flags & ALL_VGS_IS_DEFAULT);
|
||||
int need_vgnameids = 0;
|
||||
int ret;
|
||||
|
||||
cmd->error_foreign_vgs = 0;
|
||||
@ -2330,11 +2264,17 @@ int process_each_lv(struct cmd_context *cmd, int argc, char **argv, uint32_t fla
|
||||
/*
|
||||
* Obtain the complete list of VGs present on the system if it is needed because:
|
||||
* any tags were supplied and need resolving; or
|
||||
* no VG names were given and the select option needs resolving; or
|
||||
* no VG names were given and the command defaults to processing all VGs.
|
||||
*/
|
||||
if (((dm_list_empty(&arg_vgnames) && (enable_all_vgs ||
|
||||
handle->internal_report_for_select)) || !dm_list_empty(&arg_tags)) &&
|
||||
(ret = _get_vgnameids_on_system(cmd, &vgnameids_on_system, NULL, 0) != ECMD_PROCESSED))
|
||||
if (!dm_list_empty(&arg_tags))
|
||||
need_vgnameids = 1;
|
||||
else if (dm_list_empty(&arg_vgnames) && enable_all_vgs)
|
||||
need_vgnameids = 1;
|
||||
else if (dm_list_empty(&arg_vgnames) && handle->internal_report_for_select)
|
||||
need_vgnameids = 1;
|
||||
|
||||
if (need_vgnameids && !get_vgnameids(cmd, &vgnameids_on_system, NULL, 0))
|
||||
goto_out;
|
||||
|
||||
if (dm_list_empty(&arg_vgnames) && dm_list_empty(&vgnameids_on_system)) {
|
||||
@ -2822,11 +2762,12 @@ int process_each_pv(struct cmd_context *cmd,
|
||||
arg_count(cmd, all_ARG);
|
||||
|
||||
/*
|
||||
* Read all the vgs here because this has the effect of initializing
|
||||
* device/lvmcache info so that dev->pvid is available when creating
|
||||
* a list of devices.
|
||||
* Need pvid's set on all PVs before processing so that pvid's
|
||||
* can be compared to find duplicates while processing.
|
||||
*/
|
||||
if ((ret = _get_vgnameids_on_system(cmd, &all_vgnameids, only_this_vgname, 1) != ECMD_PROCESSED)) {
|
||||
lvmcache_seed_infos_from_lvmetad(cmd);
|
||||
|
||||
if (!get_vgnameids(cmd, &all_vgnameids, only_this_vgname, 1)) {
|
||||
stack;
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user