From 772cac09e358dc20b88fd05e44aae7015604015a Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Wed, 8 Apr 2009 12:53:20 +0000 Subject: [PATCH] Enable use of cached metadata for pvs & pvdisplay. Currently PV commands, which performs full device scan, repeatly re-reads PVs and scans for all devices. This behaviour can lead to OOM for large VG. This patch allows using internal metadata cache for pvs & pvdisplay, so the commands scan the PVs only once. (We have to use VG_GLOBAL otherwise cache is invalidated on every VG unlock in process_single PV call.) --- WHATS_NEW | 1 + tools/commands.h | 4 ++-- tools/toollib.c | 35 +++++++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 40e31b7ac..19ba5a949 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.46 - ================================ + Enable use of cached metadata for pvs and pvdisplay commands. Add missing 'device-mapper' internal subdir build dependency. Fix memory leak in mirror allocation code. Save and restore the previous logging level when log level is changed. diff --git a/tools/commands.h b/tools/commands.h index da202c075..cd83d5e72 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -497,7 +497,7 @@ xx(pvdata, xx(pvdisplay, "Display various attributes of physical volume(s)", - 0, + CACHE_VGMETADATA, "pvdisplay\n" "\t[-c|--colon]\n" "\t[-d|--debug]\n" @@ -571,7 +571,7 @@ xx(pvremove, xx(pvs, "Display information about physical volumes", - 0, + CACHE_VGMETADATA, "pvs" "\n" "\t[--aligned]\n" "\t[-a|--all]\n" diff --git a/tools/toollib.c b/tools/toollib.c index aa2194ceb..0bc3e40da 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -633,6 +633,11 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle, return ret_max; } +/* + * If the lock_type is LCK_VG_READ (used only in reporting commands), + * we lock VG_GLOBAL to enable use of metadata cache. + * This can pause alongide pvscan or vgscan process for a while. + */ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, struct volume_group *vg, uint32_t lock_type, int scan_label_only, void *handle, @@ -644,6 +649,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, int opt = 0; int ret_max = ECMD_PROCESSED; int ret = 0; + int lock_global = lock_type == LCK_VG_READ; struct pv_list *pvl; struct physical_volume *pv; @@ -656,6 +662,11 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, dm_list_init(&tags); + if (lock_global && !lock_vol(cmd, VG_GLOBAL, lock_type)) { + log_error("Unable to obtain global lock."); + return ECMD_FAILED; + } + if (argc) { log_verbose("Using physical volume(s) on command line"); for (; opt < argc; opt++) { @@ -673,7 +684,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, dm_pool_strdup(cmd->mem, tagname))) { log_error("strlist allocation failed"); - return ECMD_FAILED; + goto bad; } continue; } @@ -727,7 +738,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, if (ret > ret_max) ret_max = ret; if (sigint_caught()) - return ret_max; + goto out; } if (!dm_list_empty(&tags) && (vgnames = get_vgnames(cmd, 0)) && !dm_list_empty(vgnames)) { @@ -761,7 +772,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, if (ret > ret_max) ret_max = ret; if (sigint_caught()) - return ret_max; + goto out; } } } else { @@ -773,17 +784,18 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, if (ret > ret_max) ret_max = ret; if (sigint_caught()) - return ret_max; + goto out; } else if (arg_count(cmd, all_ARG)) { ret = _process_all_devs(cmd, handle, process_single); if (ret > ret_max) ret_max = ret; if (sigint_caught()) - return ret_max; + goto out; } else { log_verbose("Scanning for physical volume names"); + if (!(pvslist = get_pvs(cmd))) - return ECMD_FAILED; + goto bad; dm_list_iterate_items(pvl, pvslist) { ret = process_single(cmd, NULL, pvl->pv, @@ -791,12 +803,19 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, if (ret > ret_max) ret_max = ret; if (sigint_caught()) - return ret_max; + goto out; } } } - +out: + if (lock_global) + unlock_vg(cmd, VG_GLOBAL); return ret_max; +bad: + if (lock_global) + unlock_vg(cmd, VG_GLOBAL); + + return ECMD_FAILED; } /*