1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

stacked mirror support (incomplete)

This commit is contained in:
Alasdair Kergon 2007-12-20 18:55:46 +00:00
parent ac089d9015
commit 31e9db2690
9 changed files with 346 additions and 103 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.30 -
===================================
Add support for stacked mirrors.
Major restructuring of pvmove and lvconvert layer manipulation code.
Replace tools/fsadm with scripts/fsadm.sh.
Append fields to report/pvsegs_cols_verbose.

View File

@ -1407,6 +1407,7 @@ int lv_add_mirror_lvs(struct logical_volume *lv,
for (m = old_area_count; m < new_area_count; m++) {
set_lv_segment_area_lv(seg, m, sub_lvs[m - old_area_count], 0, status);
first_seg(sub_lvs[m - old_area_count])->mirror_seg = seg;
sub_lvs[m - old_area_count]->status &= ~VISIBLE_LV;
}
return 1;
@ -1451,6 +1452,39 @@ int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv)
return 1;
}
static int _lv_extend_mirror(struct alloc_handle *ah,
struct logical_volume *lv,
uint32_t extents, uint32_t first_area)
{
struct lv_segment *seg;
uint32_t m, s;
seg = first_seg(lv);
for (m = first_area, s = 0; s < seg->area_count; s++) {
if (is_temporary_mirror_layer(seg_lv(seg, s))) {
if (!_lv_extend_mirror(ah, seg_lv(seg, s), extents, m))
return_0;
m += lv_mirror_count(seg_lv(seg, s));
continue;
}
if (!lv_add_segment(ah, m++, 1, seg_lv(seg, s),
get_segtype_from_string(lv->vg->cmd,
"striped"),
0, 0, 0, NULL)) {
log_error("Aborting. Failed to extend %s.",
seg_lv(seg, s)->name);
return 0;
}
}
seg->area_len += extents;
seg->len += extents;
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
return 1;
}
/*
* Entry point for single-step LV allocation + extension.
*/
@ -1464,9 +1498,7 @@ int lv_extend(struct logical_volume *lv,
alloc_policy_t alloc)
{
int r = 1;
uint32_t m;
struct alloc_handle *ah;
struct lv_segment *seg;
if (segtype_is_virtual(segtype))
return lv_add_virtual_segment(lv, status, extents, segtype);
@ -1482,21 +1514,8 @@ int lv_extend(struct logical_volume *lv,
goto out;
}
} else {
seg = first_seg(lv);
for (m = 0; m < mirrors; m++) {
if (!lv_add_segment(ah, m, 1, seg_lv(seg, m),
get_segtype_from_string(lv->vg->cmd,
"striped"),
0, 0, 0, NULL)) {
log_error("Aborting. Failed to extend %s.",
seg_lv(seg, m)->name);
return 0;
}
}
seg->area_len += extents;
seg->len += extents;
lv->le_count += extents;
lv->size += (uint64_t) extents *lv->vg->extent_size;
if (!_lv_extend_mirror(ah, lv, extents, 0))
return_0;
}
out:
@ -1599,10 +1618,14 @@ static int _for_each_sub_lv(struct cmd_context *cmd, struct logical_volume *lv,
list_iterate_items(seg, &lv->segments) {
if (seg->log_lv && !func(cmd, seg->log_lv, data))
return 0;
for (s = 0; s < seg->area_count; s++)
if (seg_type(seg, s) == AREA_LV &&
!func(cmd, seg_lv(seg, s), data))
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (!func(cmd, seg_lv(seg, s), data))
return 0;
if (!_for_each_sub_lv(cmd, seg_lv(seg, s), func, data))
return 0;
}
}
return 1;
@ -2180,23 +2203,62 @@ static void _move_lv_segments(struct logical_volume *lv_to,
lv_from->size = 0;
}
/* Remove a layer from the LV */
/* FIXME: how to specify what should be removed if multiple layers stacked? */
int remove_layer_from_lv(struct logical_volume *lv)
/*
* Find a parent LV for the layer_lv in the lv
*/
struct logical_volume *find_parent_for_layer(struct logical_volume *lv,
struct logical_volume *layer_lv)
{
struct logical_volume *orig_lv;
struct logical_volume *parent;
struct lv_segment *seg;
uint32_t s;
list_iterate_items(seg, &lv->segments) {
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (seg_lv(seg, s) == layer_lv)
return lv;
parent = find_parent_for_layer(seg_lv(seg, s),
layer_lv);
if (parent)
return parent;
}
}
return NULL;
}
/* Remove a layer from the LV */
int remove_layer_from_lv(struct logical_volume *lv,
struct logical_volume *layer_lv)
{
struct logical_volume *parent;
struct segment_type *segtype;
parent = find_parent_for_layer(lv, layer_lv);
if (!parent) {
log_error("Failed to find layer %s in %s",
layer_lv->name, lv->name);
return 0;
}
/*
* Before removal, the layer should be cleaned up,
* i.e. additional segments and areas should have been removed.
*/
if (list_size(&lv->segments) != 1 ||
first_seg(lv)->area_count != 1 ||
seg_type(first_seg(lv), 0) != AREA_LV)
return 0;
if (list_size(&parent->segments) != 1 ||
first_seg(parent)->area_count != 1 ||
seg_type(first_seg(parent), 0) != AREA_LV ||
layer_lv != seg_lv(first_seg(parent), 0) ||
parent->le_count != layer_lv->le_count)
return_0;
orig_lv = seg_lv(first_seg(lv), 0);
_move_lv_segments(lv, orig_lv, 0, 0);
_move_lv_segments(parent, layer_lv, 0, 0);
/* Replace the empty layer with error segment */
segtype = get_segtype_from_string(lv->vg->cmd, "error");
if (!lv_add_virtual_segment(layer_lv, 0, parent->le_count, segtype))
return_0;
return 1;
}

