mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
more lvconvert mirror code
This commit is contained in:
parent
7424de5b77
commit
e2619d9ec1
@ -1,5 +1,10 @@
|
|||||||
Version 2.02.02
|
Version 2.02.02
|
||||||
====================================
|
====================================
|
||||||
|
Add some activation logic to remove_mirror_images().
|
||||||
|
lvconvert can remove specified PVs from a mirror.
|
||||||
|
lvconvert turns an existing LV into a mirror.
|
||||||
|
Allow signed mirrors arguments.
|
||||||
|
Move create_mirror_log() into toollib.
|
||||||
Determine parallel PVs to avoid with ALLOC_NORMAL allocation.
|
Determine parallel PVs to avoid with ALLOC_NORMAL allocation.
|
||||||
Fix lv_empty.
|
Fix lv_empty.
|
||||||
|
|
||||||
|
@ -561,8 +561,14 @@ int create_mirror_layers(struct alloc_handle *ah,
|
|||||||
uint32_t status,
|
uint32_t status,
|
||||||
uint32_t region_size,
|
uint32_t region_size,
|
||||||
struct logical_volume *log_lv);
|
struct logical_volume *log_lv);
|
||||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors);
|
int add_mirror_layers(struct alloc_handle *ah,
|
||||||
int remove_all_mirror_images(struct logical_volume *lv);
|
uint32_t num_mirrors,
|
||||||
|
uint32_t existing_mirrors,
|
||||||
|
struct logical_volume *lv,
|
||||||
|
struct segment_type *segtype);
|
||||||
|
|
||||||
|
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||||
|
struct list *removable_pvs, int remove_log);
|
||||||
/*
|
/*
|
||||||
* Given mirror image or mirror log segment, find corresponding mirror segment
|
* Given mirror image or mirror log segment, find corresponding mirror segment
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#include "activate.h"
|
#include "activate.h"
|
||||||
#include "lv_alloc.h"
|
#include "lv_alloc.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
|
#include "locking.h" /* FIXME Should not be used in this file */
|
||||||
|
|
||||||
struct lv_segment *find_mirror_seg(struct lv_segment *seg)
|
struct lv_segment *find_mirror_seg(struct lv_segment *seg)
|
||||||
{
|
{
|
||||||
@ -62,6 +63,9 @@ static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volum
|
|||||||
|
|
||||||
list_init(&lv_from->segments);
|
list_init(&lv_from->segments);
|
||||||
|
|
||||||
|
lv_to->le_count = lv_from->le_count;
|
||||||
|
lv_to->size = lv_from->size;
|
||||||
|
|
||||||
lv_from->le_count = 0;
|
lv_from->le_count = 0;
|
||||||
lv_from->size = 0;
|
lv_from->size = 0;
|
||||||
}
|
}
|
||||||
@ -69,65 +73,163 @@ static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volum
|
|||||||
/*
|
/*
|
||||||
* Reduce mirrored_seg to num_mirrors images.
|
* Reduce mirrored_seg to num_mirrors images.
|
||||||
*/
|
*/
|
||||||
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors)
|
int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
|
||||||
|
struct list *removable_pvs, int remove_log)
|
||||||
{
|
{
|
||||||
uint32_t m;
|
uint32_t m;
|
||||||
|
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_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;
|
||||||
|
|
||||||
|
log_very_verbose("Reducing mirror set from %" PRIu32 " to %"
|
||||||
|
PRIu32 " image(s)%s.",
|
||||||
|
old_area_count, num_mirrors,
|
||||||
|
remove_log ? " and no log volume" : "");
|
||||||
|
|
||||||
|
/* Move removable_pvs to end of array */
|
||||||
|
if (removable_pvs) {
|
||||||
|
for (s = 0; s < mirrored_seg->area_count; s++) {
|
||||||
|
all_pvs_removable = 1;
|
||||||
|
sub_lv = seg_lv(mirrored_seg, s);
|
||||||
|
list_iterate_items(seg, &sub_lv->segments) {
|
||||||
|
for (s1 = 0; s1 < seg->area_count; s1++) {
|
||||||
|
if (seg_type(seg, s1) != AREA_PV)
|
||||||
|
/* FIXME Recurse for AREA_LV */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pv = seg_pv(seg, s1);
|
||||||
|
|
||||||
|
pv_found = 0;
|
||||||
|
list_iterate_items(pvl, removable_pvs) {
|
||||||
|
if (pv->dev->dev == pvl->pv->dev->dev) {
|
||||||
|
pv_found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!pv_found) {
|
||||||
|
all_pvs_removable = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!all_pvs_removable)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (all_pvs_removable) {
|
||||||
|
/* Swap segment to end */
|
||||||
|
new_area_count--;
|
||||||
|
area = mirrored_seg->areas[new_area_count];
|
||||||
|
mirrored_seg->areas[new_area_count] = mirrored_seg->areas[s];
|
||||||
|
mirrored_seg->areas[s] = area;
|
||||||
|
}
|
||||||
|
/* Found enough matches? */
|
||||||
|
if (new_area_count == num_mirrors)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (new_area_count == mirrored_seg->area_count) {
|
||||||
|
log_error("No mirror images found using specified PVs.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (m = num_mirrors; m < mirrored_seg->area_count; m++) {
|
for (m = num_mirrors; m < mirrored_seg->area_count; m++) {
|
||||||
|
seg_lv(mirrored_seg, m)->status &= ~MIRROR_IMAGE;
|
||||||
|
seg_lv(mirrored_seg, m)->status |= VISIBLE_LV;
|
||||||
|
}
|
||||||
|
|
||||||
|
mirrored_seg->area_count = num_mirrors;
|
||||||
|
|
||||||
|
/* If no more mirrors, remove mirror layer */
|
||||||
|
if (num_mirrors == 1) {
|
||||||
|
lv1 = seg_lv(mirrored_seg, 0);
|
||||||
|
_move_lv_segments(mirrored_seg->lv, lv1);
|
||||||
|
mirrored_seg->lv->status &= ~MIRRORED;
|
||||||
|
remove_log = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove_log) {
|
||||||
|
log_lv = mirrored_seg->log_lv;
|
||||||
|
mirrored_seg->log_lv = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To successfully remove these unwanted LVs we need to
|
||||||
|
* remove the LVs from the mirror set, commit that metadata
|
||||||
|
* then deactivate and remove them fully.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME lv1 has no segments here so shouldn't be written to disk! */
|
||||||
|
|
||||||
|
if (!vg_write(mirrored_seg->lv->vg)) {
|
||||||
|
log_error("intermediate VG write failed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!suspend_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
|
||||||
|
log_error("Failed to lock %s", mirrored_seg->lv->name);
|
||||||
|
vg_revert(mirrored_seg->lv->vg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vg_commit(mirrored_seg->lv->vg)) {
|
||||||
|
resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_very_verbose("Updating \"%s\" in kernel", mirrored_seg->lv->name);
|
||||||
|
|
||||||
|
if (!resume_lv(mirrored_seg->lv->vg->cmd, mirrored_seg->lv)) {
|
||||||
|
log_error("Problem reactivating %s", mirrored_seg->lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete the 'orphan' LVs */
|
||||||
|
for (m = num_mirrors; m < old_area_count; m++) {
|
||||||
|
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, seg_lv(mirrored_seg, m))) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!lv_remove(seg_lv(mirrored_seg, m))) {
|
if (!lv_remove(seg_lv(mirrored_seg, m))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mirrored_seg->area_count = num_mirrors;
|
if (lv1) {
|
||||||
|
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, lv1)) {
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int remove_all_mirror_images(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
struct lv_segment *seg;
|
|
||||||
struct logical_volume *lv1;
|
|
||||||
|
|
||||||
seg = first_seg(lv);
|
|
||||||
|
|
||||||
if (!remove_mirror_images(seg, 1)) {
|
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seg->log_lv && !lv_remove(seg->log_lv)) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lv1 = seg_lv(seg, 0);
|
|
||||||
|
|
||||||
_move_lv_segments(lv, lv1);
|
|
||||||
|
|
||||||
if (!lv_remove(lv1)) {
|
if (!lv_remove(lv1)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lv->status &= ~MIRRORED;
|
if (log_lv) {
|
||||||
|
if (!deactivate_lv(mirrored_seg->lv->vg->cmd, log_lv)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lv_remove(log_lv)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Add mirror images to an existing mirror
|
|
||||||
*/
|
|
||||||
/* FIXME
|
|
||||||
int add_mirror_images(struct alloc_handle *ah,
|
|
||||||
uint32_t first_area,
|
|
||||||
uint32_t num_areas,
|
|
||||||
struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int _create_layers_for_mirror(struct alloc_handle *ah,
|
static int _create_layers_for_mirror(struct alloc_handle *ah,
|
||||||
uint32_t first_area,
|
uint32_t first_area,
|
||||||
uint32_t num_mirrors,
|
uint32_t num_mirrors,
|
||||||
@ -161,7 +263,10 @@ static int _create_layers_for_mirror(struct alloc_handle *ah,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lv_add_segment(ah, m, 1, img_lvs[m],
|
if (m < first_area)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!lv_add_segment(ah, m - first_area, 1, img_lvs[m],
|
||||||
get_segtype_from_string(lv->vg->cmd,
|
get_segtype_from_string(lv->vg->cmd,
|
||||||
"striped"),
|
"striped"),
|
||||||
0, NULL, 0, 0, 0, NULL)) {
|
0, NULL, 0, 0, 0, NULL)) {
|
||||||
@ -219,6 +324,30 @@ int create_mirror_layers(struct alloc_handle *ah,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int add_mirror_layers(struct alloc_handle *ah,
|
||||||
|
uint32_t num_mirrors,
|
||||||
|
uint32_t existing_mirrors,
|
||||||
|
struct logical_volume *lv,
|
||||||
|
struct segment_type *segtype)
|
||||||
|
{
|
||||||
|
struct logical_volume **img_lvs;
|
||||||
|
|
||||||
|
if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
|
||||||
|
log_error("img_lvs allocation failed. "
|
||||||
|
"Remove new LV and retry.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_create_layers_for_mirror(ah, 0, num_mirrors,
|
||||||
|
lv, segtype,
|
||||||
|
img_lvs)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Replace any LV segments on given PV with temporary mirror.
|
* Replace any LV segments on given PV with temporary mirror.
|
||||||
* Returns list of LVs changed.
|
* Returns list of LVs changed.
|
||||||
|
@ -85,11 +85,12 @@ xx(lvconvert,
|
|||||||
"\t[-d|--debug]\n"
|
"\t[-d|--debug]\n"
|
||||||
"\t[-h|-?|--help]\n"
|
"\t[-h|-?|--help]\n"
|
||||||
"\t[-m|--mirrors Mirrors]\n"
|
"\t[-m|--mirrors Mirrors]\n"
|
||||||
|
"\t[-R|--regionsize MirrorLogRegionSize]\n"
|
||||||
"\t[-v|--verbose]\n"
|
"\t[-v|--verbose]\n"
|
||||||
"\t[--version]" "\n"
|
"\t[--version]" "\n"
|
||||||
"\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n",
|
"\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n",
|
||||||
|
|
||||||
alloc_ARG, mirrors_ARG, test_ARG)
|
alloc_ARG, mirrors_ARG, regionsize_ARG, test_ARG)
|
||||||
|
|
||||||
xx(lvcreate,
|
xx(lvcreate,
|
||||||
"Create a logical volume",
|
"Create a logical volume",
|
||||||
|
@ -13,10 +13,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
#include "lv_alloc.h"
|
||||||
|
|
||||||
struct lvconvert_params {
|
struct lvconvert_params {
|
||||||
const char *lv_name;
|
const char *lv_name;
|
||||||
uint32_t mirrors;
|
uint32_t mirrors;
|
||||||
|
sign_t mirrors_sign;
|
||||||
|
uint32_t region_size;
|
||||||
|
|
||||||
alloc_policy_t alloc;
|
alloc_policy_t alloc;
|
||||||
|
|
||||||
@ -40,7 +43,29 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
|
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
|
||||||
|
lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* --regionsize is only valid when converting an LV into a mirror.
|
||||||
|
* This is checked when we know the state of the LV being converted.
|
||||||
|
*/
|
||||||
|
if (arg_count(cmd, regionsize_ARG)) {
|
||||||
|
if (arg_sign_value(cmd, regionsize_ARG, 0) == SIGN_MINUS) {
|
||||||
|
log_error("Negative regionsize is invalid");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lp->region_size = 2 * arg_uint_value(cmd, regionsize_ARG, 0);
|
||||||
|
} else
|
||||||
|
lp->region_size = 2 * find_config_int(cmd->cft->root,
|
||||||
|
"activation/mirror_region_size",
|
||||||
|
DEFAULT_MIRROR_REGION_SIZE);
|
||||||
|
|
||||||
|
if (lp->region_size & (lp->region_size - 1)) {
|
||||||
|
log_error("Region size (%" PRIu32 ") must be a power of 2",
|
||||||
|
lp->region_size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
log_error("Please give logical volume path");
|
log_error("Please give logical volume path");
|
||||||
@ -61,8 +86,33 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
|||||||
{
|
{
|
||||||
struct lv_segment *seg;
|
struct lv_segment *seg;
|
||||||
uint32_t existing_mirrors;
|
uint32_t existing_mirrors;
|
||||||
// struct alloc_handle *ah = NULL;
|
struct alloc_handle *ah = NULL;
|
||||||
// struct logical_volume *log_lv;
|
struct logical_volume *log_lv;
|
||||||
|
struct list *parallel_areas;
|
||||||
|
struct segment_type *segtype;
|
||||||
|
|
||||||
|
seg = first_seg(lv);
|
||||||
|
existing_mirrors = seg->area_count;
|
||||||
|
|
||||||
|
/* Adjust required number of mirrors */
|
||||||
|
if (lp->mirrors_sign == SIGN_PLUS)
|
||||||
|
lp->mirrors = existing_mirrors + lp->mirrors;
|
||||||
|
else if (lp->mirrors_sign == SIGN_MINUS) {
|
||||||
|
if (lp->mirrors >= existing_mirrors) {
|
||||||
|
log_error("Logical volume %s only has %" PRIu32 " mirrors.",
|
||||||
|
lv->name, existing_mirrors);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lp->mirrors = existing_mirrors - lp->mirrors;
|
||||||
|
} else
|
||||||
|
lp->mirrors += 1;
|
||||||
|
|
||||||
|
if (arg_count(cmd, regionsize_ARG) && (lv->status & MIRRORED) &&
|
||||||
|
(lp->region_size != seg->region_size)) {
|
||||||
|
log_error("Mirror log region size cannot be changed on "
|
||||||
|
"an existing mirror.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((lp->mirrors == 1)) {
|
if ((lp->mirrors == 1)) {
|
||||||
if (!(lv->status & MIRRORED)) {
|
if (!(lv->status & MIRRORED)) {
|
||||||
@ -70,8 +120,8 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
|||||||
lv->name);
|
lv->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* FIXME If allocatable_pvs supplied only remove those */
|
|
||||||
if (!remove_all_mirror_images(lv)) {
|
if (!remove_mirror_images(seg, 1, lp->pv_count ? lp->pvh : NULL, 1)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -82,8 +132,6 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
|||||||
"mirror segments.", lv->name);
|
"mirror segments.", lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
seg = first_seg(lv);
|
|
||||||
existing_mirrors = seg->area_count;
|
|
||||||
if (lp->mirrors == existing_mirrors) {
|
if (lp->mirrors == existing_mirrors) {
|
||||||
log_error("Logical volume %s already has %"
|
log_error("Logical volume %s already has %"
|
||||||
PRIu32 " mirror(s).", lv->name,
|
PRIu32 " mirror(s).", lv->name,
|
||||||
@ -100,21 +148,61 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
|
|||||||
"supported yet.");
|
"supported yet.");
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (!remove_mirror_images(seg, lp->mirrors)) {
|
/* Reduce number of mirrors */
|
||||||
|
if (!remove_mirror_images(seg, lp->mirrors, lp->pv_count ? lp->pvh : NULL, 0)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* Make existing LV into mirror set */
|
||||||
/* FIXME Share code with lvcreate */
|
/* FIXME Share code with lvcreate */
|
||||||
/* region size, log_name, create log_lv, zero it */
|
|
||||||
// Allocate (mirrors) new areas & log - replace mirrored_pv with mirrored_lv
|
/* FIXME Why is this restriction here? Fix it! */
|
||||||
// Restructure as mirror - add existing param to create_mirror_layers
|
list_iterate_items(seg, &lv->segments) {
|
||||||
log_error("Adding mirror images is not supported yet.");
|
if (seg_is_striped(seg) && seg->area_count > 1) {
|
||||||
|
log_error("Mirrors of striped volumes are not yet supported.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv))) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
segtype = get_segtype_from_string(cmd, "striped");
|
||||||
|
|
||||||
|
if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1,
|
||||||
|
lp->mirrors - 1, 1,
|
||||||
|
lv->le_count * (lp->mirrors - 1),
|
||||||
|
NULL, 0, 0, lp->pvh,
|
||||||
|
lp->alloc,
|
||||||
|
parallel_areas))) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lp->region_size = adjusted_mirror_region_size(lv->vg->extent_size,
|
||||||
|
lv->le_count,
|
||||||
|
lp->region_size);
|
||||||
|
|
||||||
|
if (!(log_lv = create_mirror_log(cmd, lv->vg, ah,
|
||||||
|
lp->alloc,
|
||||||
|
lv->name))) {
|
||||||
|
log_error("Failed to create mirror log.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!create_mirror_layers(ah, 1, lp->mirrors, lv,
|
||||||
|
segtype, 0, lp->region_size,
|
||||||
|
log_lv)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
|
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
|
||||||
|
|
||||||
if (!vg_write(lv->vg)) {
|
if (!vg_write(lv->vg)) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||||
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
|
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This file is part of LVM2.
|
* This file is part of LVM2.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user