mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +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 -
|
Version 2.02.29 -
|
||||||
==================================
|
==================================
|
||||||
|
Avoid nested vg_reads when processing PVs in VGs and fix associated locking.
|
||||||
Accept sizes with --readahead argument.
|
Accept sizes with --readahead argument.
|
||||||
Store size arguments as sectors internally.
|
Store size arguments as sectors internally.
|
||||||
Attempt to remove incomplete LVs with lvcreate zeroing/activation problems.
|
Attempt to remove incomplete LVs with lvcreate zeroing/activation problems.
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
static int _pvdisplay_single(struct cmd_context *cmd,
|
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 physical_volume *pv, void *handle)
|
||||||
{
|
{
|
||||||
struct pv_list *pvl;
|
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 *pv_name = pv_dev_name(pv);
|
||||||
const char *vg_name = NULL;
|
const char *vg_name = NULL;
|
||||||
|
|
||||||
if (!is_orphan(pv)) {
|
if (!is_orphan(pv) && !vg) {
|
||||||
vg_name = pv_vg_name(pv);
|
vg_name = pv_vg_name(pv);
|
||||||
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
||||||
log_error("Can't lock %s: skipping", vg_name);
|
log_error("Can't lock %s: skipping", vg_name);
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(vg = vg_read(cmd, vg_name, (char *)&pv->vgid, &consistent))) {
|
if (!(vg = vg_read(cmd, vg_name, (char *)&pv->vgid, &consistent))) {
|
||||||
log_error("Can't read %s: skipping", vg_name);
|
log_error("Can't read %s: skipping", vg_name);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vg_check_status(vg, CLUSTERED)) {
|
if (!vg_check_status(vg, CLUSTERED)) {
|
||||||
ret = ECMD_FAILED;
|
ret = ECMD_FAILED;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace possibly incomplete PV structure with new one
|
* Replace possibly incomplete PV structure with new one
|
||||||
* allocated in vg_read() path.
|
* allocated in vg_read() path.
|
||||||
*/
|
*/
|
||||||
if (!(pvl = find_pv_in_vg(vg, pv_name))) {
|
if (!(pvl = find_pv_in_vg(vg, pv_name))) {
|
||||||
log_error("Unable to find \"%s\" in volume group \"%s\"",
|
log_error("Unable to find \"%s\" in volume group \"%s\"",
|
||||||
pv_name, vg->name);
|
pv_name, vg->name);
|
||||||
@ -119,5 +119,6 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
|
|||||||
return EINVALID_CMD_LINE;
|
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.done = 0;
|
||||||
params.total = 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) "
|
log_print("%d physical volume(s) resized / %d physical volume(s) "
|
||||||
"not resized", params.done, params.total - params.done);
|
"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;
|
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)
|
struct pv_segment *pvseg, void *handle)
|
||||||
{
|
{
|
||||||
int consistent = 0;
|
|
||||||
struct physical_volume *pv = pvseg->pv;
|
|
||||||
int ret = ECMD_PROCESSED;
|
int ret = ECMD_PROCESSED;
|
||||||
|
|
||||||
if (!lock_vol(cmd, pv_vg_name(pv), LCK_VG_READ)) {
|
if (!report_object(handle, vg, NULL, pvseg->pv, NULL, pvseg))
|
||||||
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))
|
|
||||||
ret = ECMD_FAILED;
|
ret = ECMD_FAILED;
|
||||||
|
|
||||||
out:
|
|
||||||
unlock_vg(cmd, pv_vg_name(pv));
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +90,7 @@ static int _pvs_single(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
int ret = ECMD_PROCESSED;
|
int ret = ECMD_PROCESSED;
|
||||||
const char *vg_name = NULL;
|
const char *vg_name = NULL;
|
||||||
|
|
||||||
if (!is_orphan(pv)) {
|
if (!is_orphan(pv) && !vg) {
|
||||||
vg_name = pv_vg_name(pv);
|
vg_name = pv_vg_name(pv);
|
||||||
|
|
||||||
if (!lock_vol(cmd, vg_name, LCK_VG_READ)) {
|
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;
|
break;
|
||||||
case PVS:
|
case PVS:
|
||||||
if (args_are_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);
|
report_handle, &_pvs_single);
|
||||||
else
|
else
|
||||||
r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0,
|
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;
|
break;
|
||||||
case PVSEGS:
|
case PVSEGS:
|
||||||
if (args_are_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, &_pvsegs_single);
|
report_handle, &_pvsegs_single);
|
||||||
else
|
else
|
||||||
r = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0,
|
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))
|
void *handle))
|
||||||
{
|
{
|
||||||
struct pv_segment *pvseg;
|
struct pv_segment *pvseg;
|
||||||
|
const char *vg_name = NULL;
|
||||||
int ret_max = 0;
|
int ret_max = 0;
|
||||||
int ret;
|
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) {
|
list_iterate_items(pvseg, &pv->segments) {
|
||||||
ret = process_single(cmd, vg, pvseg, handle);
|
ret = process_single(cmd, vg, pvseg, handle);
|
||||||
@ -435,6 +455,10 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
|
|||||||
return ret_max;
|
return ret_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (vg_name)
|
||||||
|
unlock_vg(cmd, vg_name);
|
||||||
|
|
||||||
return ret_max;
|
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,
|
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,
|
int (*process_single) (struct cmd_context * cmd,
|
||||||
struct volume_group * vg,
|
struct volume_group * vg,
|
||||||
struct physical_volume * pv,
|
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)) &&
|
if (!list_empty(&tags) && (vgnames = get_vgs(cmd, 0)) &&
|
||||||
!list_empty(vgnames)) {
|
!list_empty(vgnames)) {
|
||||||
list_iterate_items(sll, 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))) {
|
if (!(vg = vg_read(cmd, sll->str, NULL, &consistent))) {
|
||||||
log_error("Volume group \"%s\" not found", sll->str);
|
log_error("Volume group \"%s\" not found", sll->str);
|
||||||
|
unlock_vg(cmd, sll->str);
|
||||||
ret_max = ECMD_FAILED;
|
ret_max = ECMD_FAILED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!consistent)
|
if (!consistent) {
|
||||||
|
unlock_vg(cmd, sll->str);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!vg_check_status(vg, CLUSTERED))
|
if (!vg_check_status(vg, CLUSTERED)) {
|
||||||
|
unlock_vg(cmd, sll->str);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ret = process_each_pv_in_vg(cmd, vg, &tags,
|
ret = process_each_pv_in_vg(cmd, vg, &tags,
|
||||||
handle,
|
handle,
|
||||||
process_single);
|
process_single);
|
||||||
|
|
||||||
|
unlock_vg(cmd, sll->str);
|
||||||
|
|
||||||
if (ret > ret_max)
|
if (ret > ret_max)
|
||||||
ret_max = ret;
|
ret_max = ret;
|
||||||
if (sigint_caught())
|
if (sigint_caught())
|
||||||
|
@ -34,7 +34,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv,
|
|||||||
int consistent, void *handle));
|
int consistent, void *handle));
|
||||||
|
|
||||||
int process_each_pv(struct cmd_context *cmd, int argc, char **argv,
|
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,
|
int (*process_single) (struct cmd_context * cmd,
|
||||||
struct volume_group * vg,
|
struct volume_group * vg,
|
||||||
struct physical_volume * pv,
|
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 */
|
/* FIXME: Pass private struct through to all these functions */
|
||||||
/* and update in batch here? */
|
/* 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);
|
_vgreduce_single);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user