From: agk@sourceware.org <agk@sourceware.org>
To: lvm-devel@redhat.com
Subject: LVM2 ./WHATS_NEW lib/metadata/lv_manip.c lib/m ...
Date: 20 Dec 2007 18:55:47 -0000 [thread overview]
Message-ID: <20071220185547.9279.qmail@sourceware.org> (raw)
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk at sourceware.org 2007-12-20 18:55:46
Modified files:
. : WHATS_NEW
lib/metadata : lv_manip.c metadata-exported.h metadata.c
metadata.h mirror.c
tools : lvconvert.c lvresize.c toollib.c
Log message:
stacked mirror support (incomplete)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.747&r2=1.748
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.137&r2=1.138
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.26&r2=1.27
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.144&r2=1.145
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.175&r2=1.176
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/mirror.c.diff?cvsroot=lvm2&r1=1.46&r2=1.47
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvconvert.c.diff?cvsroot=lvm2&r1=1.48&r2=1.49
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvresize.c.diff?cvsroot=lvm2&r1=1.89&r2=1.90
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.119&r2=1.120
--- LVM2/WHATS_NEW 2007/12/20 15:42:55 1.747
+++ LVM2/WHATS_NEW 2007/12/20 18:55:46 1.748
@@ -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.
--- LVM2/lib/metadata/lv_manip.c 2007/12/20 15:42:55 1.137
+++ LVM2/lib/metadata/lv_manip.c 2007/12/20 18:55:46 1.138
@@ -1407,6 +1407,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
lv_from->size = 0;
}
+/*
+ * 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 *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 */
-/* FIXME: how to specify what should be removed if multiple layers stacked? */
-int remove_layer_from_lv(struct logical_volume *lv)
+int remove_layer_from_lv(struct logical_volume *lv,
+ struct logical_volume *layer_lv)
{
- struct logical_volume *orig_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;
}
--- LVM2/lib/metadata/metadata-exported.h 2007/12/20 15:42:55 1.26
+++ LVM2/lib/metadata/metadata-exported.h 2007/12/20 18:55:46 1.27
@@ -398,7 +398,10 @@
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 @@
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 @@
#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 @@
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 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);
--- LVM2/lib/metadata/metadata.c 2007/11/15 02:20:03 1.144
+++ LVM2/lib/metadata/metadata.c 2007/12/20 18:55:46 1.145
@@ -937,7 +937,7 @@
}
/* 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 @@
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 @@
}
/* 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;
--- LVM2/lib/metadata/metadata.h 2007/12/20 15:42:55 1.175
+++ LVM2/lib/metadata/metadata.h 2007/12/20 18:55:46 1.176
@@ -264,10 +264,10 @@
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.
--- LVM2/lib/metadata/mirror.c 2007/12/20 15:42:55 1.46
+++ LVM2/lib/metadata/mirror.c 2007/12/20 18:55:46 1.47
@@ -33,11 +33,40 @@
#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 @@
/*
* 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 @@
}
/*
- * 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 @@
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 @@
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)))
- return 0;
+ /* 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(mirrored_seg, lv1))
+ if (lv1 && !_delete_lv(lv, lv1))
return 0;
- if (log_lv && !_delete_lv(mirrored_seg, log_lv))
+ 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 (!_merge_mirror_images(parent_lv, &lvlist)) {
+ log_error("Failed to add mirror images");
+ return 0;
+ }
+ }
return 1;
}
@@ -338,19 +508,13 @@
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 @@
*/
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 @@
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 @@
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);
}
--- LVM2/tools/lvconvert.c 2007/12/20 15:42:55 1.48
+++ LVM2/tools/lvconvert.c 2007/12/20 18:55:46 1.49
@@ -369,14 +369,20 @@
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,
--- LVM2/tools/lvresize.c 2007/11/15 02:20:03 1.89
+++ LVM2/tools/lvresize.c 2007/12/20 18:55:46 1.90
@@ -435,7 +435,7 @@
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 @@
}
if (seg_is_mirrored(seg))
- seg_mirrors = seg->area_count;
+ seg_mirrors = lv_mirror_count(seg->lv);
else
seg_mirrors = 0;
--- LVM2/tools/toollib.c 2007/12/20 15:42:55 1.119
+++ LVM2/tools/toollib.c 2007/12/20 18:55:46 1.120
@@ -1222,6 +1222,12 @@
return 0;
}
+ if (strstr(name, "_resync")) {
+ log_error("Names including \"_resync\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
return 1;
}
next reply other threads:[~2007-12-20 18:55 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-20 18:55 agk [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-02-23 17:36 LVM2 ./WHATS_NEW lib/metadata/lv_manip.c lib/m jbrassow
2012-02-23 3:57 jbrassow
2012-02-15 15:18 zkabelac
2012-02-08 13:05 zkabelac
2012-02-01 2:10 agk
2011-10-22 16:42 zkabelac
2011-09-06 18:49 agk
2011-08-18 19:41 jbrassow
2011-08-11 3:29 jbrassow
2011-06-23 14:01 jbrassow
2011-04-09 19:05 zkabelac
2011-01-24 14:19 agk
2011-01-11 17:05 jbrassow
2010-10-14 20:03 jbrassow
2010-04-23 19:27 snitzer
2010-04-09 1:00 agk
2010-03-25 21:19 agk
2010-03-25 2:31 agk
2010-01-08 22:32 jbrassow
2010-01-11 13:34 ` Zdenek Kabelac
2009-05-13 21:29 mbroz
2009-05-13 21:28 mbroz
2009-04-21 14:32 mbroz
2009-04-07 10:20 mbroz
2008-03-28 19:08 wysochanski
2008-01-26 0:25 agk
2008-01-18 22:00 agk
2007-08-28 16:14 wysochanski
2007-08-03 21:22 wysochanski
2006-12-13 3:39 agk
2006-10-23 15:54 agk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071220185547.9279.qmail@sourceware.org \
--to=agk@sourceware.org \
--cc=lvm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.