summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-10-19 13:58:43 -0500
committerDavid Teigland <teigland@redhat.com>2015-10-19 14:05:14 -0500
commitc9dde69d7621e9bb1514b3cca28bc74a429d0f82 (patch)
treef6d704e67fa58d16362e68e4d1bdd5fa6b538abd
parentad060654ad00a3ffc6aed9d7781a28db5fa78e06 (diff)
downloadlvm2-dev-dct-lvmetad3.tar.gz
pvscan: use process_each_pvdev-dct-lvmetad3
The old code made two loops through the PVs: in the first loop it could find the max PV and VG name lengths, and in the second loop it could use these max lengths as field widths for aligning columns when printing. The new code using process_each_pv() uses only one loop through the PVs. In the first pvscan_single() function, the max PV and VG name lengths are looked up in lvmcache.
-rw-r--r--lib/cache/lvmcache.c24
-rw-r--r--lib/cache/lvmcache.h4
-rw-r--r--tools/pvscan.c184
3 files changed, 120 insertions, 92 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 04cf3fb01..a0098a785 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -2358,3 +2358,27 @@ int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd)
return 0;
}
+void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
+ unsigned *pv_max_name_len,
+ unsigned *vg_max_name_len)
+{
+ struct lvmcache_vginfo *vginfo;
+ struct lvmcache_info *info;
+ unsigned len;
+
+ *vg_max_name_len = 0;
+ *pv_max_name_len = 0;
+
+ dm_list_iterate_items(vginfo, &_vginfos) {
+ len = strlen(vginfo->vgname);
+ if (*vg_max_name_len < len)
+ *vg_max_name_len = len;
+
+ dm_list_iterate_items(info, &vginfo->infos) {
+ len = strlen(dev_name(info->dev));
+ if (*pv_max_name_len < len)
+ *pv_max_name_len = len;
+ }
+ }
+}
+
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 76b9b10ae..ccf3eb498 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -190,4 +190,8 @@ void lvmcache_set_preferred_duplicates(const char *vgid);
int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
+void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
+ unsigned *pv_max_name_len, unsigned *vg_max_name_len);
+
+
#endif
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 85e59f87b..6d20123a2 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -18,24 +18,31 @@
#include "lvmetad.h"
#include "lvmcache.h"
-unsigned pv_max_name_len = 0;
-unsigned vg_max_name_len = 0;
-
-static void _pvscan_display_single(struct cmd_context *cmd,
- struct physical_volume *pv,
- void *handle __attribute__((unused)))
+struct pvscan_params {
+ int new_pvs_found;
+ int pvs_found;
+ uint64_t size_total;
+ uint64_t size_new;
+ unsigned pv_max_name_len;
+ unsigned vg_max_name_len;
+ unsigned pv_tmp_namelen;
+ char *pv_tmp_name;
+};
+
+static int _pvscan_display_single(struct cmd_context *cmd,
+ struct physical_volume *pv,
+ struct pvscan_params *params)
{
/* XXXXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXXXX */
char uuid[40] __attribute__((aligned(8)));
- const unsigned suffix = sizeof(uuid) + 10;
- char pv_tmp_name[pv_max_name_len + suffix];
- unsigned pv_len = pv_max_name_len;
+ const unsigned suffix_len = sizeof(uuid) + 10;
+ unsigned pv_len;
const char *pvdevname = pv_dev_name(pv);
/* short listing? */
if (arg_count(cmd, short_ARG) > 0) {
log_print_unless_silent("%s", pvdevname);
- return;
+ return ECMD_PROCESSED;
}
if (arg_count(cmd, verbose_ARG) > 1) {
@@ -49,25 +56,39 @@ static void _pvscan_display_single(struct cmd_context *cmd,
/* return; */
}
+ if (!params->pv_max_name_len) {
+ lvmcache_get_max_name_lengths(cmd, &params->pv_max_name_len, &params->vg_max_name_len);
+
+ params->pv_max_name_len += 2;
+ params->vg_max_name_len += 2;
+ params->pv_tmp_namelen = params->pv_max_name_len + suffix_len;
+
+ if (!(params->pv_tmp_name = dm_pool_alloc(cmd->mem, params->pv_tmp_namelen)))
+ return ECMD_FAILED;
+ }
+
+ pv_len = params->pv_max_name_len;
+ memset(params->pv_tmp_name, 0, params->pv_tmp_namelen);
+
if (arg_count(cmd, uuid_ARG)) {
if (!id_write_format(&pv->id, uuid, sizeof(uuid))) {
stack;
- return;
+ return ECMD_FAILED;
}
- if (dm_snprintf(pv_tmp_name, sizeof(pv_tmp_name), "%-*s with UUID %s",
- pv_max_name_len - 2, pvdevname, uuid) < 0) {
+ if (dm_snprintf(params->pv_tmp_name, params->pv_tmp_namelen, "%-*s with UUID %s",
+ params->pv_max_name_len - 2, pvdevname, uuid) < 0) {
log_error("Invalid PV name with uuid.");
- return;
+ return ECMD_FAILED;
}
- pvdevname = pv_tmp_name;
- pv_len += suffix;
+ pvdevname = params->pv_tmp_name;
+ pv_len += suffix_len;
}
if (is_orphan(pv))
log_print_unless_silent("PV %-*s %-*s %s [%s]",
pv_len, pvdevname,
- vg_max_name_len, " ",
+ params->vg_max_name_len, " ",
pv->fmt ? pv->fmt->name : " ",
display_size(cmd, pv_size(pv)));
else if (pv_status(pv) & EXPORTED_VG)
@@ -78,10 +99,46 @@ static void _pvscan_display_single(struct cmd_context *cmd,
else
log_print_unless_silent("PV %-*s VG %-*s %s [%s / %s free]",
pv_len, pvdevname,
- vg_max_name_len, pv_vg_name(pv),
+ params->vg_max_name_len, pv_vg_name(pv),
pv->fmt ? pv->fmt->name : " ",
display_size(cmd, (uint64_t) pv_pe_count(pv) * pv_pe_size(pv)),
display_size(cmd, (uint64_t) (pv_pe_count(pv) - pv_pe_alloc_count(pv)) * pv_pe_size(pv)));
+ return ECMD_PROCESSED;
+}
+
+static int _pvscan_single(struct cmd_context *cmd, struct volume_group *vg,
+ struct physical_volume *pv, struct processing_handle *handle)
+{
+ struct pvscan_params *params = (struct pvscan_params *)handle->custom_handle;
+
+ if ((arg_count(cmd, exported_ARG) && !(pv_status(pv) & EXPORTED_VG)) ||
+ (arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
+ return ECMD_PROCESSED;
+
+ }
+
+ /* Also check for MD use? */
+/*******
+ if (MAJOR(pv_create_kdev_t(pv[p]->pv_name)) != MD_MAJOR) {
+ log_warn("WARNING: physical volume \"%s\" belongs to a meta device",
+ pv[p]->pv_name);
+ }
+ if (MAJOR(pv[p]->pv_dev) != MD_MAJOR)
+ continue;
+********/
+
+ params->pvs_found++;
+
+ if (is_orphan(pv)) {
+ params->new_pvs_found++;
+ params->size_new += pv_size(pv);
+ params->size_total += pv_size(pv);
+ } else {
+ params->size_total += (uint64_t) pv_pe_count(pv) * pv_pe_size(pv);
+ }
+
+ _pvscan_display_single(cmd, pv, params);
+ return ECMD_PROCESSED;
}
#define REFRESH_BEFORE_AUTOACTIVATION_RETRIES 5
@@ -319,16 +376,9 @@ out:
int pvscan(struct cmd_context *cmd, int argc, char **argv)
{
- int new_pvs_found = 0;
- int pvs_found = 0;
-
- struct dm_list *pvslist;
- struct pv_list *pvl;
- struct physical_volume *pv;
-
- uint64_t size_total = 0;
- uint64_t size_new = 0;
- unsigned len;
+ struct pvscan_params params = { 0 };
+ struct processing_handle *handle = NULL;
+ int ret;
if (arg_count(cmd, cache_long_ARG))
return _pvscan_lvmetad(cmd, argc, argv);
@@ -386,78 +436,28 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
cmd->full_filter->wipe(cmd->full_filter);
lvmcache_destroy(cmd, 1, 0);
- /* populate lvmcache */
- if (!lvmetad_vg_list_to_lvmcache(cmd))
- stack;
-
- log_verbose("Walking through all physical volumes");
- if (!(pvslist = get_pvs(cmd))) {
- unlock_vg(cmd, VG_GLOBAL);
- return_ECMD_FAILED;
- }
-
- /* eliminate exported/new if required */
- dm_list_iterate_items(pvl, pvslist) {
- pv = pvl->pv;
-
- if ((arg_count(cmd, exported_ARG)
- && !(pv_status(pv) & EXPORTED_VG)) ||
- (arg_count(cmd, novolumegroup_ARG) && (!is_orphan(pv)))) {
- dm_list_del(&pvl->list);
- free_pv_fid(pv);
- continue;
- }
-
- /* Also check for MD use? */
-/*******
- if (MAJOR(pv_create_kdev_t(pv[p]->pv_name)) != MD_MAJOR) {
- log_warn
- ("WARNING: physical volume \"%s\" belongs to a meta device",
- pv[p]->pv_name);
- }
- if (MAJOR(pv[p]->pv_dev) != MD_MAJOR)
- continue;
-********/
- pvs_found++;
-
- if (is_orphan(pv)) {
- new_pvs_found++;
- size_new += pv_size(pv);
- size_total += pv_size(pv);
- } else
- size_total += (uint64_t) pv_pe_count(pv) * pv_pe_size(pv);
+ if (!(handle = init_processing_handle(cmd))) {
+ log_error("Failed to initialize processing handle.");
+ ret = ECMD_FAILED;
+ goto out;
}
- /* find maximum pv name length */
- pv_max_name_len = vg_max_name_len = 0;
- dm_list_iterate_items(pvl, pvslist) {
- pv = pvl->pv;
- len = strlen(pv_dev_name(pv));
- if (pv_max_name_len < len)
- pv_max_name_len = len;
- len = strlen(pv_vg_name(pv));
- if (vg_max_name_len < len)
- vg_max_name_len = len;
- }
- pv_max_name_len += 2;
- vg_max_name_len += 2;
+ handle->custom_handle = &params;
- dm_list_iterate_items(pvl, pvslist) {
- _pvscan_display_single(cmd, pvl->pv, NULL);
- free_pv_fid(pvl->pv);
- }
+ ret = process_each_pv(cmd, argc, argv, NULL, 0, handle, _pvscan_single);
- if (!pvs_found)
+ if (!params.pvs_found)
log_print_unless_silent("No matching physical volumes found");
else
log_print_unless_silent("Total: %d [%s] / in use: %d [%s] / in no VG: %d [%s]",
- pvs_found,
- display_size(cmd, size_total),
- pvs_found - new_pvs_found,
- display_size(cmd, (size_total - size_new)),
- new_pvs_found, display_size(cmd, size_new));
+ params.pvs_found,
+ display_size(cmd, params.size_total),
+ params.pvs_found - params.new_pvs_found,
+ display_size(cmd, (params.size_total - params.size_new)),
+ params.new_pvs_found, display_size(cmd, params.size_new));
+out:
unlock_vg(cmd, VG_GLOBAL);
- return ECMD_PROCESSED;
+ return ret;
}