View File

@ -398,7 +398,10 @@ int remove_layers_for_segments_all(struct cmd_context *cmd,
struct list *lvs_changed);
int split_parent_segments_for_layer(struct cmd_context *cmd,
struct logical_volume *layer_lv);
int remove_layer_from_lv(struct logical_volume *lv);
struct logical_volume *find_parent_for_layer(struct logical_volume *lv,
struct logical_volume *layer_lv);
int remove_layer_from_lv(struct logical_volume *lv,
struct logical_volume *layer_lv);
struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
struct logical_volume *lv_where,
uint32_t status,
@ -417,7 +420,7 @@ struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
const char *pv_name);
/* Find LV segment containing given LE */
struct lv_segment *first_seg(struct logical_volume *lv);
struct lv_segment *first_seg(const struct logical_volume *lv);
/*
@ -458,8 +461,8 @@ int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
#define MIRROR_BY_SEG 0x00000001U /* segment-by-segment mirror */
#define MIRROR_BY_LV 0x00000002U /* mirror by mimage LVs */
uint32_t lv_mirror_count(struct logical_volume *lv);
struct alloc_handle;
int is_temporary_mirror_layer(const struct logical_volume *lv);
uint32_t lv_mirror_count(const struct logical_volume *lv);
uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
uint32_t region_size);
int remove_mirrors_from_segments(struct logical_volume *lv,
@ -468,7 +471,7 @@ int add_mirrors_to_segments(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t region_size,
struct list *allocatable_pvs, alloc_policy_t alloc);
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log);
int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t stripes, uint32_t region_size,
@ -482,6 +485,7 @@ int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log);
int collapse_mirrored_lv(struct logical_volume *lv);
struct logical_volume *find_pvmove_lv(struct volume_group *vg,
struct device *dev, uint32_t lv_type);

View File

