1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-02-01 09:47:48 +03:00

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.)
This commit is contained in:
Milan Broz 2009-04-08 12:53:20 +00:00
parent bef749c942
commit 772cac09e3
3 changed files with 30 additions and 10 deletions

View File

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

View File

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

View File

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