mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
When lvconvert allocates a mirror log, respect parallel area constraints.
Use loop to iterate through the now-ordered policy list in _allocate(). Check for failure to allocate just the mirror log. Introduce calc_area_multiple(). Support mirror log allocation when there is only one PV: area_count now 0. (See lvm-devel list archives for further details.)
This commit is contained in:
parent
948ee3e396
commit
5b61ca7281
@ -1,5 +1,10 @@
|
|||||||
Version 2.02.17 -
|
Version 2.02.17 -
|
||||||
===================================
|
===================================
|
||||||
|
When lvconvert allocates a mirror log, respect parallel area constraints.
|
||||||
|
Use loop to iterate through the now-ordered policy list in _allocate().
|
||||||
|
Check for failure to allocate just the mirror log.
|
||||||
|
Introduce calc_area_multiple().
|
||||||
|
Support mirror log allocation when there is only one PV: area_count now 0.
|
||||||
Fix detection of smallest area in _alloc_parallel_area() for cling policy.
|
Fix detection of smallest area in _alloc_parallel_area() for cling policy.
|
||||||
Add manpage entry for clvmd -T
|
Add manpage entry for clvmd -T
|
||||||
Fix gulm operation of clvmd, including a hang when doing lvchange -aey
|
Fix gulm operation of clvmd, including a hang when doing lvchange -aey
|
||||||
|
@ -415,6 +415,15 @@ struct alloc_handle {
|
|||||||
struct list alloced_areas[0]; /* Lists of areas in each stripe */
|
struct list alloced_areas[0]; /* Lists of areas in each stripe */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint32_t calc_area_multiple(const struct segment_type *segtype,
|
||||||
|
const uint32_t area_count)
|
||||||
|
{
|
||||||
|
if (!segtype_is_striped(segtype) || !area_count)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return area_count;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preparation for a specific allocation attempt
|
* Preparation for a specific allocation attempt
|
||||||
*/
|
*/
|
||||||
@ -476,7 +485,7 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
|
|||||||
ah->area_count = area_count;
|
ah->area_count = area_count;
|
||||||
ah->log_count = log_count;
|
ah->log_count = log_count;
|
||||||
ah->alloc = alloc;
|
ah->alloc = alloc;
|
||||||
ah->area_multiple = segtype_is_striped(segtype) ? ah->area_count : 1;
|
ah->area_multiple = calc_area_multiple(segtype, area_count);
|
||||||
|
|
||||||
for (s = 0; s < ah->area_count; s++)
|
for (s = 0; s < ah->area_count; s++)
|
||||||
list_init(&ah->alloced_areas[s]);
|
list_init(&ah->alloced_areas[s]);
|
||||||
@ -553,7 +562,7 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
|
|||||||
if (mirrored_pv)
|
if (mirrored_pv)
|
||||||
extra_areas = 1;
|
extra_areas = 1;
|
||||||
|
|
||||||
area_multiple = segtype_is_striped(segtype) ? area_count : 1;
|
area_multiple = calc_area_multiple(segtype, area_count);
|
||||||
|
|
||||||
/* log_lv gets set up elsehere */
|
/* log_lv gets set up elsehere */
|
||||||
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
|
||||||
@ -707,7 +716,7 @@ static int _for_each_pv(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
if (max_seg_len && *max_seg_len > remaining_seg_len)
|
if (max_seg_len && *max_seg_len > remaining_seg_len)
|
||||||
*max_seg_len = remaining_seg_len;
|
*max_seg_len = remaining_seg_len;
|
||||||
|
|
||||||
area_multiple = segtype_is_striped(seg->segtype) ? seg->area_count : 1;
|
area_multiple = calc_area_multiple(seg->segtype, seg->area_count);
|
||||||
area_len = remaining_seg_len / area_multiple ? : 1;
|
area_len = remaining_seg_len / area_multiple ? : 1;
|
||||||
|
|
||||||
for (s = first_area;
|
for (s = first_area;
|
||||||
@ -1066,6 +1075,7 @@ static int _allocate(struct alloc_handle *ah,
|
|||||||
int r = 0;
|
int r = 0;
|
||||||
struct list *pvms;
|
struct list *pvms;
|
||||||
uint32_t areas_size;
|
uint32_t areas_size;
|
||||||
|
alloc_policy_t alloc;
|
||||||
|
|
||||||
if (allocated >= new_extents && !ah->log_count) {
|
if (allocated >= new_extents && !ah->log_count) {
|
||||||
log_error("_allocate called with no work to do!");
|
log_error("_allocate called with no work to do!");
|
||||||
@ -1111,50 +1121,18 @@ static int _allocate(struct alloc_handle *ah,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_allocated = allocated;
|
/* Attempt each defined allocation policy in turn */
|
||||||
if (!_find_parallel_space(ah, ALLOC_CONTIGUOUS, pvms, areas,
|
for (alloc = ALLOC_CONTIGUOUS; alloc < ALLOC_INHERIT; alloc++) {
|
||||||
areas_size, can_split,
|
old_allocated = allocated;
|
||||||
prev_lvseg, &allocated, new_extents)) {
|
if (!_find_parallel_space(ah, alloc, pvms, areas,
|
||||||
stack;
|
areas_size, can_split,
|
||||||
goto out;
|
prev_lvseg, &allocated, new_extents))
|
||||||
|
goto_out;
|
||||||
|
if ((allocated == new_extents) || (ah->alloc == alloc) ||
|
||||||
|
(!can_split && (allocated != old_allocated)))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((allocated == new_extents) || (ah->alloc == ALLOC_CONTIGUOUS) ||
|
|
||||||
(!can_split && (allocated != old_allocated)))
|
|
||||||
goto finished;
|
|
||||||
|
|
||||||
old_allocated = allocated;
|
|
||||||
if (!_find_parallel_space(ah, ALLOC_CLING, pvms, areas,
|
|
||||||
areas_size, can_split,
|
|
||||||
prev_lvseg, &allocated, new_extents)) {
|
|
||||||
stack;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((allocated == new_extents) || (ah->alloc == ALLOC_CLING) ||
|
|
||||||
(!can_split && (allocated != old_allocated)))
|
|
||||||
goto finished;
|
|
||||||
|
|
||||||
old_allocated = allocated;
|
|
||||||
if (!_find_parallel_space(ah, ALLOC_NORMAL, pvms, areas,
|
|
||||||
areas_size, can_split,
|
|
||||||
prev_lvseg, &allocated, new_extents)) {
|
|
||||||
stack;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((allocated == new_extents) || (ah->alloc == ALLOC_NORMAL) ||
|
|
||||||
(!can_split && (allocated != old_allocated)))
|
|
||||||
goto finished;
|
|
||||||
|
|
||||||
if (!_find_parallel_space(ah, ALLOC_ANYWHERE, pvms, areas,
|
|
||||||
areas_size, can_split,
|
|
||||||
prev_lvseg, &allocated, new_extents)) {
|
|
||||||
stack;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
finished:
|
|
||||||
if (allocated != new_extents) {
|
if (allocated != new_extents) {
|
||||||
log_error("Insufficient suitable %sallocatable extents "
|
log_error("Insufficient suitable %sallocatable extents "
|
||||||
"for logical volume %s: %u more required",
|
"for logical volume %s: %u more required",
|
||||||
@ -1165,6 +1143,13 @@ static int _allocate(struct alloc_handle *ah,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ah->log_count && !ah->log_area.len) {
|
||||||
|
log_error("Insufficient extents for log allocation "
|
||||||
|
"for logical volume %s.",
|
||||||
|
lv ? lv->name : "");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -78,17 +78,18 @@
|
|||||||
#define FMT_RESIZE_PV 0x00000080U /* Supports pvresize? */
|
#define FMT_RESIZE_PV 0x00000080U /* Supports pvresize? */
|
||||||
#define FMT_UNLIMITED_STRIPESIZE 0x00000100U /* Unlimited stripe size? */
|
#define FMT_UNLIMITED_STRIPESIZE 0x00000100U /* Unlimited stripe size? */
|
||||||
|
|
||||||
|
/* Ordered list - see lv_manip.c */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ALLOC_INVALID = 0,
|
ALLOC_INVALID,
|
||||||
ALLOC_INHERIT,
|
|
||||||
ALLOC_CONTIGUOUS,
|
ALLOC_CONTIGUOUS,
|
||||||
ALLOC_CLING,
|
ALLOC_CLING,
|
||||||
ALLOC_NORMAL,
|
ALLOC_NORMAL,
|
||||||
ALLOC_ANYWHERE
|
ALLOC_ANYWHERE,
|
||||||
|
ALLOC_INHERIT
|
||||||
} alloc_policy_t;
|
} alloc_policy_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
AREA_UNASSIGNED = 0,
|
AREA_UNASSIGNED,
|
||||||
AREA_PV,
|
AREA_PV,
|
||||||
AREA_LV
|
AREA_LV
|
||||||
} area_type_t;
|
} area_type_t;
|
||||||
|
@ -281,15 +281,8 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
|||||||
if (lp->mirrors == existing_mirrors) {
|
if (lp->mirrors == existing_mirrors) {
|
||||||
if (!seg->log_lv && !arg_count(cmd, corelog_ARG)) {
|
if (!seg->log_lv && !arg_count(cmd, corelog_ARG)) {
|
||||||
/* No disk log present, add one. */
|
/* No disk log present, add one. */
|
||||||
/* FIXME: Why doesn't this work? Without
|
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
|
||||||
it, we will probably put the log on the
|
return_0;
|
||||||
same device as a mirror leg.
|
|
||||||
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv))) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
parallel_areas = NULL;
|
|
||||||
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL)) {
|
if (!lv_mirror_percent(cmd, lv, 0, &sync_percent, NULL)) {
|
||||||
log_error("Unable to determine mirror sync status.");
|
log_error("Unable to determine mirror sync status.");
|
||||||
return 0;
|
return 0;
|
||||||
@ -297,7 +290,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
|||||||
|
|
||||||
segtype = get_segtype_from_string(cmd, "striped");
|
segtype = get_segtype_from_string(cmd, "striped");
|
||||||
|
|
||||||
if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1,
|
if (!(ah = allocate_extents(lv->vg, NULL, segtype, 0,
|
||||||
0, 1, 0,
|
0, 1, 0,
|
||||||
NULL, 0, 0, lp->pvh,
|
NULL, 0, 0, lp->pvh,
|
||||||
lp->alloc,
|
lp->alloc,
|
||||||
|
Loading…
Reference in New Issue
Block a user