@ -937,7 +937,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
}
/* Find segment at a given logical extent in an LV */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le)
struct lv_segment *find_seg_by_le(const struct logical_volume *lv, uint32_t le)
{
struct lv_segment *seg;
@ -948,7 +948,7 @@ struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le)
return NULL;
}
struct lv_segment *first_seg(struct logical_volume *lv)
struct lv_segment *first_seg(const struct logical_volume *lv)
{
struct lv_segment *seg = NULL;
@ -959,7 +959,7 @@ struct lv_segment *first_seg(struct logical_volume *lv)
}
/* Find segment at a given physical extent in a PV */
struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe)
struct pv_segment *find_peg_by_pe(const struct physical_volume *pv, uint32_t pe)
{
struct pv_segment *peg;

View File

@ -264,10 +264,10 @@ struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
/* Find LV segment containing given LE */
struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le);
struct lv_segment *find_seg_by_le(const struct logical_volume *lv, uint32_t le);
/* Find PV segment containing given LE */
struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe);
struct pv_segment *find_peg_by_pe(const struct physical_volume *pv, uint32_t pe);
/*
* Remove a dev_dir if present.

View File

@ -32,12 +32,41 @@
#define MIRROR_ALLOCATE 1
#define MIRROR_ALLOCATE_ANYWHERE 2
/*
* Returns true if the lv is temporary mirror layer for resync
*/
int is_temporary_mirror_layer(const struct logical_volume *lv)
{
if (lv->status & MIRROR_IMAGE
&& lv->status & MIRRORED
&& !(lv->status & LOCKED))
return 1;
return 0;
}
/*
* Returns the number of mirrors of the LV
*/
uint32_t lv_mirror_count(struct logical_volume *lv)
uint32_t lv_mirror_count(const struct logical_volume *lv)
{
return (lv->status & MIRRORED) ? first_seg(lv)->area_count : 1;
struct lv_segment *seg;
uint32_t s, mirrors;
if (!(lv->status & MIRRORED))
return 1;
seg = first_seg(lv);
mirrors = seg->area_count;
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) != AREA_LV)
continue;
if (is_temporary_mirror_layer(seg_lv(seg, s)))
mirrors += lv_mirror_count(seg_lv(seg, s)) - 1;
}
return mirrors;
}
struct lv_segment *find_mirror_seg(struct lv_segment *seg)
@ -68,21 +97,21 @@ uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
/*
* Delete independent/orphan LV, it must acquire lock.
*/
static int _delete_lv(struct lv_segment *mirrored_seg, struct logical_volume *lv)
static int _delete_lv(struct logical_volume *mirror_lv, struct logical_volume *lv)
{
struct cmd_context *cmd = mirrored_seg->lv->vg->cmd;
struct cmd_context *cmd = mirror_lv->vg->cmd;
struct str_list *sl;
/* Inherit tags - maybe needed for activation */
if (!str_list_match_list(&mirrored_seg->lv->tags, &lv->tags)) {
list_iterate_items(sl, &mirrored_seg->lv->tags)
if (!str_list_match_list(&mirror_lv->tags, &lv->tags)) {
list_iterate_items(sl, &mirror_lv->tags)
if (!str_list_add(cmd->mem, &lv->tags, sl->str)) {
log_error("Aborting. Unable to tag.");
return 0;
}
if (!vg_write(mirrored_seg->lv->vg) ||
!vg_commit(mirrored_seg->lv->vg)) {
if (!vg_write(mirror_lv->vg) ||
!vg_commit(mirror_lv->vg)) {
log_error("Intermediate VG commit for orphan volume failed.");
return 0;
}
@ -101,29 +130,31 @@ static int _delete_lv(struct lv_segment *mirrored_seg, struct logical_volume *lv
}
/*
* Reduce mirrored_seg to num_mirrors images.
* Remove num_removed images from mirrored_seg
*/
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log)
static int _remove_mirror_images(struct logical_volume *lv,
uint32_t num_removed,
struct list *removable_pvs,
unsigned remove_log, struct list *orphan_lvs)
{
uint32_t m;
uint32_t extents;
uint32_t s, s1;
struct logical_volume *sub_lv;
struct logical_volume *log_lv = NULL;
struct logical_volume *lv1 = NULL;
struct physical_volume *pv;
struct lv_segment *seg;
struct lv_segment *seg, *mirrored_seg = first_seg(lv);
struct lv_segment_area area;
int all_pvs_removable, pv_found;
struct pv_list *pvl;
uint32_t old_area_count = mirrored_seg->area_count;
uint32_t new_area_count = mirrored_seg->area_count;
struct segment_type *segtype;
struct lv_list *lvl;
struct list tmp_orphan_lvs;
log_very_verbose("Reducing mirror set from %" PRIu32 " to %"
PRIu32 " image(s)%s.",
old_area_count, num_mirrors,
old_area_count, old_area_count - num_removed,
remove_log ? " and no log volume" : "");
/* Move removable_pvs to end of array */
@ -162,39 +193,46 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
mirrored_seg->areas[s] = area;
}
/* Found enough matches? */
if (new_area_count == num_mirrors)
if (old_area_count - new_area_count == num_removed)
break;
}
if (new_area_count == mirrored_seg->area_count) {
if (old_area_count == new_area_count) {
log_error("No mirror images found using specified PVs.");
return 0;
}
}
} else
new_area_count = old_area_count - num_removed;
for (m = num_mirrors; m < mirrored_seg->area_count; m++) {
/* Remove mimage LVs from the segment */
list_init(&tmp_orphan_lvs);
for (m = new_area_count; m < mirrored_seg->area_count; m++) {
seg_lv(mirrored_seg, m)->status &= ~MIRROR_IMAGE;
seg_lv(mirrored_seg, m)->status |= VISIBLE_LV;
if (!(lvl = dm_pool_alloc(lv->vg->cmd->mem, sizeof(*lvl)))) {
log_error("lv_list alloc failed");
return 0;
}
lvl->lv = seg_lv(mirrored_seg, m);
list_add(&tmp_orphan_lvs, &lvl->list);
}
mirrored_seg->area_count = new_area_count;
mirrored_seg->area_count = num_mirrors;
/* Save log_lv as mirrored_seg may not be available after
* remove_layer_from_lv(), */
log_lv = mirrored_seg->log_lv;
/* If no more mirrors, remove mirror layer */
if (num_mirrors == 1) {
if (new_area_count == 1) {
lv1 = seg_lv(mirrored_seg, 0);
extents = lv1->le_count;
remove_layer_from_lv(mirrored_seg->lv);
mirrored_seg->lv->status &= ~MIRRORED;
mirrored_seg->lv->status &= ~MIRROR_NOTSYNCED;
remove_log = 1;
/* Replace mirror with error segment */
segtype = get_segtype_from_string(mirrored_seg->lv->vg->cmd, "error");
if (!lv_add_virtual_segment(lv1, 0, extents, segtype))
mirrored_seg->log_lv = NULL;
if (!remove_layer_from_lv(lv, lv1))
return_0;
lv->status &= ~MIRRORED;
lv->status &= ~MIRROR_NOTSYNCED;
remove_log = 1;
}
if (remove_log && mirrored_seg->log_lv) {
log_lv = mirrored_seg->log_lv;
mirrored_seg->log_lv = NULL;
if (remove_log && log_lv) {
log_lv->status &= ~MIRROR_LOG;
log_lv->status |= VISIBLE_LV;
}
@ -228,16 +266,148 @@ int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
return 0;
}
/* Delete the 'orphan' LVs */
for (m = num_mirrors; m < old_area_count; m++)
if (!_delete_lv(mirrored_seg, seg_lv(mirrored_seg, m)))
/* Save or delete the 'orphan' LVs */
if (orphan_lvs) {
*orphan_lvs = tmp_orphan_lvs;
orphan_lvs->n->p = orphan_lvs;
orphan_lvs->p->n = orphan_lvs;
} else {
list_iterate_items(lvl, &tmp_orphan_lvs)
if (!_delete_lv(lv, lvl->lv))
return 0;
}
if (lv1 && !_delete_lv(lv, lv1))
return 0;
if (remove_log && log_lv && !_delete_lv(lv, log_lv))
return 0;
return 1;
}
/*
* Remove the number of mirror images from the LV
*/
int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
struct list *removable_pvs, unsigned remove_log)
{
uint32_t num_removed, removed_once;
uint32_t existing_mirrors = lv_mirror_count(lv);
num_removed = existing_mirrors - num_mirrors;
while (num_removed) {
if (num_removed < first_seg(lv)->area_count)
removed_once = num_removed;
else
removed_once = first_seg(lv)->area_count - 1;
if (!_remove_mirror_images(lv, removed_once,
removable_pvs, remove_log, NULL))
return_0;
num_removed -= removed_once;
}
return 1;
}
static int _mirrored_lv_in_sync(struct logical_volume *lv)
{
float sync_percent;
if (!lv_mirror_percent(lv->vg->cmd, lv, 0, &sync_percent, NULL)) {
log_error("Unable to determine mirror sync status of %s/%s.",
lv->vg->name, lv->name);
return 0;
}
if (sync_percent >= 100.0)
return 1;
return 0;
}
static int _merge_mirror_images(struct logical_volume *lv,
const struct list *mimages)
{
int addition = list_size(mimages);
struct logical_volume **img_lvs;
struct lv_list *lvl;
int i = 0;
if (!addition)
return 1;
if (!(img_lvs = alloca(sizeof(*img_lvs) * addition)))
return_0;
list_iterate_items(lvl, mimages)
img_lvs[i++] = lvl->lv;
return lv_add_mirror_lvs(lv, img_lvs, addition,
MIRROR_IMAGE, first_seg(lv)->region_size);
}
/*
* Return a temporary LV for resyncing added mirror image.
* Add other mirror legs to lvs list.
*/
static struct logical_volume *_find_tmp_mirror(struct logical_volume *lv)
{
struct lv_segment *seg;
if (!(lv->status & MIRRORED))
return NULL;
seg = first_seg(lv);
/* Temporary mirror is always area_num == 0 */
if (seg_type(seg, 0) == AREA_LV &&
is_temporary_mirror_layer(seg_lv(seg, 0)))
return seg_lv(seg, 0);
return NULL;
}
/*
* Collapsing temporary mirror layers.
*
* When mirrors are added to already-mirrored LV, a temporary mirror layer
* is inserted at the top of the stack to reduce resync work.
* The function will remove the intermediate layer and collapse the stack
* as far as mirrors are in-sync.
*
* The function is destructive: to remove intermediate mirror layers,
* VG metadata commits and suspend/resume are necessary.
*/
int collapse_mirrored_lv(struct logical_volume *lv)
{
struct logical_volume *tmp_lv, *parent_lv;
struct list lvlist;
while ((tmp_lv = _find_tmp_mirror(lv))) {
parent_lv = find_parent_for_layer(lv, tmp_lv);
if (!_mirrored_lv_in_sync(parent_lv)) {
log_verbose("Not collapsing %s: out-of-sync",
parent_lv->name);
return 1;
}
list_init(&lvlist);
if (!_remove_mirror_images(parent_lv,
first_seg(parent_lv)->area_count - 1,
NULL, 1, &lvlist)) {
log_error("Failed to release mirror images");
return 0;
}
if (lv1 && !_delete_lv(mirrored_seg, lv1))
return 0;
if (log_lv && !_delete_lv(mirrored_seg, log_lv))
return 0;
if (!_merge_mirror_images(parent_lv, &lvlist)) {
log_error("Failed to add mirror images");
return 0;
}
}
return 1;
}
@ -338,19 +508,13 @@ int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirr
struct list *removable_pvs, unsigned remove_log)
{
int r;
int in_sync = 0;
int in_sync;
int log_policy, dev_policy;
uint32_t old_num_mirrors = mirrored_seg->area_count;
int had_log = (mirrored_seg->log_lv) ? 1 : 0;
float sync_percent = 0;
/* was the mirror in-sync before problems? */
if (!lv_mirror_percent(mirrored_seg->lv->vg->cmd,
mirrored_seg->lv, 0, &sync_percent, NULL))
log_error("WARNING: Unable to determine mirror sync status of %s/%s.",
mirrored_seg->lv->vg->name, mirrored_seg->lv->name);
else if (sync_percent >= 100.0)
in_sync = 1;
in_sync = _mirrored_lv_in_sync(mirrored_seg->lv);
/*
* While we are only removing devices, we can have sync set.
@ -359,7 +523,7 @@ int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirr
*/
init_mirror_in_sync(in_sync);
r = remove_mirror_images(mirrored_seg, num_mirrors,
r = remove_mirror_images(mirrored_seg->lv, num_mirrors,
removable_pvs, remove_log);
if (!r)
/* Unable to remove bad devices */
@ -721,7 +885,7 @@ int remove_mirror_log(struct cmd_context *cmd,
init_mirror_in_sync(0);
}
if (!remove_mirror_images(first_seg(lv), lv_mirror_count(lv),
if (!remove_mirror_images(lv, lv_mirror_count(lv),
removable_pvs, 1U))
return_0;
@ -1195,17 +1359,17 @@ int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
if (seg->area_count <= mirrors) {
if (lv_mirror_count(lv) <= mirrors) {
log_error("Removing more than existing: %d <= %d",
seg->area_count, mirrors);
return 0;
}
new_mirrors = seg->area_count - mirrors - 1;
new_mirrors = lv_mirror_count(lv) - mirrors - 1;
/* MIRROR_BY_LV */
if (seg_type(seg, 0) == AREA_LV &&
seg_lv(seg, 0)->status & MIRROR_IMAGE) {
return remove_mirror_images(first_seg(lv), new_mirrors + 1,
return remove_mirror_images(lv, new_mirrors + 1,
pvs, log_count ? 1U : 0);
}

View File

@ -369,14 +369,20 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
return 1;
}
} else if (lp->mirrors > existing_mirrors) {
/* FIXME Unless anywhere, remove PV of log_lv
* from allocatable_pvs & allocate
* (mirrors - existing_mirrors) new areas
*/
/* FIXME Create mirror hierarchy to sync */
log_error("Adding mirror images is not "
"supported yet.");
return 0;
/* FIXME: can't have multiple mlogs. force corelog. */
corelog = 1;
if (!insert_layer_for_lv(cmd, lv, 0, "_resync%d")) {
log_error("Failed to insert resync layer");
return 0;
}
if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
corelog ? 0U : 1U, lp->pvh, lp->alloc,
MIRROR_BY_LV))
return_0;
} else {
/* Reduce number of mirrors */
if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,

View File

@ -435,7 +435,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
if ((lp->extents > lv->le_count)) {
list_iterate_back_items(seg, &lv->segments) {
if (seg_is_mirrored(seg))
seg_mirrors = seg->area_count;
seg_mirrors = lv_mirror_count(seg->lv);
else
seg_mirrors = 0;
break;
@ -469,7 +469,7 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
}
if (seg_is_mirrored(seg))
seg_mirrors = seg->area_count;
seg_mirrors = lv_mirror_count(seg->lv);
else
seg_mirrors = 0;

View File

@ -1222,6 +1222,12 @@ int apply_lvname_restrictions(const char *name)
return 0;
}
if (strstr(name, "_resync")) {
log_error("Names including \"_resync\" are reserved. "
"Please choose a different LV name.");
return 0;
}
return 1;
}