mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Avoid nested vg_reads when processing PVs in VGs and fix associated locking.
This commit is contained in:
parent
96b250d625
commit
223c62e7b7
@ -1,5 +1,6 @@
|
||||
Version 2.02.29 -
|
||||
==================================
|
||||
Avoid nested vg_reads when processing PVs in VGs and fix associated locking.
|
||||
Accept sizes with --readahead argument.
|
||||
Store size arguments as sectors internally.
|
||||
Attempt to remove incomplete LVs with lvcreate zeroing/activation problems.
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "tools.h"
|
||||
|
||||
static int _pvdisplay_single(struct cmd_context *cmd,
|
||||
struct volume_group *vg __attribute((unused)),
|
||||
struct volume_group *vg,
|
||||
struct physical_volume *pv, void *handle)
|
||||
{
|
||||
struct pv_list *pvl;
|
||||
@ -27,27 +27,27 @@ static int _pvdisplay_single(struct cmd_context *cmd,
|
||||
const char *pv_name = pv_dev_name(pv);
|
||||
const char *vg_name = NULL;
|
||||
|
||||
if (!is_orphan(pv)) {
|
||||
if (!is_orphan(pv) && !vg) {
|
||||
vg_name = pv_vg_name(pv);
|
||||
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
||||
log_error("Can't lock %s: skipping", vg_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
||||
log_error("Can't lock %s: skipping", vg_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!(vg = vg_read(cmd, vg_name, (char *)&pv->vgid, &consistent))) {
|
||||
log_error("Can't read %s: skipping", vg_name);
|
||||
goto out;
|
||||
}
|
||||
if (!(vg = vg_read(cmd, vg_name, (char *)&pv->vgid, &consistent))) {
|
||||
log_error("Can't read %s: skipping", vg_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!vg_check_status(vg, CLUSTERED)) {
|
||||
ret = ECMD_FAILED;
|
||||
goto out;
|
||||
}
|
||||
if (!vg_check_status(vg, CLUSTERED)) {
|
||||
ret = ECMD_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace possibly incomplete PV structure with new one
|
||||
* allocated in vg_read() path.
|
||||
*/
|
||||
/*
|
||||
* Replace possibly incomplete PV structure with new one
|
||||
* allocated in vg_read() path.
|
||||
*/
|
||||
if (!(pvl = find_pv_in_vg(vg, pv_name))) {
|
||||
log_error("Unable to find \"%s\" in volume group \"%s\"",
|
||||
pv_name, vg->name);
|
||||
@ -119,5 +119,6 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
return process_each_pv(cmd, argc, argv, NULL, NULL, _pvdisplay_single);
|
||||
return process_each_pv(cmd, argc, argv, NULL, LCK_VG_READ, NULL,
|
||||
_pvdisplay_single);
|
||||
}
|
||||
|
@ -61,7 +61,8 @@ int pvresize(struct cmd_context *cmd, int argc, char **argv)
|
||||
params.done = 0;
|
||||
params.total = 0;
|
||||
|
||||
ret = process_each_pv(cmd, argc, argv, NULL, ¶ms, _pvresize_single);
|
||||
ret = process_each_pv(cmd, argc, argv, NULL, LCK_VG_WRITE, ¶ms,
|
||||
_pvresize_single);
|
||||
|
||||
log_print("%d physical volume(s) resized / %d physical volume(s) "
|
||||
"not resized", params.done, params.total - params.done);
|
||||
|
@ -54,33 +54,15 @@ static int _segs_single(struct cmd_context *cmd __attribute((unused)),
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
static int _pvsegs_sub_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
static int _pvsegs_sub_single(struct cmd_context *cmd __attribute((unused)),
|
||||
struct volume_group *vg,
|
||||
struct pv_segment *pvseg, void *handle)
|
||||
{
|
||||
int consistent = 0;
|
||||
struct physical_volume *pv = pvseg->pv;
|
||||
int ret = ECMD_PROCESSED;
|
||||
|
||||
if (!lock_vol(cmd, pv_vg_name(pv), LCK_VG_READ)) {
|
||||
log_error("Can't lock %s: skipping", pv_vg_name(pv));
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!(vg = vg_read(cmd, pv_vg_name(pv), NULL, &consistent))) {
|
||||
log_error("Can't read %s: skipping", pv_vg_name(pv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!vg_check_status(vg, CLUSTERED)) {
|
||||
ret = ECMD_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!report_object(handle, vg, NULL, pv, NULL, pvseg))
|
||||
if (!report_object(handle, vg, NULL, pvseg->pv, NULL, pvseg))
|
||||
ret = ECMD_FAILED;
|
||||
|
||||
out:
|
||||
unlock_vg(cmd, pv_vg_name(pv));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -108,7 +90,7 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
int ret = ECMD_PROCESSED;
|
||||
const char *vg_name = NULL;
|
||||
|
||||
if (!is_orphan(pv)) {
|
||||
if (!is_orphan(pv) && !vg) {
|
||||
vg_name = pv_vg_name(pv);
|
||||
|
||||
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
||||
@ -334,7 +316,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
|
||||
break;
|
||||
case PVS:
|
||||
if (args_are_pvs)
|
||||
r = process_each_pv(cmd, argc, argv, NULL,
|
||||
r = process_each_pv(cmd, argc, argv, NULL, LCK_VG_READ,
|
||||
report_handle, &_pvs_single);
|
||||
else
|
||||
r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0,
|
||||
@ -346,7 +328,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
|
||||
break;
|
||||
case PVSEGS:
|
||||
if (args_are_pvs)
|
||||
r = process_each_pv(cmd, argc, argv, NULL,
|
||||
r = process_each_pv(cmd, argc, argv, NULL, LCK_VG_READ,
|
||||
report_handle, &_pvsegs_single);
|
||||
else
|
||||
r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0,
|
||||
|
@ -424,8 +424,28 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
|
||||
void *handle))
|
||||
{
|
||||
struct pv_segment *pvseg;
|
||||
const char *vg_name = NULL;
|
||||
int ret_max = 0;
|
||||
int ret;
|
||||
int consistent = 0;
|
||||
|
||||
if (!vg) {
|
||||
vg_name = pv_vg_name(pv);
|
||||
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
||||
log_error("Can't lock %s: skipping", vg_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!(vg = vg_read(cmd, vg_name, NULL, &consistent))) {
|
||||
log_error("Can't read %s: skipping", vg_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!vg_check_status(vg, CLUSTERED)) {
|
||||
ret = ECMD_FAILED;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
list_iterate_items(pvseg, &pv->segments) {
|
||||
ret = process_single(cmd, vg, pvseg, handle);
|
||||
@ -435,6 +455,10 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
|
||||
return ret_max;
|
||||
}
|
||||
|
||||
out:
|
||||
if (vg_name)
|
||||
unlock_vg(cmd, vg_name);
|
||||
|
||||
return ret_max;
|
||||
}
|
||||
|
||||
@ -665,7 +689,7 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle,
|
||||
}
|
||||
|
||||
int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
|
||||
struct volume_group *vg, void *handle,
|
||||
struct volume_group *vg, uint32_t lock_type, void *handle,
|
||||
int (*process_single) (struct cmd_context * cmd,
|
||||
struct volume_group * vg,
|
||||
struct physical_volume * pv,
|
||||
@ -735,20 +759,32 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
|
||||
if (!list_empty(&tags) && (vgnames = get_vgs(cmd, 0)) &&
|
||||
!list_empty(vgnames)) {
|
||||
list_iterate_items(sll, vgnames) {
|
||||
if (!lock_vol(cmd, sll->str, lock_type)) {
|
||||
log_error("Can't lock %s: skipping", sll->str);
|
||||
continue;
|
||||
}
|
||||
if (!(vg = vg_read(cmd, sll->str, NULL, &consistent))) {
|
||||
log_error("Volume group \"%s\" not found", sll->str);
|
||||
unlock_vg(cmd, sll->str);
|
||||
ret_max = ECMD_FAILED;
|
||||
continue;
|
||||
}
|
||||
if (!consistent)
|
||||
if (!consistent) {
|
||||
unlock_vg(cmd, sll->str);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!vg_check_status(vg, CLUSTERED))
|
||||
if (!vg_check_status(vg, CLUSTERED)) {
|
||||
unlock_vg(cmd, sll->str);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = process_each_pv_in_vg(cmd, vg, &tags,
|
||||
handle,
|
||||
process_single);
|
||||
|
||||
unlock_vg(cmd, sll->str);
|
||||
|
||||
if (ret > ret_max)
|
||||
ret_max = ret;
|
||||
if (sigint_caught())
|
||||
|
@ -34,7 +34,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
|
||||
int consistent, void *handle));
|
||||
|
||||
int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
|
||||
struct volume_group *vg, void *handle,
|
||||
struct volume_group *vg, uint32_t lock_type, void *handle,
|
||||
int (*process_single) (struct cmd_context * cmd,
|
||||
struct volume_group * vg,
|
||||
struct physical_volume * pv,
|
||||
|
@ -539,7 +539,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
/* FIXME: Pass private struct through to all these functions */
|
||||
/* and update in batch here? */
|
||||
ret = process_each_pv(cmd, argc, argv, vg, NULL,
|
||||
ret = process_each_pv(cmd, argc, argv, vg, LCK_VG_WRITE, NULL,
|
||||
_vgreduce_single);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user