mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
Various allocation-related pvmove fixes.
This commit is contained in:
parent
ca4e0c973a
commit
39fbb844f9
@ -1,10 +1,12 @@
|
||||
Version 2.01.12 -
|
||||
================================
|
||||
Various allocation-related pvmove fixes.
|
||||
Log an error if clvmd can't resolve a host name got from CCS
|
||||
Fix potential spin loop in clvmd
|
||||
|
||||
Version 2.01.11 - 13th June 2005
|
||||
================================
|
||||
Added lvmconf.sh.
|
||||
Use matchpathcon mode parameter.
|
||||
Don't defer closing dead FDs in clvmd.
|
||||
Remove hard-coded 64k text metadata writing restriction.
|
||||
|
@ -803,7 +803,7 @@ int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
(seg_pv(seg, s)->pe_start +
|
||||
(esize * seg_pe(seg, s))),
|
||||
trailing_space);
|
||||
else {
|
||||
else if (seg_type(seg, s) == AREA_LV) {
|
||||
if (!(dl = hash_lookup(dm->layers,
|
||||
seg_lv(seg, s)->lvid.s))) {
|
||||
log_error("device layer %s missing from hash",
|
||||
@ -822,6 +822,10 @@ int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
"%s %" PRIu64 "%s", devbuf,
|
||||
esize * seg_le(seg, s),
|
||||
trailing_space);
|
||||
} else {
|
||||
log_error("Internal error: Unassigned area found in LV %s.",
|
||||
seg->lv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tw < 0) {
|
||||
@ -1243,6 +1247,7 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
|
||||
|
||||
/* Add dependencies for any LVs that segments refer to */
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
// When do we need? _set_flag(dl, REMOVE) on the log?
|
||||
if (seg->log_lv &&
|
||||
!str_list_add(dm->mem, &dl->pre_create,
|
||||
_build_dlid(dm->mem, seg->log_lv->lvid.s,
|
||||
@ -1250,7 +1255,6 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
// FIXME Check we don't want NOPROPAGATE here
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) != AREA_LV)
|
||||
@ -1262,7 +1266,10 @@ static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ? if (seg_lv(seg, s)->status & PVMOVE)
|
||||
_set_flag(dl, NOPROPAGATE);
|
||||
// When do we need? _set_flag(dl, REMOVE)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,6 +247,8 @@ static int _insert_dev(const char *path, dev_t d)
|
||||
|
||||
/* Generate pretend device numbers for loopfiles */
|
||||
if (!d) {
|
||||
if (hash_lookup(_cache.names, path))
|
||||
return 1;
|
||||
d = ++loopfile_count;
|
||||
loopfile = 1;
|
||||
}
|
||||
@ -627,6 +629,10 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
|
||||
if (!d) {
|
||||
_insert(name, 0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
if (!d) {
|
||||
_full_scan(0);
|
||||
d = (struct device *) hash_lookup(_cache.names, name);
|
||||
}
|
||||
}
|
||||
|
||||
return (d && (!f || (d->flags & DEV_REGULAR) ||
|
||||
|
@ -471,7 +471,9 @@ void display_stripe(const struct lv_segment *seg, uint32_t s, const char *pre)
|
||||
log_print("%sLogical extents\t%d to %d", pre,
|
||||
seg_le(seg, s),
|
||||
seg_le(seg, s) + seg->area_len - 1);
|
||||
|
||||
break;
|
||||
case AREA_UNASSIGNED:
|
||||
log_print("%sUnassigned area", pre);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,7 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
|
||||
return 0;
|
||||
}
|
||||
if (seg_type(seg, s) != AREA_PV) {
|
||||
log_error("LV stripe found in LV %s: "
|
||||
log_error("Non-PV stripe found in LV %s: "
|
||||
"unsupported by format1", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
@ -480,6 +480,9 @@ int out_areas(struct formatter *f, const struct lv_segment *seg,
|
||||
seg_lv(seg, s)->name,
|
||||
seg_le(seg, s),
|
||||
(s == seg->area_count - 1) ? "" : ",");
|
||||
break;
|
||||
case AREA_UNASSIGNED:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,10 +364,6 @@ int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Adjust extent counts in the pv and vg.
|
||||
*/
|
||||
seg->lv->vg->free_count -= seg->area_len;
|
||||
} else if ((lv1 = find_lv(seg->lv->vg, cv->v.str))) {
|
||||
set_lv_segment_area_lv(seg, s, lv1, cv->next->v.i,
|
||||
flags);
|
||||
|
@ -37,6 +37,10 @@ int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
|
||||
void set_lv_segment_area_lv(struct lv_segment *seg, uint32_t area_num,
|
||||
struct logical_volume *lv, uint32_t le,
|
||||
uint32_t flags);
|
||||
int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
|
||||
struct lv_segment *seg_from, uint32_t area_from);
|
||||
void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
|
||||
uint32_t area_reduction);
|
||||
|
||||
struct alloc_handle;
|
||||
struct alloc_handle *allocate_extents(struct volume_group *vg,
|
||||
|
@ -125,6 +125,74 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
|
||||
return seg;
|
||||
}
|
||||
|
||||
void release_lv_segment_area(struct lv_segment *seg, uint32_t s,
|
||||
uint32_t area_reduction)
|
||||
{
|
||||
if (seg_type(seg, s) == AREA_UNASSIGNED)
|
||||
return;
|
||||
|
||||
if (seg_type(seg, s) == AREA_PV) {
|
||||
release_pv_segment(seg_pvseg(seg, s), area_reduction);
|
||||
return;
|
||||
}
|
||||
|
||||
if (seg_lv(seg, s)->status & MIRROR_IMAGE) {
|
||||
lv_reduce(seg_lv(seg, s), area_reduction);
|
||||
return;
|
||||
}
|
||||
|
||||
if (area_reduction == seg->area_len) {
|
||||
seg_lv(seg, s) = NULL;
|
||||
seg_le(seg, s) = 0;
|
||||
seg_type(seg, s) = AREA_UNASSIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move a segment area from one segment to another
|
||||
*/
|
||||
int move_lv_segment_area(struct lv_segment *seg_to, uint32_t area_to,
|
||||
struct lv_segment *seg_from, uint32_t area_from)
|
||||
{
|
||||
struct physical_volume *pv;
|
||||
struct logical_volume *lv;
|
||||
uint32_t pe, le;
|
||||
|
||||
switch (seg_type(seg_from, area_from)) {
|
||||
case AREA_PV:
|
||||
pv = seg_pv(seg_from, area_from);
|
||||
pe = seg_pe(seg_from, area_from);
|
||||
|
||||
release_lv_segment_area(seg_from, area_from,
|
||||
seg_from->area_len);
|
||||
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
|
||||
|
||||
if (!set_lv_segment_area_pv(seg_to, area_to, pv, pe)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AREA_LV:
|
||||
lv = seg_lv(seg_from, area_from);
|
||||
le = seg_le(seg_from, area_from);
|
||||
|
||||
release_lv_segment_area(seg_from, area_from,
|
||||
seg_from->area_len);
|
||||
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
|
||||
|
||||
set_lv_segment_area_lv(seg_to, area_to, lv, le, 0);
|
||||
|
||||
break;
|
||||
|
||||
case AREA_UNASSIGNED:
|
||||
release_lv_segment_area(seg_to, area_to, seg_to->area_len);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Link part of a PV to an LV segment.
|
||||
*/
|
||||
@ -132,7 +200,6 @@ int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
|
||||
struct physical_volume *pv, uint32_t pe)
|
||||
{
|
||||
seg->area[area_num].type = AREA_PV;
|
||||
pv->pe_alloc_count += seg->area_len;
|
||||
|
||||
if (!(seg_pvseg(seg, area_num) =
|
||||
assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
|
||||
@ -175,24 +242,19 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
|
||||
} else
|
||||
area_reduction = reduction;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++)
|
||||
release_lv_segment_area(seg, s, area_reduction);
|
||||
|
||||
seg->len -= reduction;
|
||||
seg->area_len -= area_reduction;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) == AREA_PV) {
|
||||
release_pv_segment(seg_pvseg(seg, s), area_reduction);
|
||||
seg->lv->vg->free_count += area_reduction;
|
||||
} else if (seg_lv(seg, s)->status & MIRROR_IMAGE)
|
||||
lv_reduce(seg_lv(seg, s), area_reduction);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry point for all LV reductions in size.
|
||||
*/
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
struct lv_segment *seg;
|
||||
@ -225,6 +287,9 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
lv->le_count -= extents;
|
||||
lv->size = (uint64_t) lv->le_count * lv->vg->extent_size;
|
||||
|
||||
if (!delete)
|
||||
return 1;
|
||||
|
||||
/* Remove the LV if it is now empty */
|
||||
if (!lv->le_count) {
|
||||
if (!(lvl = find_lv_in_vg(lv->vg, lv->name))) {
|
||||
@ -244,6 +309,19 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty an LV
|
||||
*/
|
||||
int lv_empty(struct logical_volume *lv)
|
||||
{
|
||||
return _lv_reduce(lv, 0, lv->le_count);
|
||||
}
|
||||
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
{
|
||||
return _lv_reduce(lv, extents, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Completely remove an LV.
|
||||
*/
|
||||
@ -406,8 +484,6 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
||||
lv->le_count += extents;
|
||||
lv->size += (uint64_t) extents *lv->vg->extent_size;
|
||||
|
||||
lv->vg->free_count -= aa[0].len * area_count;
|
||||
|
||||
if (segtype_is_mirrored(segtype))
|
||||
lv->status |= MIRRORED;
|
||||
|
||||
@ -624,8 +700,8 @@ static int _find_parallel_space(struct alloc_handle *ah, alloc_policy_t alloc,
|
||||
|
||||
/* Only allocate log_area the first time around */
|
||||
if (ix + ix_offset < ah->area_count +
|
||||
(ah->log_count && !ah->log_area.len) ?
|
||||
ah->log_count : 0)
|
||||
((ah->log_count && !ah->log_area.len) ?
|
||||
ah->log_count : 0))
|
||||
/* FIXME With ALLOC_ANYWHERE, need to split areas */
|
||||
break;
|
||||
|
||||
@ -912,8 +988,6 @@ int lv_add_log_segment(struct alloc_handle *ah, struct logical_volume *log_lv)
|
||||
log_lv->le_count += ah->log_area.len;
|
||||
log_lv->size += (uint64_t) log_lv->le_count *log_lv->vg->extent_size;
|
||||
|
||||
log_lv->vg->free_count--;
|
||||
|
||||
if (log_lv->vg->fid->fmt->ops->lv_setup &&
|
||||
!log_lv->vg->fid->fmt->ops->lv_setup(log_lv->vg->fid, log_lv)) {
|
||||
stack;
|
||||
|
@ -86,7 +86,12 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
}
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) == AREA_PV) {
|
||||
if (seg_type(seg, s) == AREA_UNASSIGNED) {
|
||||
log_error("LV %s: segment %u has unassigned "
|
||||
"area %u.",
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
} else if (seg_type(seg, s) == AREA_PV) {
|
||||
if (!seg_pvseg(seg, s) ||
|
||||
seg_pvseg(seg, s)->lvseg != seg ||
|
||||
seg_pvseg(seg, s)->lv_area != s) {
|
||||
@ -104,6 +109,7 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
}
|
||||
/* FIXME I don't think this ever holds?
|
||||
if (seg_le(seg, s) != le) {
|
||||
log_error("LV %s: segment %u has "
|
||||
"inconsistent LV area %u "
|
||||
@ -111,6 +117,7 @@ int check_lv_segments(struct logical_volume *lv)
|
||||
lv->name, seg_count, s);
|
||||
r = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,9 +212,8 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
|
||||
seg_pe(split_seg, s));
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error("Unrecognised segment type %u",
|
||||
seg_type(seg, s));
|
||||
case AREA_UNASSIGNED:
|
||||
log_error("Unassigned area %u found in segment", s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -465,9 +465,9 @@ int vg_change_pesize(struct cmd_context *cmd, struct volume_group *vg,
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
log_error("Unrecognised segment type "
|
||||
"%u", seg_type(seg, s));
|
||||
case AREA_UNASSIGNED:
|
||||
log_error("Unassigned area %u found in "
|
||||
"segment", s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1045,7 +1045,27 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
|
||||
struct volume_group *vg_read(struct cmd_context *cmd, const char *vgname,
|
||||
int *consistent)
|
||||
{
|
||||
return _vg_read(cmd, vgname, consistent, 0);
|
||||
struct volume_group *vg;
|
||||
struct lv_list *lvl;
|
||||
|
||||
if (!(vg = _vg_read(cmd, vgname, consistent, 0)))
|
||||
return NULL;
|
||||
|
||||
if (!check_pv_segments(vg)) {
|
||||
log_error("Internal error: PV segments corrupted in %s.",
|
||||
vg->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate_items(lvl, &vg->lvs) {
|
||||
if (!check_lv_segments(lvl->lv)) {
|
||||
log_error("Internal error: LV segments corrupted in %s.",
|
||||
lvl->lv->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return vg;
|
||||
}
|
||||
|
||||
struct volume_group *vg_read_precommitted(struct cmd_context *cmd,
|
||||
|
@ -81,6 +81,7 @@ typedef enum {
|
||||
} alloc_policy_t;
|
||||
|
||||
typedef enum {
|
||||
AREA_UNASSIGNED = 0,
|
||||
AREA_PV,
|
||||
AREA_LV
|
||||
} area_type_t;
|
||||
@ -443,9 +444,12 @@ struct logical_volume *lv_create_empty(struct format_instance *fi,
|
||||
int import,
|
||||
struct volume_group *vg);
|
||||
|
||||
/* Entry point for all LV extent reductions */
|
||||
/* Reduce the size of an LV by extents */
|
||||
int lv_reduce(struct logical_volume *lv, uint32_t extents);
|
||||
|
||||
/* Empty an LV prior to deleting it */
|
||||
int lv_empty(struct logical_volume *lv);
|
||||
|
||||
/* Entry point for all LV extent allocations */
|
||||
int lv_extend(struct logical_volume *lv,
|
||||
struct segment_type *segtype,
|
||||
|
@ -171,6 +171,8 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
struct lv_segment *seg;
|
||||
struct lv_list *lvl;
|
||||
struct pv_list *pvl;
|
||||
struct physical_volume *pv;
|
||||
uint32_t pe;
|
||||
int lv_used = 0;
|
||||
uint32_t s, start_le, extent_count = 0u;
|
||||
struct segment_type *segtype;
|
||||
@ -270,18 +272,19 @@ int insert_pvmove_mirrors(struct cmd_context *cmd,
|
||||
lv_used = 1;
|
||||
}
|
||||
|
||||
pv = seg_pv(seg, s);
|
||||
pe = seg_pe(seg, s);
|
||||
log_very_verbose("Moving %s:%u-%u of %s/%s",
|
||||
dev_name(pvl->pv->dev),
|
||||
seg_pe(seg, s),
|
||||
seg_pe(seg, s) +
|
||||
seg->area_len - 1,
|
||||
pe, pe + seg->area_len - 1,
|
||||
lv->vg->name, lv->name);
|
||||
|
||||
start_le = lv_mirr->le_count;
|
||||
/* FIXME Clean this up */
|
||||
release_lv_segment_area(seg, s, seg->area_len);
|
||||
if (!lv_extend(lv_mirr, segtype, 1,
|
||||
seg->area_len, 0u, seg->area_len,
|
||||
seg_pv(seg, s),
|
||||
seg_pe(seg, s),
|
||||
pv, pe,
|
||||
PVMOVE, allocatable_pvs,
|
||||
alloc)) {
|
||||
log_error("Unable to allocate "
|
||||
@ -355,22 +358,22 @@ int remove_pvmove_mirrors(struct volume_group *vg,
|
||||
else
|
||||
c = 0;
|
||||
|
||||
if (!set_lv_segment_area_pv(seg, s,
|
||||
seg_pv(mir_seg, c),
|
||||
seg_pe(mir_seg, c))) {
|
||||
if (!move_lv_segment_area(seg, s, mir_seg, c)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replace mirror with old area */
|
||||
release_lv_segment_area(mir_seg, !c, mir_seg->area_len);
|
||||
|
||||
/* Replace mirror with error segment */
|
||||
if (!
|
||||
(mir_seg->segtype =
|
||||
get_segtype_from_string(vg->cmd,
|
||||
"striped"))) {
|
||||
log_error("Missing striped segtype");
|
||||
"error"))) {
|
||||
log_error("Missing error segtype");
|
||||
return 0;
|
||||
}
|
||||
mir_seg->area_count = 1;
|
||||
mir_seg->area_count = 0;
|
||||
|
||||
/* FIXME Assumes only one pvmove at a time! */
|
||||
lv1->status &= ~LOCKED;
|
||||
@ -381,6 +384,10 @@ int remove_pvmove_mirrors(struct volume_group *vg,
|
||||
|
||||
}
|
||||
|
||||
if (!lv_empty(lv_mirr)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -392,7 +399,7 @@ const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
|
||||
list_iterate_items(seg, &lv_mirr->segments) {
|
||||
if (!seg_is_mirrored(seg))
|
||||
continue;
|
||||
if (seg->area[0].type != AREA_PV)
|
||||
if (seg_type(seg, 0) != AREA_PV)
|
||||
continue;
|
||||
return dev_name(seg_dev(seg, 0));
|
||||
}
|
||||
@ -433,7 +440,7 @@ struct logical_volume *find_pvmove_lv(struct volume_group *vg,
|
||||
|
||||
/* Check segment origins point to pvname */
|
||||
list_iterate_items(seg, &lv->segments) {
|
||||
if (seg->area[0].type != AREA_PV)
|
||||
if (seg_type(seg, 0) != AREA_PV)
|
||||
continue;
|
||||
if (seg_dev(seg, 0) != dev)
|
||||
continue;
|
||||
|
@ -162,14 +162,18 @@ struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv,
|
||||
peg->lvseg = seg;
|
||||
peg->lv_area = area_num;
|
||||
|
||||
peg->pv->pe_alloc_count += area_len;
|
||||
peg->lvseg->lv->vg->free_count -= area_len;
|
||||
|
||||
return peg;
|
||||
}
|
||||
|
||||
int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
|
||||
{
|
||||
peg->pv->pe_alloc_count -= area_reduction;
|
||||
peg->lvseg->lv->vg->free_count += area_reduction;
|
||||
|
||||
if (!peg->lvseg->area_len) {
|
||||
if (peg->lvseg->area_len == area_reduction) {
|
||||
peg->lvseg = NULL;
|
||||
peg->lv_area = 0;
|
||||
|
||||
@ -178,7 +182,8 @@ int release_pv_segment(struct pv_segment *peg, uint32_t area_reduction)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len)) {
|
||||
if (!pv_split_segment(peg->pv, peg->pe + peg->lvseg->area_len -
|
||||
area_reduction)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
@ -163,8 +163,8 @@ static int _devices_disp(struct report_handle *rh, struct field *field,
|
||||
name = dev_name(seg_dev(seg, s));
|
||||
extent = seg_pe(seg, s);
|
||||
break;
|
||||
default:
|
||||
name = "unknown";
|
||||
case AREA_UNASSIGNED:
|
||||
name = "unassigned";
|
||||
extent = 0;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,8 @@ static int _segments_compatible(struct lv_segment *first,
|
||||
/* FIXME Relax this to first area type != second area type */
|
||||
/* plus the additional AREA_LV checks needed */
|
||||
if ((first->area[s].type != AREA_PV) ||
|
||||
(second->area[s].type != AREA_PV)) return 0;
|
||||
(second->area[s].type != AREA_PV))
|
||||
return 0;
|
||||
|
||||
width = first->area_len;
|
||||
|
||||
|
@ -170,6 +170,14 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
log_print("Skipping mirror LV %s", lv->name);
|
||||
continue;
|
||||
}
|
||||
if (lv->status & MIRROR_LOG) {
|
||||
log_print("Skipping mirror log LV %s", lv->name);
|
||||
continue;
|
||||
}
|
||||
if (lv->status & MIRROR_IMAGE) {
|
||||
log_print("Skipping mirror image LV %s", lv->name);
|
||||
continue;
|
||||
}
|
||||
if (lv->status & LOCKED) {
|
||||
log_print("Skipping locked LV %s", lv->name);
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user