* [RFC] [PATCH] lvm2: mirroredlog support
@ 2008-12-30 0:10 ` malahal
0 siblings, 0 replies; 19+ messages in thread
From: malahal @ 2008-12-30 0:10 UTC (permalink / raw)
To: dm-devel; +Cc: agk
This patch adds '--mirroredlog' option to LVM commands to create a
mirror with mirrored log device. Rebased to the latest LVM code
(LVM2.2.02.43). Appreciate any comments.
Signed-off-by: Stefan Raspl <raspl@de.ibm.com>
---
lib/activate/activate.c | 16 ++++++
lib/metadata/metadata-exported.h | 17 +++++--
lib/metadata/mirror.c | 90 ++++++++++++++++++++++++++++-----------
tools/args.h | 1
tools/commands.h | 7 ++-
tools/lvconvert.c | 17 +++----
tools/lvcreate.c | 9 +++
tools/pvmove.c | 4 -
8 files changed, 118 insertions(+), 43 deletions(-)
diff -r d548a82e6195 lib/activate/activate.c
--- a/lib/activate/activate.c Mon Dec 29 15:36:50 2008 -0800
+++ b/lib/activate/activate.c Mon Dec 29 15:54:33 2008 -0800
@@ -948,6 +948,8 @@
{
struct logical_volume *lv;
struct lvinfo info;
+ struct lv_segment *seg, *log_seg;
+ struct segment_type *type = get_segtype_from_string(cmd, "mirror");
int r;
if (!activation())
@@ -975,6 +977,20 @@
if (!monitor_dev_for_events(cmd, lv, 0))
stack;
+
+ if ( !dm_list_empty(&lv->segments) ) {
+ seg = dm_list_item(dm_list_first(&lv->segments), struct lv_segment);
+ if (seg->log_lv) {
+ log_very_verbose("lv %s is mirrored, check it's log %s...", lv->name, seg->log_lv->name);
+ if ( !dm_list_empty(&seg->log_lv->segments) ) {
+ log_seg = dm_list_item(dm_list_first(&seg->log_lv->segments), struct lv_segment);
+ if (log_seg->segtype == type) {
+ log_verbose("log %s is mirrored, unregister for events", log_seg->lv->name);
+ monitor_dev_for_events(cmd, log_seg->lv, 0);
+ }
+ }
+ }
+ }
memlock_inc();
r = _lv_deactivate(lv);
diff -r d548a82e6195 lib/metadata/metadata-exported.h
--- a/lib/metadata/metadata-exported.h Mon Dec 29 15:36:50 2008 -0800
+++ b/lib/metadata/metadata-exported.h Mon Dec 29 15:54:33 2008 -0800
@@ -505,9 +505,11 @@
*/
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes,
+ const struct segment_type *segtype,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
uint32_t region_size, uint32_t log_count,
- struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
+ struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
+ uint32_t mirrored_log);
int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t log_count,
struct dm_list *pvs, uint32_t status_mask);
@@ -526,16 +528,21 @@
int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
struct dm_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,
+ const struct segment_type *segtype,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
- uint32_t log_count);
+ uint32_t log_count, uint32_t mirrored_log);
struct logical_volume *detach_mirror_log(struct lv_segment *seg);
int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct dm_list *removable_pvs);
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ const struct segment_type *segtype,
uint32_t log_count, uint32_t region_size,
- struct dm_list *allocatable_pvs, alloc_policy_t alloc);
+ struct dm_list *allocatable_pvs, alloc_policy_t alloc,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrored_log);
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct dm_list *removable_pvs, unsigned remove_log);
diff -r d548a82e6195 lib/metadata/mirror.c
--- a/lib/metadata/mirror.c Mon Dec 29 15:36:50 2008 -0800
+++ b/lib/metadata/mirror.c Mon Dec 29 15:54:33 2008 -0800
@@ -1241,7 +1241,8 @@
struct alloc_handle *ah,
alloc_policy_t alloc,
const char *lv_name,
- const char *suffix)
+ const char *suffix,
+ uint32_t mirrored_log)
{
struct logical_volume *log_lv;
char *log_name;
@@ -1263,7 +1264,7 @@
alloc, 0, lv->vg)))
return_NULL;
- if (!lv_add_log_segment(ah, log_lv))
+ if (!mirrored_log && !lv_add_log_segment(ah, log_lv))
return_NULL;
return log_lv;
@@ -1272,10 +1273,16 @@
static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
struct alloc_handle *ah,
struct logical_volume *lv,
+ const struct segment_type *segtype,
uint32_t log_count,
- uint32_t region_size __attribute((unused)),
+ uint32_t region_size,
alloc_policy_t alloc,
- int in_sync)
+ int in_sync,
+ uint32_t mirrors,
+ uint32_t stripes,
+ uint32_t stripe_size,
+ struct list *allocatable_pvs,
+ uint32_t mirrored_log)
{
struct logical_volume *log_lv;
const char *suffix, *c;
@@ -1317,9 +1324,18 @@
}
if (!(log_lv = _create_mirror_log(lv, ah, alloc,
- (const char *) lv_name, suffix))) {
+ (const char *) lv_name, suffix, mirrored_log))) {
log_error("Failed to create mirror log.");
return NULL;
+ }
+
+ if (mirrored_log) {
+ if (!lv_extend(log_lv, segtype, stripes, stripe_size,
+ 1u, 1u, NULL, 0u, 0u, allocatable_pvs, alloc))
+ return NULL;
+
+ add_mirror_images(cmd, log_lv, segtype, mirrors, stripes, stripe_size,
+ region_size, allocatable_pvs, alloc, 0, 0);
}
if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
@@ -1339,8 +1355,11 @@
}
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ const struct segment_type *seg_type,
uint32_t log_count, uint32_t region_size,
- struct dm_list *allocatable_pvs, alloc_policy_t alloc)
+ struct dm_list *allocatable_pvs, alloc_policy_t alloc,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrored_log)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1402,8 +1421,10 @@
else
in_sync = 0;
- if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
- region_size, alloc, in_sync)))
+ if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count,
+ region_size, alloc, in_sync,
+ mirrors, stripes, stripe_size, allocatable_pvs,
+ mirrored_log)))
return_0;
if (!attach_mirror_log(first_seg(lv), log_lv))
@@ -1417,9 +1438,10 @@
* Convert "linear" LV to "mirror".
*/
int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes, uint32_t region_size,
+ const struct segment_type *seg_type, uint32_t mirrors,
+ uint32_t stripes, uint32_t stripe_size, uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
- uint32_t log_count)
+ uint32_t log_count, uint32_t mirrored_log)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1442,9 +1464,16 @@
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
return_0;
- ah = allocate_extents(lv->vg, NULL, segtype,
- stripes, mirrors, log_count, lv->le_count,
- allocatable_pvs, alloc, parallel_areas);
+ if (mirrored_log)
+ // no PV allocation restriction for mirrored logs
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, 0, 1,
+ allocatable_pvs, alloc, parallel_areas);
+ else
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, log_count, lv->le_count,
+ allocatable_pvs, alloc, parallel_areas);
+
if (!ah) {
log_error("Unable to allocate extents for mirror(s).");
return 0;
@@ -1453,10 +1482,19 @@
/*
* create and initialize mirror log
*/
- if (log_count &&
- !(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count, region_size,
- alloc, mirror_in_sync())))
- return_0;
+ if (log_count) {
+ if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count, region_size,
+ alloc, mirror_in_sync(), mirrors, stripes,
+ stripe_size, allocatable_pvs, mirrored_log)))
+ return_0;
+ if (mirrored_log) {
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, 0, lv->le_count,
+ allocatable_pvs, alloc, parallel_areas);
+ if (!ah)
+ return_0;
+ }
+ }
/* The log initialization involves vg metadata commit.
So from here on, if failure occurs, the log must be explicitly
@@ -1512,9 +1550,11 @@
* 'pvs' is either allocatable pvs.
*/
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes,
+ const struct segment_type *seg_type, uint32_t mirrors,
+ uint32_t stripes, uint32_t stripe_size,
uint32_t region_size, uint32_t log_count,
- struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags)
+ struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
+ uint32_t mirrored_log)
{
if (!mirrors && !log_count) {
log_error("No conversion is requested");
@@ -1547,11 +1587,13 @@
region_size, pvs, alloc);
} else if (flags & MIRROR_BY_LV) {
if (!mirrors)
- return add_mirror_log(cmd, lv, log_count,
- region_size, pvs, alloc);
- return add_mirror_images(cmd, lv, mirrors,
- stripes, region_size,
- pvs, alloc, log_count);
+ return add_mirror_log(cmd, lv, seg_type, log_count,
+ region_size, pvs, alloc, mirrors,
+ stripes, stripe_size, mirrored_log);
+ return add_mirror_images(cmd, lv, seg_type, mirrors,
+ stripes, stripe_size, region_size,
+ pvs, alloc, log_count,
+ mirrored_log);
}
log_error("Unsupported mirror conversion type");
diff -r d548a82e6195 tools/args.h
--- a/tools/args.h Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/args.h Mon Dec 29 15:54:33 2008 -0800
@@ -45,6 +45,7 @@
arg(alloc_ARG, '\0', "alloc", alloc_arg, 0)
arg(separator_ARG, '\0', "separator", string_arg, 0)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0)
+arg(mirroredlog_ARG, '\0', "mirroredlog", NULL, 0)
arg(nosync_ARG, '\0', "nosync", NULL, 0)
arg(resync_ARG, '\0', "resync", NULL, 0)
arg(corelog_ARG, '\0', "corelog", NULL, 0)
diff -r d548a82e6195 tools/commands.h
--- a/tools/commands.h Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/commands.h Mon Dec 29 15:54:33 2008 -0800
@@ -93,7 +93,7 @@
"Change logical volume layout",
0,
"lvconvert "
- "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
+ "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog|--mirroredlog}]]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
@@ -115,7 +115,8 @@
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
- mirrorlog_ARG, mirrors_ARG, regionsize_ARG, snapshot_ARG, test_ARG, zero_ARG)
+ mirrorlog_ARG, mirrors_ARG, regionsize_ARG, mirroredlog_ARG,
+ snapshot_ARG, test_ARG, zero_ARG)
xx(lvcreate,
"Create a logical volume",
@@ -132,6 +133,7 @@
"\t -L|--size LogicalVolumeSize[kKmMgGtTpPeE]}\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
"\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--corelog}]]\n"
+ "\t[--mirroredlog]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
@@ -163,6 +165,7 @@
"\t[--version]\n"
"\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
+ mirroredlog_ARG,
addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG, contiguous_ARG,
corelog_ARG, extents_ARG, major_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG,
name_ARG, nosync_ARG, permission_ARG, persistent_ARG, readahead_ARG,
diff -r d548a82e6195 tools/lvconvert.c
--- a/tools/lvconvert.c Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/lvconvert.c Mon Dec 29 15:54:33 2008 -0800
@@ -383,6 +383,7 @@
const char *mirrorlog;
unsigned corelog = 0;
struct logical_volume *original_lv;
+ uint32_t mirrored_log = arg_count(cmd, mirroredlog_ARG);
seg = first_seg(lv);
existing_mirrors = lv_mirror_count(lv);
@@ -484,13 +485,13 @@
}
}
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, 1, 0,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
corelog ? 0U : 1U, lp->pvh, lp->alloc,
- MIRROR_BY_LV))
+ MIRROR_BY_LV, mirrored_log))
return_0;
if (lp->wait_completion)
lp->need_polling = 1;
@@ -513,12 +514,12 @@
*/
original_lv = _original_lv(lv);
if (!first_seg(original_lv)->log_lv && !corelog) {
- if (!add_mirror_log(cmd, original_lv, 1,
+ if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
- lp->pvh, lp->alloc))
+ lp->pvh, lp->alloc, lp->mirrors, 0, 0, mirrored_log))
return_0;
} else if (first_seg(original_lv)->log_lv && corelog) {
if (!remove_mirror_log(cmd, original_lv,
@@ -546,12 +547,12 @@
*/
original_lv = _original_lv(lv);
if (!first_seg(original_lv)->log_lv && !corelog) {
- if (!add_mirror_log(cmd, original_lv, 1,
+ if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
- lp->pvh, lp->alloc))
+ lp->pvh, lp->alloc, lp->mirrors, 0, 0, mirrored_log))
return_0;
} else if (first_seg(original_lv)->log_lv && corelog) {
if (!remove_mirror_log(cmd, original_lv,
@@ -565,13 +566,13 @@
return 0;
}
/* FIXME: can't have multiple mlogs. force corelog. */
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
+ if (!lv_add_mirrors(cmd, lv, NULL, lp->mirrors - existing_mirrors, 1, 0,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
0U, lp->pvh, lp->alloc,
- MIRROR_BY_LV))
+ MIRROR_BY_LV, lp->mirrors))
return_0;
lv->status |= CONVERTING;
lp->need_polling = 1;
diff -r d548a82e6195 tools/lvcreate.c
--- a/tools/lvcreate.c Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/lvcreate.c Mon Dec 29 15:54:33 2008 -0800
@@ -37,6 +37,7 @@
uint32_t region_size;
uint32_t mirrors;
+ uint32_t mirrored_log;
const struct segment_type *segtype;
@@ -320,6 +321,9 @@
}
lp->region_size = region_size;
}
+
+ if (arg_count(cmd, mirroredlog_ARG))
+ lp->mirrored_log = 1;
if (!_validate_mirror_params(cmd, lp))
return 0;
@@ -772,14 +776,15 @@
return_0;
if (lp->mirrors > 1) {
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, lp->stripes,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, lp->stripes, lp->stripe_size,
adjusted_mirror_region_size(
vg->extent_size,
lv->le_count,
lp->region_size),
lp->corelog ? 0U : 1U, pvh, lp->alloc,
MIRROR_BY_LV |
- (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0))) {
+ (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0),
+ lp->mirrored_log)) {
stack;
goto revert_new_lv;
}
diff -r d548a82e6195 tools/pvmove.c
--- a/tools/pvmove.c Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/pvmove.c Mon Dec 29 15:54:33 2008 -0800
@@ -251,8 +251,8 @@
return NULL;
}
- if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, log_count,
- allocatable_pvs, alloc, MIRROR_BY_SEG)) {
+ if (!lv_add_mirrors(cmd, lv_mirr, NULL, 1u, 1u, 0u, 0u, log_count,
+ allocatable_pvs, alloc, MIRROR_BY_SEG, 0)) {
log_error("Failed to convert pvmove LV to mirrored");
return_NULL;
}
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC] [PATCH] lvm2: mirroredlog support
@ 2008-12-30 0:10 ` malahal
0 siblings, 0 replies; 19+ messages in thread
From: malahal @ 2008-12-30 0:10 UTC (permalink / raw)
To: lvm-devel
This patch adds '--mirroredlog' option to LVM commands to create a
mirror with mirrored log device. Rebased to the latest LVM code
(LVM2.2.02.43). Appreciate any comments.
Signed-off-by: Stefan Raspl <raspl@de.ibm.com>
---
lib/activate/activate.c | 16 ++++++
lib/metadata/metadata-exported.h | 17 +++++--
lib/metadata/mirror.c | 90 ++++++++++++++++++++++++++++-----------
tools/args.h | 1
tools/commands.h | 7 ++-
tools/lvconvert.c | 17 +++----
tools/lvcreate.c | 9 +++
tools/pvmove.c | 4 -
8 files changed, 118 insertions(+), 43 deletions(-)
diff -r d548a82e6195 lib/activate/activate.c
--- a/lib/activate/activate.c Mon Dec 29 15:36:50 2008 -0800
+++ b/lib/activate/activate.c Mon Dec 29 15:54:33 2008 -0800
@@ -948,6 +948,8 @@
{
struct logical_volume *lv;
struct lvinfo info;
+ struct lv_segment *seg, *log_seg;
+ struct segment_type *type = get_segtype_from_string(cmd, "mirror");
int r;
if (!activation())
@@ -975,6 +977,20 @@
if (!monitor_dev_for_events(cmd, lv, 0))
stack;
+
+ if ( !dm_list_empty(&lv->segments) ) {
+ seg = dm_list_item(dm_list_first(&lv->segments), struct lv_segment);
+ if (seg->log_lv) {
+ log_very_verbose("lv %s is mirrored, check it's log %s...", lv->name, seg->log_lv->name);
+ if ( !dm_list_empty(&seg->log_lv->segments) ) {
+ log_seg = dm_list_item(dm_list_first(&seg->log_lv->segments), struct lv_segment);
+ if (log_seg->segtype == type) {
+ log_verbose("log %s is mirrored, unregister for events", log_seg->lv->name);
+ monitor_dev_for_events(cmd, log_seg->lv, 0);
+ }
+ }
+ }
+ }
memlock_inc();
r = _lv_deactivate(lv);
diff -r d548a82e6195 lib/metadata/metadata-exported.h
--- a/lib/metadata/metadata-exported.h Mon Dec 29 15:36:50 2008 -0800
+++ b/lib/metadata/metadata-exported.h Mon Dec 29 15:54:33 2008 -0800
@@ -505,9 +505,11 @@
*/
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes,
+ const struct segment_type *segtype,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
uint32_t region_size, uint32_t log_count,
- struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
+ struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
+ uint32_t mirrored_log);
int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t log_count,
struct dm_list *pvs, uint32_t status_mask);
@@ -526,16 +528,21 @@
int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
struct dm_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,
+ const struct segment_type *segtype,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
- uint32_t log_count);
+ uint32_t log_count, uint32_t mirrored_log);
struct logical_volume *detach_mirror_log(struct lv_segment *seg);
int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct dm_list *removable_pvs);
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ const struct segment_type *segtype,
uint32_t log_count, uint32_t region_size,
- struct dm_list *allocatable_pvs, alloc_policy_t alloc);
+ struct dm_list *allocatable_pvs, alloc_policy_t alloc,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrored_log);
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct dm_list *removable_pvs, unsigned remove_log);
diff -r d548a82e6195 lib/metadata/mirror.c
--- a/lib/metadata/mirror.c Mon Dec 29 15:36:50 2008 -0800
+++ b/lib/metadata/mirror.c Mon Dec 29 15:54:33 2008 -0800
@@ -1241,7 +1241,8 @@
struct alloc_handle *ah,
alloc_policy_t alloc,
const char *lv_name,
- const char *suffix)
+ const char *suffix,
+ uint32_t mirrored_log)
{
struct logical_volume *log_lv;
char *log_name;
@@ -1263,7 +1264,7 @@
alloc, 0, lv->vg)))
return_NULL;
- if (!lv_add_log_segment(ah, log_lv))
+ if (!mirrored_log && !lv_add_log_segment(ah, log_lv))
return_NULL;
return log_lv;
@@ -1272,10 +1273,16 @@
static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
struct alloc_handle *ah,
struct logical_volume *lv,
+ const struct segment_type *segtype,
uint32_t log_count,
- uint32_t region_size __attribute((unused)),
+ uint32_t region_size,
alloc_policy_t alloc,
- int in_sync)
+ int in_sync,
+ uint32_t mirrors,
+ uint32_t stripes,
+ uint32_t stripe_size,
+ struct list *allocatable_pvs,
+ uint32_t mirrored_log)
{
struct logical_volume *log_lv;
const char *suffix, *c;
@@ -1317,9 +1324,18 @@
}
if (!(log_lv = _create_mirror_log(lv, ah, alloc,
- (const char *) lv_name, suffix))) {
+ (const char *) lv_name, suffix, mirrored_log))) {
log_error("Failed to create mirror log.");
return NULL;
+ }
+
+ if (mirrored_log) {
+ if (!lv_extend(log_lv, segtype, stripes, stripe_size,
+ 1u, 1u, NULL, 0u, 0u, allocatable_pvs, alloc))
+ return NULL;
+
+ add_mirror_images(cmd, log_lv, segtype, mirrors, stripes, stripe_size,
+ region_size, allocatable_pvs, alloc, 0, 0);
}
if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
@@ -1339,8 +1355,11 @@
}
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ const struct segment_type *seg_type,
uint32_t log_count, uint32_t region_size,
- struct dm_list *allocatable_pvs, alloc_policy_t alloc)
+ struct dm_list *allocatable_pvs, alloc_policy_t alloc,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrored_log)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1402,8 +1421,10 @@
else
in_sync = 0;
- if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
- region_size, alloc, in_sync)))
+ if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count,
+ region_size, alloc, in_sync,
+ mirrors, stripes, stripe_size, allocatable_pvs,
+ mirrored_log)))
return_0;
if (!attach_mirror_log(first_seg(lv), log_lv))
@@ -1417,9 +1438,10 @@
* Convert "linear" LV to "mirror".
*/
int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes, uint32_t region_size,
+ const struct segment_type *seg_type, uint32_t mirrors,
+ uint32_t stripes, uint32_t stripe_size, uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
- uint32_t log_count)
+ uint32_t log_count, uint32_t mirrored_log)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1442,9 +1464,16 @@
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
return_0;
- ah = allocate_extents(lv->vg, NULL, segtype,
- stripes, mirrors, log_count, lv->le_count,
- allocatable_pvs, alloc, parallel_areas);
+ if (mirrored_log)
+ // no PV allocation restriction for mirrored logs
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, 0, 1,
+ allocatable_pvs, alloc, parallel_areas);
+ else
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, log_count, lv->le_count,
+ allocatable_pvs, alloc, parallel_areas);
+
if (!ah) {
log_error("Unable to allocate extents for mirror(s).");
return 0;
@@ -1453,10 +1482,19 @@
/*
* create and initialize mirror log
*/
- if (log_count &&
- !(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count, region_size,
- alloc, mirror_in_sync())))
- return_0;
+ if (log_count) {
+ if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count, region_size,
+ alloc, mirror_in_sync(), mirrors, stripes,
+ stripe_size, allocatable_pvs, mirrored_log)))
+ return_0;
+ if (mirrored_log) {
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, 0, lv->le_count,
+ allocatable_pvs, alloc, parallel_areas);
+ if (!ah)
+ return_0;
+ }
+ }
/* The log initialization involves vg metadata commit.
So from here on, if failure occurs, the log must be explicitly
@@ -1512,9 +1550,11 @@
* 'pvs' is either allocatable pvs.
*/
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes,
+ const struct segment_type *seg_type, uint32_t mirrors,
+ uint32_t stripes, uint32_t stripe_size,
uint32_t region_size, uint32_t log_count,
- struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags)
+ struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
+ uint32_t mirrored_log)
{
if (!mirrors && !log_count) {
log_error("No conversion is requested");
@@ -1547,11 +1587,13 @@
region_size, pvs, alloc);
} else if (flags & MIRROR_BY_LV) {
if (!mirrors)
- return add_mirror_log(cmd, lv, log_count,
- region_size, pvs, alloc);
- return add_mirror_images(cmd, lv, mirrors,
- stripes, region_size,
- pvs, alloc, log_count);
+ return add_mirror_log(cmd, lv, seg_type, log_count,
+ region_size, pvs, alloc, mirrors,
+ stripes, stripe_size, mirrored_log);
+ return add_mirror_images(cmd, lv, seg_type, mirrors,
+ stripes, stripe_size, region_size,
+ pvs, alloc, log_count,
+ mirrored_log);
}
log_error("Unsupported mirror conversion type");
diff -r d548a82e6195 tools/args.h
--- a/tools/args.h Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/args.h Mon Dec 29 15:54:33 2008 -0800
@@ -45,6 +45,7 @@
arg(alloc_ARG, '\0', "alloc", alloc_arg, 0)
arg(separator_ARG, '\0', "separator", string_arg, 0)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0)
+arg(mirroredlog_ARG, '\0', "mirroredlog", NULL, 0)
arg(nosync_ARG, '\0', "nosync", NULL, 0)
arg(resync_ARG, '\0', "resync", NULL, 0)
arg(corelog_ARG, '\0', "corelog", NULL, 0)
diff -r d548a82e6195 tools/commands.h
--- a/tools/commands.h Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/commands.h Mon Dec 29 15:54:33 2008 -0800
@@ -93,7 +93,7 @@
"Change logical volume layout",
0,
"lvconvert "
- "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
+ "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog|--mirroredlog}]]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
@@ -115,7 +115,8 @@
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
- mirrorlog_ARG, mirrors_ARG, regionsize_ARG, snapshot_ARG, test_ARG, zero_ARG)
+ mirrorlog_ARG, mirrors_ARG, regionsize_ARG, mirroredlog_ARG,
+ snapshot_ARG, test_ARG, zero_ARG)
xx(lvcreate,
"Create a logical volume",
@@ -132,6 +133,7 @@
"\t -L|--size LogicalVolumeSize[kKmMgGtTpPeE]}\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
"\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--corelog}]]\n"
+ "\t[--mirroredlog]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
@@ -163,6 +165,7 @@
"\t[--version]\n"
"\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
+ mirroredlog_ARG,
addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG, contiguous_ARG,
corelog_ARG, extents_ARG, major_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG,
name_ARG, nosync_ARG, permission_ARG, persistent_ARG, readahead_ARG,
diff -r d548a82e6195 tools/lvconvert.c
--- a/tools/lvconvert.c Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/lvconvert.c Mon Dec 29 15:54:33 2008 -0800
@@ -383,6 +383,7 @@
const char *mirrorlog;
unsigned corelog = 0;
struct logical_volume *original_lv;
+ uint32_t mirrored_log = arg_count(cmd, mirroredlog_ARG);
seg = first_seg(lv);
existing_mirrors = lv_mirror_count(lv);
@@ -484,13 +485,13 @@
}
}
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, 1, 0,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
corelog ? 0U : 1U, lp->pvh, lp->alloc,
- MIRROR_BY_LV))
+ MIRROR_BY_LV, mirrored_log))
return_0;
if (lp->wait_completion)
lp->need_polling = 1;
@@ -513,12 +514,12 @@
*/
original_lv = _original_lv(lv);
if (!first_seg(original_lv)->log_lv && !corelog) {
- if (!add_mirror_log(cmd, original_lv, 1,
+ if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
- lp->pvh, lp->alloc))
+ lp->pvh, lp->alloc, lp->mirrors, 0, 0, mirrored_log))
return_0;
} else if (first_seg(original_lv)->log_lv && corelog) {
if (!remove_mirror_log(cmd, original_lv,
@@ -546,12 +547,12 @@
*/
original_lv = _original_lv(lv);
if (!first_seg(original_lv)->log_lv && !corelog) {
- if (!add_mirror_log(cmd, original_lv, 1,
+ if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
- lp->pvh, lp->alloc))
+ lp->pvh, lp->alloc, lp->mirrors, 0, 0, mirrored_log))
return_0;
} else if (first_seg(original_lv)->log_lv && corelog) {
if (!remove_mirror_log(cmd, original_lv,
@@ -565,13 +566,13 @@
return 0;
}
/* FIXME: can't have multiple mlogs. force corelog. */
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
+ if (!lv_add_mirrors(cmd, lv, NULL, lp->mirrors - existing_mirrors, 1, 0,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
0U, lp->pvh, lp->alloc,
- MIRROR_BY_LV))
+ MIRROR_BY_LV, lp->mirrors))
return_0;
lv->status |= CONVERTING;
lp->need_polling = 1;
diff -r d548a82e6195 tools/lvcreate.c
--- a/tools/lvcreate.c Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/lvcreate.c Mon Dec 29 15:54:33 2008 -0800
@@ -37,6 +37,7 @@
uint32_t region_size;
uint32_t mirrors;
+ uint32_t mirrored_log;
const struct segment_type *segtype;
@@ -320,6 +321,9 @@
}
lp->region_size = region_size;
}
+
+ if (arg_count(cmd, mirroredlog_ARG))
+ lp->mirrored_log = 1;
if (!_validate_mirror_params(cmd, lp))
return 0;
@@ -772,14 +776,15 @@
return_0;
if (lp->mirrors > 1) {
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, lp->stripes,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, lp->stripes, lp->stripe_size,
adjusted_mirror_region_size(
vg->extent_size,
lv->le_count,
lp->region_size),
lp->corelog ? 0U : 1U, pvh, lp->alloc,
MIRROR_BY_LV |
- (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0))) {
+ (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0),
+ lp->mirrored_log)) {
stack;
goto revert_new_lv;
}
diff -r d548a82e6195 tools/pvmove.c
--- a/tools/pvmove.c Mon Dec 29 15:36:50 2008 -0800
+++ b/tools/pvmove.c Mon Dec 29 15:54:33 2008 -0800
@@ -251,8 +251,8 @@
return NULL;
}
- if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, log_count,
- allocatable_pvs, alloc, MIRROR_BY_SEG)) {
+ if (!lv_add_mirrors(cmd, lv_mirr, NULL, 1u, 1u, 0u, 0u, log_count,
+ allocatable_pvs, alloc, MIRROR_BY_SEG, 0)) {
log_error("Failed to convert pvmove LV to mirrored");
return_NULL;
}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2008-12-30 0:10 ` malahal
(?)
@ 2009-01-19 22:56 ` Takahiro Yasui
2009-01-20 1:54 ` malahal
-1 siblings, 1 reply; 19+ messages in thread
From: Takahiro Yasui @ 2009-01-19 22:56 UTC (permalink / raw)
To: malahal; +Cc: dm-devel, agk
Hi,
I'm interested in the mirrored log approach which Malahal posted,
and now I'm looking into it. However, I found one problem with it.
When one of log disk is broken and is not recognized, there is a case
disk that replication is executed. Let me explain with the following
simple case, which is the mirror volume, vg00-lv00 is composed of two
data disks and one mirrored log which is composed of two log disks.
vg00-lv00 (253:5)
+vg00-lv00_mimage_1 (253:4)
+vg00-lv00_mimage_0 (253:3)
+vg00-lv00_mlog (253:2)
+vg00-lv00_mlog_mimage_1 (253:1)
+vg00-lv00_mlog_mimage_0 (253:0)
In this structure, if vg00-lv00_mlog_mimage_0 has problem and is not
accessed successfully, vg00-lv00_mlog is detected as a failed device
when vg00-lv00 is activated. The status of log device in vg00-lv00 is
displayed as "D". In addition, a whole data in vg00-lv00_mimage0 is
copied to vg00-lv00_mimage_1.
# vgchange -ay vg00 -P
Partial mode. Incomplete volume groups will be activated read-only.
Couldn't find device with uuid 'aLl1CE-69hT-Mghu-UvqX-aBpA-twhk-jXO5Ut'.
Couldn't find device with uuid 'aLl1CE-69hT-Mghu-UvqX-aBpA-twhk-jXO5Ut'.
Couldn't find device with uuid 'aLl1CE-69hT-Mghu-UvqX-aBpA-twhk-jXO5Ut'.
Couldn't find device with uuid 'aLl1CE-69hT-Mghu-UvqX-aBpA-twhk-jXO5Ut'.
1 logical volume(s) in volume group "vg00" now active
# dmsetup status
vg00-lv00_mimage_1: 0 24576 linear
vg00-lv00_mlog_mimage_1: 0 8192 linear
vg00-lv00_mimage_0: 0 24576 linear
vg00-lv00_mlog_mimage_0: 0 8192 linear
vg00-lv00_mlog_mimage_0-missing_0_0: 0 8192 error
vg00-lv00_mlog: 0 8192 mirror 2 253:1 253:2 0/8 1 DA 1 core
vg00-lv00: 0 24576 mirror 2 253:4 253:5 24/24 1 AA 3 disk 253:3 D
On the other hand, when vg00-lv00_mlog_mimage_0 is in a good condition
but vg00-lv00_mlog_mimage_1 has a issue, vg00-lv00_mlog is recognized
as an active device, and the status of log device in vg00-lv00 is
displayed as "A". This is an expected result.
# /sbin/dmsetup status
vg00-lv00_mimage_1: 0 24576 linear
vg00-lv00_mlog_mimage_1: 0 8192 linear
vg00-lv00_mimage_0: 0 24576 linear
vg00-lv00_mlog_mimage_0: 0 8192 linear
vg00-lv00_mlog: 0 8192 mirror 2 253:0 253:2 0/8 1 AD 1 core
vg00-lv00: 0 24576 mirror 2 253:4 253:5 24/24 1 AA 3 disk 253:3 A
vg00-lv00_mlog_mimage_1-missing_0_0: 0 8192 error
* Analysis of this problem
A mirrored log is a type of "core" log and log devices need to be
synchronized when a mirrored log is activated. But when the first log
device is not recognized, "READ" I/O returns -EIO in disk_resume()
because log disk is not in-sync status and a default log can not be
switched to the other log disk working well.
Avoiding disk replication even if a log device got trouble is one of
the requirements. Is there any solution to avoid this problem by the
mirrored log approach?
I appreciate any comments on this problem.
Thanks,
---
Takahiro Yasui
Hitachi Computer Products (America) Inc.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-01-19 22:56 ` Takahiro Yasui
@ 2009-01-20 1:54 ` malahal
2009-01-20 22:12 ` Takahiro Yasui
0 siblings, 1 reply; 19+ messages in thread
From: malahal @ 2009-01-20 1:54 UTC (permalink / raw)
To: Takahiro Yasui; +Cc: dm-devel, agk
Takahiro Yasui [tyasui@redhat.com] wrote:
> Hi,
>
> I'm interested in the mirrored log approach which Malahal posted,
> and now I'm looking into it. However, I found one problem with it.
>
> When one of log disk is broken and is not recognized, there is a case
> disk that replication is executed. Let me explain with the following
> simple case, which is the mirror volume, vg00-lv00 is composed of two
> data disks and one mirrored log which is composed of two log disks.
>
> * Analysis of this problem
>
> A mirrored log is a type of "core" log and log devices need to be
> synchronized when a mirrored log is activated. But when the first log
> device is not recognized, "READ" I/O returns -EIO in disk_resume()
> because log disk is not in-sync status and a default log can not be
> switched to the other log disk working well.
>
>
> Avoiding disk replication even if a log device got trouble is one of
> the requirements. Is there any solution to avoid this problem by the
> mirrored log approach?
Two ways to fix:
1) Never make "error leg" as your master leg as that is pointless.
2) Maybe we can use 'nosync' option when one of the two legs is known to
be an error device. This is probably easier than method (1)
Any other methods? Any help regarding which method to pursue would be
very much appreciated.
Thanks, Malahal.
PS: This patch was always used along with other patches and that could
explain why we didn't notice this problem.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2008-12-30 0:10 ` malahal
(?)
(?)
@ 2009-01-20 21:29 ` Takahiro Yasui
2009-01-20 22:14 ` malahal
-1 siblings, 1 reply; 19+ messages in thread
From: Takahiro Yasui @ 2009-01-20 21:29 UTC (permalink / raw)
To: malahal; +Cc: dm-devel
malahal@us.ibm.com wrote:
> This patch adds '--mirroredlog' option to LVM commands to create a
> mirror with mirrored log device. Rebased to the latest LVM code
> (LVM2.2.02.43). Appreciate any comments.
Hi, Malahal
This is the additional test results of mirrored log. Currently your
patch is proposed by "RFC", and these might be known issues to you,
but I hope this reports would be helpful to improve your patch.
Any comments are welcome.
0. Test environment
- LVM2.2.02.43 with mirrored log patch
- vg00 is composed of 8 PVs (/dev/sd[c-j])
1. SIGSEGV at converting a core log to a mirrored log
# dmsetup status
vg00-lv00_mimage_1: 0 24576 linear
vg00-lv00_mimage_0: 0 24576 linear
vg00-lv00: 0 24576 mirror 2 253:3 253:4 24/24 1 AA 1 core
# lvconvert -m1 --mirroredlog /dev/vg00/lv00
Segmentation fault
# lvconvert -m2 --mirroredlog /dev/vg00/lv00
Segmentation fault
2. Fail at conversion from 2 legs to 3 legs
lv00 in vg00 has 2 legs (2 log legs and 2 data legs), and when it is
converted to the structure with 3 lets, the conversion fails.
vg00-lv00 (253:5)
+ vg00-lv00_mimage_1 (253:4)
+ vg00-lv00_mimage_0 (253:3)
+ vg00-lv00_mlog (253:2)
+ vg00-lv00_mlog_mimage_1 (253:1)
+ vg00-lv00_mlog_mimage_0 (253:0)
# lvconvert -m2 --mirroredlog /dev/vg00/lv00
device-mapper: reload ioctl failed: No such device or address
Failed to lock lv00
# dmsetup status
vg00-lv00_mimage_2: 0 8192 linear <-- data leg is created
vg00-lv00_mimage_1: 0 24576 linear
vg00-lv00_mlog_mimage_1: 0 8192 linear
vg00-lv00_mimage_0: 0 24576 linear
vg00-lv00_mlog_mimage_0: 0 8192 linear
vg00-lv00_mimagetmp_2: 0 24576 error <-- temporary data log exists
vg00-lv00_mlog: 0 8192 mirror 2 253:1 253:2 8/8 1 AA 1 core
vg00-lv00: 0 24576 mirror 2 253:4 253:5 24/24 1 AA 3 disk 253:3 A
3. Fail at conversion from disk log to mirrored log
# dmsetup status
vg00-lv00_mimage_1: 0 24576 linear
vg00-lv00_mimage_0: 0 24576 linear
vg00-lv00_mlog: 0 8192 linear
vg00-lv00: 0 24576 mirror 2 253:1 253:2 24/24 1 AA 3 disk 253:0 A
# lvconvert -m1 --mirroredlog /dev/vg00/lv00
Logical volume lv00 already has 1 mirror(s).
=> disk log should be converted to mirrored log?
# lvconvert -m2 --mirroredlog /dev/vg00/lv00
device-mapper: reload ioctl failed: No such device or address
Failed to lock lv00
# dmsetup status
vg00-lv00_mimage_2: 0 8192 linear
vg00-lv00_mimage_1: 0 24576 linear
vg00-lv00_mimage_0: 0 24576 linear
vg00-lv00_mimagetmp_2: 0 24576 error
vg00-lv00_mlog: 0 8192 linear
vg00-lv00: 0 24576 mirror 2 253:1 253:2 24/24 1 AA 3 disk 253:0 A
=> disk log should be converted to mirrored log with 3 legs?
Thanks,
---
Takahiro Yasui
Hitachi Computer Products (America), Inc.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-01-20 1:54 ` malahal
@ 2009-01-20 22:12 ` Takahiro Yasui
0 siblings, 0 replies; 19+ messages in thread
From: Takahiro Yasui @ 2009-01-20 22:12 UTC (permalink / raw)
To: malahal; +Cc: dm-devel, agk
malahal@us.ibm.com wrote:
> Takahiro Yasui [tyasui@redhat.com] wrote:
> ...
>> When one of log disk is broken and is not recognized, there is a case
>> disk that replication is executed. Let me explain with the following
>> simple case, which is the mirror volume, vg00-lv00 is composed of two
>> data disks and one mirrored log which is composed of two log disks.
>>
>> * Analysis of this problem
>>
>> A mirrored log is a type of "core" log and log devices need to be
>> synchronized when a mirrored log is activated. But when the first log
>> device is not recognized, "READ" I/O returns -EIO in disk_resume()
>> because log disk is not in-sync status and a default log can not be
>> switched to the other log disk working well.
>>
>>
>> Avoiding disk replication even if a log device got trouble is one of
>> the requirements. Is there any solution to avoid this problem by the
>> mirrored log approach?
>
> Two ways to fix:
> 1) Never make "error leg" as your master leg as that is pointless.
This approach will solve the case that a log leg is not recognized, but
I'm afraid that it won't solve other type of I/O errors, such as medium
error.
LVM commands such as vgchange accesses only sectors containing label and
metadata, and LVM commands will successfully activate mirrored log as a
userland process. However, in kernel, I/Os errors might be detected in
a log area, and "READ" I/O returns -EIO. In this case, log will be detected
as a failed device.
> 2) Maybe we can use 'nosync' option when one of the two legs is known to
> be an error device. This is probably easier than method (1)
This approach looks good.
Thanks,
---
Takahiro Yasui
Hitachi Computer Products (America), Inc.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-01-20 21:29 ` Takahiro Yasui
@ 2009-01-20 22:14 ` malahal
0 siblings, 0 replies; 19+ messages in thread
From: malahal @ 2009-01-20 22:14 UTC (permalink / raw)
To: Takahiro Yasui; +Cc: dm-devel
Thank you Takahiro for your comments. They all need to be fixed! I also
found that 'lvremove' doesn't remove the device mapper tables for the
"log mirror".
--Malahal.
Takahiro Yasui [tyasui@redhat.com] wrote:
> malahal@us.ibm.com wrote:
> > This patch adds '--mirroredlog' option to LVM commands to create a
> > mirror with mirrored log device. Rebased to the latest LVM code
> > (LVM2.2.02.43). Appreciate any comments.
>
> Hi, Malahal
>
> This is the additional test results of mirrored log. Currently your
> patch is proposed by "RFC", and these might be known issues to you,
> but I hope this reports would be helpful to improve your patch.
> Any comments are welcome.
>
>
> 0. Test environment
> - LVM2.2.02.43 with mirrored log patch
> - vg00 is composed of 8 PVs (/dev/sd[c-j])
>
>
> 1. SIGSEGV at converting a core log to a mirrored log
>
> # dmsetup status
> vg00-lv00_mimage_1: 0 24576 linear
> vg00-lv00_mimage_0: 0 24576 linear
> vg00-lv00: 0 24576 mirror 2 253:3 253:4 24/24 1 AA 1 core
>
> # lvconvert -m1 --mirroredlog /dev/vg00/lv00
> Segmentation fault
>
> # lvconvert -m2 --mirroredlog /dev/vg00/lv00
> Segmentation fault
>
>
> 2. Fail at conversion from 2 legs to 3 legs
>
> lv00 in vg00 has 2 legs (2 log legs and 2 data legs), and when it is
> converted to the structure with 3 lets, the conversion fails.
>
> vg00-lv00 (253:5)
> + vg00-lv00_mimage_1 (253:4)
> + vg00-lv00_mimage_0 (253:3)
> + vg00-lv00_mlog (253:2)
> + vg00-lv00_mlog_mimage_1 (253:1)
> + vg00-lv00_mlog_mimage_0 (253:0)
>
> # lvconvert -m2 --mirroredlog /dev/vg00/lv00
> device-mapper: reload ioctl failed: No such device or address
> Failed to lock lv00
> # dmsetup status
> vg00-lv00_mimage_2: 0 8192 linear <-- data leg is created
> vg00-lv00_mimage_1: 0 24576 linear
> vg00-lv00_mlog_mimage_1: 0 8192 linear
> vg00-lv00_mimage_0: 0 24576 linear
> vg00-lv00_mlog_mimage_0: 0 8192 linear
> vg00-lv00_mimagetmp_2: 0 24576 error <-- temporary data log exists
> vg00-lv00_mlog: 0 8192 mirror 2 253:1 253:2 8/8 1 AA 1 core
> vg00-lv00: 0 24576 mirror 2 253:4 253:5 24/24 1 AA 3 disk 253:3 A
>
>
> 3. Fail at conversion from disk log to mirrored log
>
> # dmsetup status
> vg00-lv00_mimage_1: 0 24576 linear
> vg00-lv00_mimage_0: 0 24576 linear
> vg00-lv00_mlog: 0 8192 linear
> vg00-lv00: 0 24576 mirror 2 253:1 253:2 24/24 1 AA 3 disk 253:0 A
>
> # lvconvert -m1 --mirroredlog /dev/vg00/lv00
> Logical volume lv00 already has 1 mirror(s).
>
> => disk log should be converted to mirrored log?
>
> # lvconvert -m2 --mirroredlog /dev/vg00/lv00
> device-mapper: reload ioctl failed: No such device or address
> Failed to lock lv00
> # dmsetup status
> vg00-lv00_mimage_2: 0 8192 linear
> vg00-lv00_mimage_1: 0 24576 linear
> vg00-lv00_mimage_0: 0 24576 linear
> vg00-lv00_mimagetmp_2: 0 24576 error
> vg00-lv00_mlog: 0 8192 linear
> vg00-lv00: 0 24576 mirror 2 253:1 253:2 24/24 1 AA 3 disk 253:0 A
>
> => disk log should be converted to mirrored log with 3 legs?
>
>
> Thanks,
> ---
> Takahiro Yasui
> Hitachi Computer Products (America), Inc.
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2008-12-30 0:10 ` malahal
` (2 preceding siblings ...)
(?)
@ 2009-01-23 19:14 ` Jonathan Brassow
-1 siblings, 0 replies; 19+ messages in thread
From: Jonathan Brassow @ 2009-01-23 19:14 UTC (permalink / raw)
To: device-mapper development
[-- Attachment #1.1: Type: text/plain, Size: 997 bytes --]
Be careful not to waste your time on some thing that will not be
included....
I see the order of events like this:
1) Generic layering of LVs
2) Improved mirror DSO
3) Mirrored log implementation
Note that once you get #1 done you /should/ be able to get a mirrored
log by:
prompt> lvcreate -m1 --mirrorlog core -l 1 -n mirrored_log vg
prompt> lvcreate -m1 -L 5G -n mirror vg /dev/sdb /dev/sdc /dev/vg/
mirrored_log
Leapfrogging #2 /might/ be acceptable, but leapfrogging #1 is not.
This is because you are creating a one-off solution rather than
creating something more general that would benefit LVM as a whole.
Feel free to disagree, but I really see the above as the way forward.
brassow
On Dec 29, 2008, at 6:10 PM, malahal@us.ibm.com wrote:
> This patch adds '--mirroredlog' option to LVM commands to create a
> mirror with mirrored log device. Rebased to the latest LVM code
> (LVM2.2.02.43). Appreciate any comments.
>
> Signed-off-by: Stefan Raspl <raspl@de.ibm.com>
[-- Attachment #1.2: Type: text/html, Size: 2053 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread
* [RFC] [PATCH] lvm2: mirroredlog support
@ 2009-09-23 3:03 malahal
2009-09-23 20:29 ` Jonathan Brassow
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: malahal @ 2009-09-23 3:03 UTC (permalink / raw)
To: dm-devel
This patch adds '--mirroredlog' option to LVM commands to create a
mirror with mirrored log device. Rebased to the latest LVM code
(LVM2.2.02.51). Have not done 'lvconvert' related changes yet!
Appreciate any comments.
diff -r c70315774a35 lib/activate/activate.c
--- a/lib/activate/activate.c Tue Sep 15 12:08:46 2009 -0700
+++ b/lib/activate/activate.c Tue Sep 22 19:51:15 2009 -0700
@@ -979,6 +979,8 @@
{
struct logical_volume *lv;
struct lvinfo info;
+ struct lv_segment *seg, *log_seg;
+ struct segment_type *type = get_segtype_from_string(cmd, "mirror");
int r = 0;
if (!activation())
@@ -1012,6 +1014,20 @@
if (!monitor_dev_for_events(cmd, lv, 0))
stack;
+ if ( !dm_list_empty(&lv->segments) ) {
+ seg = dm_list_item(dm_list_first(&lv->segments), struct lv_segment);
+ if (seg->log_lv) {
+ log_very_verbose("lv %s is mirrored, check it's log %s...", lv->name, seg->log_lv->name);
+ if ( !dm_list_empty(&seg->log_lv->segments) ) {
+ log_seg = dm_list_item(dm_list_first(&seg->log_lv->segments), struct lv_segment);
+ if (log_seg->segtype == type) {
+ log_verbose("log %s is mirrored, unregister for events", log_seg->lv->name);
+ monitor_dev_for_events(cmd, log_seg->lv, 0);
+ }
+ }
+ }
+ }
+
memlock_inc();
r = _lv_deactivate(lv);
memlock_dec();
diff -r c70315774a35 lib/metadata/lv_manip.c
--- a/lib/metadata/lv_manip.c Tue Sep 15 12:08:46 2009 -0700
+++ b/lib/metadata/lv_manip.c Tue Sep 22 19:51:15 2009 -0700
@@ -3029,14 +3029,16 @@
return_0;
if (lp->mirrors > 1) {
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, lp->stripes,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1,
+ lp->stripes, lp->stripe_size,
adjusted_mirror_region_size(
vg->extent_size,
lv->le_count,
lp->region_size),
lp->corelog ? 0U : 1U, lp->pvh, lp->alloc,
MIRROR_BY_LV |
- (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0))) {
+ (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0),
+ lp->mirrored_log)) {
stack;
goto revert_new_lv;
}
diff -r c70315774a35 lib/metadata/metadata-exported.h
--- a/lib/metadata/metadata-exported.h Tue Sep 15 12:08:46 2009 -0700
+++ b/lib/metadata/metadata-exported.h Tue Sep 22 19:51:15 2009 -0700
@@ -528,6 +528,7 @@
uint32_t region_size; /* mirror */
uint32_t mirrors; /* mirror */
+ uint32_t mirrored_log; /* mirror */
const struct segment_type *segtype; /* all */
@@ -637,9 +638,11 @@
*/
struct lv_segment *find_mirror_seg(struct lv_segment *seg);
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes,
+ const struct segment_type *segtype,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
uint32_t region_size, uint32_t log_count,
- struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
+ struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
+ uint32_t mirrored_log);
int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
uint32_t mirrors, uint32_t log_count,
struct dm_list *pvs, uint32_t status_mask);
@@ -658,16 +661,21 @@
int remove_mirror_images(struct logical_volume *lv, uint32_t num_mirrors,
struct dm_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,
+ const struct segment_type *segtype,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
- uint32_t log_count);
+ uint32_t log_count, uint32_t mirrored_log);
struct logical_volume *detach_mirror_log(struct lv_segment *seg);
int attach_mirror_log(struct lv_segment *seg, struct logical_volume *lv);
int remove_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
struct dm_list *removable_pvs);
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ const struct segment_type *segtype,
uint32_t log_count, uint32_t region_size,
- struct dm_list *allocatable_pvs, alloc_policy_t alloc);
+ struct dm_list *allocatable_pvs, alloc_policy_t alloc,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrored_log);
int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
struct dm_list *removable_pvs, unsigned remove_log);
diff -r c70315774a35 lib/metadata/mirror.c
--- a/lib/metadata/mirror.c Tue Sep 15 12:08:46 2009 -0700
+++ b/lib/metadata/mirror.c Tue Sep 22 19:51:15 2009 -0700
@@ -1248,7 +1248,8 @@
struct alloc_handle *ah,
alloc_policy_t alloc,
const char *lv_name,
- const char *suffix)
+ const char *suffix,
+ uint32_t mirrored_log)
{
struct logical_volume *log_lv;
char *log_name;
@@ -1270,7 +1271,7 @@
alloc, lv->vg)))
return_NULL;
- if (!lv_add_log_segment(ah, log_lv))
+ if (!mirrored_log && !lv_add_log_segment(ah, log_lv))
return_NULL;
return log_lv;
@@ -1279,10 +1280,16 @@
static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
struct alloc_handle *ah,
struct logical_volume *lv,
+ const struct segment_type *segtype,
uint32_t log_count,
- uint32_t region_size __attribute((unused)),
+ uint32_t region_size,
alloc_policy_t alloc,
- int in_sync)
+ int in_sync,
+ uint32_t mirrors,
+ uint32_t stripes,
+ uint32_t stripe_size,
+ struct dm_list *allocatable_pvs,
+ uint32_t mirrored_log)
{
struct logical_volume *log_lv;
const char *suffix, *c;
@@ -1324,11 +1331,20 @@
}
if (!(log_lv = _create_mirror_log(lv, ah, alloc,
- (const char *) lv_name, suffix))) {
+ (const char *) lv_name, suffix, mirrored_log))) {
log_error("Failed to create mirror log.");
return NULL;
}
+ if (mirrored_log) {
+ if (!lv_extend(log_lv, segtype, stripes, stripe_size,
+ 1u, 1u, NULL, 0u, 0u, allocatable_pvs, alloc))
+ return NULL;
+
+ add_mirror_images(cmd, log_lv, segtype, mirrors, stripes, stripe_size,
+ region_size, allocatable_pvs, alloc, 0, 0);
+ }
+
if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
log_error("Failed to create mirror log.");
return NULL;
@@ -1346,8 +1362,11 @@
}
int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
+ const struct segment_type *seg_type,
uint32_t log_count, uint32_t region_size,
- struct dm_list *allocatable_pvs, alloc_policy_t alloc)
+ struct dm_list *allocatable_pvs, alloc_policy_t alloc,
+ uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
+ uint32_t mirrored_log)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1410,8 +1429,10 @@
else
in_sync = 0;
- if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
- region_size, alloc, in_sync)))
+ if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count,
+ region_size, alloc, in_sync,
+ mirrors, stripes, stripe_size, allocatable_pvs,
+ mirrored_log)))
goto_out;
if (!attach_mirror_log(first_seg(lv), log_lv))
@@ -1427,9 +1448,10 @@
* Convert "linear" LV to "mirror".
*/
int add_mirror_images(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes, uint32_t region_size,
+ const struct segment_type *seg_type, uint32_t mirrors,
+ uint32_t stripes, uint32_t stripe_size, uint32_t region_size,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
- uint32_t log_count)
+ uint32_t log_count, uint32_t mirrored_log)
{
struct alloc_handle *ah;
const struct segment_type *segtype;
@@ -1452,9 +1474,18 @@
if (!(segtype = get_segtype_from_string(cmd, "mirror")))
return_0;
- ah = allocate_extents(lv->vg, NULL, segtype,
- stripes, mirrors, log_count, region_size, lv->le_count,
- allocatable_pvs, alloc, parallel_areas);
+ if (mirrored_log)
+ /* Allocate mirror extents for the log */
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, 0,
+ region_size, 1,
+ allocatable_pvs, alloc, parallel_areas);
+ else
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, log_count,
+ region_size, lv->le_count,
+ allocatable_pvs, alloc, parallel_areas);
+
if (!ah) {
log_error("Unable to allocate extents for mirror(s).");
return 0;
@@ -1463,11 +1494,25 @@
/*
* create and initialize mirror log
*/
- if (log_count &&
- !(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count, region_size,
- alloc, mirror_in_sync()))) {
- stack;
- goto out_remove_images;
+ if (log_count) {
+ if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count, region_size,
+ alloc, mirror_in_sync(), mirrors, stripes,
+ stripe_size, allocatable_pvs, mirrored_log))) {
+ stack;
+ goto out_remove_images;
+ }
+ if (mirrored_log) {
+ /* Allocate extents for the mirror legs */
+ alloc_destroy(ah);
+ ah = allocate_extents(lv->vg, NULL, segtype,
+ stripes, mirrors, 0,
+ region_size, lv->le_count,
+ allocatable_pvs, alloc, parallel_areas);
+ if (!ah) {
+ stack;
+ goto out_remove_images;
+ }
+ }
}
/* The log initialization involves vg metadata commit.
@@ -1529,9 +1574,11 @@
* 'pvs' is either allocatable pvs.
*/
int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
- uint32_t mirrors, uint32_t stripes,
+ const struct segment_type *seg_type, uint32_t mirrors,
+ uint32_t stripes, uint32_t stripe_size,
uint32_t region_size, uint32_t log_count,
- struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags)
+ struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
+ uint32_t mirrored_log)
{
if (!mirrors && !log_count) {
log_error("No conversion is requested");
@@ -1564,11 +1611,13 @@
region_size, pvs, alloc);
} else if (flags & MIRROR_BY_LV) {
if (!mirrors)
- return add_mirror_log(cmd, lv, log_count,
- region_size, pvs, alloc);
- return add_mirror_images(cmd, lv, mirrors,
- stripes, region_size,
- pvs, alloc, log_count);
+ return add_mirror_log(cmd, lv, seg_type, log_count,
+ region_size, pvs, alloc, mirrors,
+ stripes, stripe_size, mirrored_log);
+ return add_mirror_images(cmd, lv, seg_type, mirrors,
+ stripes, stripe_size, region_size,
+ pvs, alloc, log_count,
+ mirrored_log);
}
log_error("Unsupported mirror conversion type");
diff -r c70315774a35 tools/args.h
--- a/tools/args.h Tue Sep 15 12:08:46 2009 -0700
+++ b/tools/args.h Tue Sep 22 19:51:15 2009 -0700
@@ -45,6 +45,7 @@
arg(alloc_ARG, '\0', "alloc", alloc_arg, 0)
arg(separator_ARG, '\0', "separator", string_arg, 0)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0)
+arg(mirroredlog_ARG, '\0', "mirroredlog", NULL, 0)
arg(nosync_ARG, '\0', "nosync", NULL, 0)
arg(resync_ARG, '\0', "resync", NULL, 0)
arg(corelog_ARG, '\0', "corelog", NULL, 0)
diff -r c70315774a35 tools/commands.h
--- a/tools/commands.h Tue Sep 15 12:08:46 2009 -0700
+++ b/tools/commands.h Tue Sep 22 19:51:15 2009 -0700
@@ -95,8 +95,7 @@
"Change logical volume layout",
0,
"lvconvert "
- "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
- "\t[--repair [--use-policies]]\n"
+ "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog|--mirroredlog}]]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
@@ -122,7 +121,7 @@
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
- mirrorlog_ARG, mirrors_ARG, noudevsync_ARG, regionsize_ARG, repair_ARG,
+ mirrorlog_ARG, mirrors_ARG, noudevsync_ARG, regionsize_ARG, repair_ARG, mirroredlog_ARG,
snapshot_ARG, test_ARG, use_policies_ARG, yes_ARG, force_ARG, zero_ARG)
xx(lvcreate,
@@ -139,7 +138,7 @@
"\t{-l|--extents LogicalExtentsNumber |\n"
"\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
"\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
- "\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--corelog}]]\n"
+ "\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--corelog|--mirroredlog}]]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[--noudevsync]\n"
"\t[-p|--permission {r|rw}]\n"
@@ -173,9 +172,9 @@
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
"\t[--version]\n"
+ "\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
- "\t[PhysicalVolumePath...]\n\n",
-
+ mirroredlog_ARG,
addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG, contiguous_ARG,
corelog_ARG, extents_ARG, major_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG,
name_ARG, nosync_ARG, noudevsync_ARG, permission_ARG, persistent_ARG,
diff -r c70315774a35 tools/lvconvert.c
--- a/tools/lvconvert.c Tue Sep 15 12:08:46 2009 -0700
+++ b/tools/lvconvert.c Tue Sep 22 19:51:15 2009 -0700
@@ -31,6 +31,7 @@
uint32_t region_size;
uint32_t mirrors;
+ uint32_t mirrored_log;
sign_t mirrors_sign;
struct segment_type *segtype;
@@ -507,13 +508,16 @@
int corelog)
{
struct logical_volume *original_lv = _original_lv(lv);
+
if (_using_corelog(lv) && !corelog) {
- if (!add_mirror_log(cmd, original_lv, 1,
+ if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
- lp->pvh, lp->alloc))
+ lp->pvh, lp->alloc,
+ lp->mirrors, 0, 0,
+ lp->mirrored_log))
return_0;
} else if (!_using_corelog(lv) && corelog) {
if (!remove_mirror_log(cmd, original_lv,
@@ -538,6 +542,8 @@
int repair = arg_count(cmd, repair_ARG);
int replace_log = 1, replace_mirrors = 1;
+ lp->mirrored_log = arg_count(cmd, mirroredlog_ARG);
+
seg = first_seg(lv);
existing_mirrors = lv_mirror_count(lv);
@@ -696,13 +702,13 @@
* currently taken by the mirror? Would make more sense from
* user perspective.
*/
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, 1, 0,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
corelog ? 0U : 1U, lp->pvh, lp->alloc,
- MIRROR_BY_LV))
+ MIRROR_BY_LV, lp->mirrored_log))
return_0;
if (lp->wait_completion)
lp->need_polling = 1;
@@ -726,13 +732,13 @@
return 0;
}
/* FIXME: can't have multiple mlogs. force corelog. */
- if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
+ if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - existing_mirrors, 1, 0,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
0U, lp->pvh, lp->alloc,
- MIRROR_BY_LV))
+ MIRROR_BY_LV, lp->mirrored_log))
return_0;
lv->status |= CONVERTING;
lp->need_polling = 1;
@@ -743,6 +749,7 @@
if (!_lv_update_log_type(cmd, lp, lv, corelog))
return_0;
} else {
+ /*malahal this needs rework...*/
log_error("Logical volume %s already has %"
PRIu32 " mirror(s).", lv->name,
lp->mirrors - 1);
diff -r c70315774a35 tools/lvcreate.c
--- a/tools/lvcreate.c Tue Sep 15 12:08:46 2009 -0700
+++ b/tools/lvcreate.c Tue Sep 22 19:51:15 2009 -0700
@@ -367,6 +367,9 @@
lp->region_size = region_size;
}
+ if (arg_count(cmd, mirroredlog_ARG))
+ lp->mirrored_log = 1;
+
if (!_validate_mirror_params(cmd, lp))
return 0;
diff -r c70315774a35 tools/pvmove.c
--- a/tools/pvmove.c Tue Sep 15 12:08:46 2009 -0700
+++ b/tools/pvmove.c Tue Sep 22 19:51:15 2009 -0700
@@ -244,8 +244,8 @@
return NULL;
}
- if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, log_count,
- allocatable_pvs, alloc, MIRROR_BY_SEG)) {
+ if (!lv_add_mirrors(cmd, lv_mirr, NULL, 1u, 1u, 0u, 0u, log_count,
+ allocatable_pvs, alloc, MIRROR_BY_SEG, 0)) {
log_error("Failed to convert pvmove LV to mirrored");
return_NULL;
}
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-23 3:03 [RFC] [PATCH] lvm2: mirroredlog support malahal
@ 2009-09-23 20:29 ` Jonathan Brassow
2009-09-23 20:44 ` malahal
2009-09-24 5:22 ` Takahiro Yasui
2009-09-30 15:50 ` Jonathan Brassow
2 siblings, 1 reply; 19+ messages in thread
From: Jonathan Brassow @ 2009-09-23 20:29 UTC (permalink / raw)
To: device-mapper development
It would be nice if we didn't have to use '--mirroredlog' (a new
option), but instead '--mirrorlog mirrored' (continuing use of the
preferred option).
I will be continuing to review this.
brassow
On Sep 22, 2009, at 10:03 PM, malahal@us.ibm.com wrote:
> This patch adds '--mirroredlog' option to LVM commands to create a
> mirror with mirrored log device. Rebased to the latest LVM code
> (LVM2.2.02.51). Have not done 'lvconvert' related changes yet!
> Appreciate any comments.
>
> diff -r c70315774a35 lib/activate/activate.c
> --- a/lib/activate/activate.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/activate/activate.c Tue Sep 22 19:51:15 2009 -0700
> @@ -979,6 +979,8 @@
> {
> struct logical_volume *lv;
> struct lvinfo info;
> + struct lv_segment *seg, *log_seg;
> + struct segment_type *type = get_segtype_from_string(cmd, "mirror");
> int r = 0;
>
> if (!activation())
> @@ -1012,6 +1014,20 @@
> if (!monitor_dev_for_events(cmd, lv, 0))
> stack;
>
> + if ( !dm_list_empty(&lv->segments) ) {
> + seg = dm_list_item(dm_list_first(&lv->segments), struct
> lv_segment);
> + if (seg->log_lv) {
> + log_very_verbose("lv %s is mirrored, check it's log %s...", lv-
> >name, seg->log_lv->name);
> + if ( !dm_list_empty(&seg->log_lv->segments) ) {
> + log_seg = dm_list_item(dm_list_first(&seg->log_lv->segments),
> struct lv_segment);
> + if (log_seg->segtype == type) {
> + log_verbose("log %s is mirrored, unregister for events",
> log_seg->lv->name);
> + monitor_dev_for_events(cmd, log_seg->lv, 0);
> + }
> + }
> + }
> + }
> +
> memlock_inc();
> r = _lv_deactivate(lv);
> memlock_dec();
> diff -r c70315774a35 lib/metadata/lv_manip.c
> --- a/lib/metadata/lv_manip.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/metadata/lv_manip.c Tue Sep 22 19:51:15 2009 -0700
> @@ -3029,14 +3029,16 @@
> return_0;
>
> if (lp->mirrors > 1) {
> - if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, lp->stripes,
> + if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1,
> + lp->stripes, lp->stripe_size,
> adjusted_mirror_region_size(
> vg->extent_size,
> lv->le_count,
> lp->region_size),
> lp->corelog ? 0U : 1U, lp->pvh, lp->alloc,
> MIRROR_BY_LV |
> - (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0))) {
> + (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0),
> + lp->mirrored_log)) {
> stack;
> goto revert_new_lv;
> }
> diff -r c70315774a35 lib/metadata/metadata-exported.h
> --- a/lib/metadata/metadata-exported.h Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/metadata/metadata-exported.h Tue Sep 22 19:51:15 2009 -0700
> @@ -528,6 +528,7 @@
> uint32_t region_size; /* mirror */
>
> uint32_t mirrors; /* mirror */
> + uint32_t mirrored_log; /* mirror */
>
> const struct segment_type *segtype; /* all */
>
> @@ -637,9 +638,11 @@
> */
> struct lv_segment *find_mirror_seg(struct lv_segment *seg);
> int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
> - uint32_t mirrors, uint32_t stripes,
> + const struct segment_type *segtype,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> uint32_t region_size, uint32_t log_count,
> - struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
> + struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
> + uint32_t mirrored_log);
> int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume
> *lv,
> uint32_t mirrors, uint32_t log_count,
> struct dm_list *pvs, uint32_t status_mask);
> @@ -658,16 +661,21 @@
> int remove_mirror_images(struct logical_volume *lv, uint32_t
> num_mirrors,
> struct dm_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,
> + const struct segment_type *segtype,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> + uint32_t region_size,
> struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> - uint32_t log_count);
> + uint32_t log_count, uint32_t mirrored_log);
> struct logical_volume *detach_mirror_log(struct lv_segment *seg);
> int attach_mirror_log(struct lv_segment *seg, struct logical_volume
> *lv);
> int remove_mirror_log(struct cmd_context *cmd, struct logical_volume
> *lv,
> struct dm_list *removable_pvs);
> int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
> + const struct segment_type *segtype,
> uint32_t log_count, uint32_t region_size,
> - struct dm_list *allocatable_pvs, alloc_policy_t alloc);
> + struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> + uint32_t mirrored_log);
>
> int reconfigure_mirror_images(struct lv_segment *mirrored_seg,
> uint32_t num_mirrors,
> struct dm_list *removable_pvs, unsigned remove_log);
> diff -r c70315774a35 lib/metadata/mirror.c
> --- a/lib/metadata/mirror.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/metadata/mirror.c Tue Sep 22 19:51:15 2009 -0700
> @@ -1248,7 +1248,8 @@
> struct alloc_handle *ah,
> alloc_policy_t alloc,
> const char *lv_name,
> - const char *suffix)
> + const char *suffix,
> + uint32_t mirrored_log)
> {
> struct logical_volume *log_lv;
> char *log_name;
> @@ -1270,7 +1271,7 @@
> alloc, lv->vg)))
> return_NULL;
>
> - if (!lv_add_log_segment(ah, log_lv))
> + if (!mirrored_log && !lv_add_log_segment(ah, log_lv))
> return_NULL;
>
> return log_lv;
> @@ -1279,10 +1280,16 @@
> static struct logical_volume *_set_up_mirror_log(struct cmd_context
> *cmd,
> struct alloc_handle *ah,
> struct logical_volume *lv,
> + const struct segment_type *segtype,
> uint32_t log_count,
> - uint32_t region_size __attribute((unused)),
> + uint32_t region_size,
> alloc_policy_t alloc,
> - int in_sync)
> + int in_sync,
> + uint32_t mirrors,
> + uint32_t stripes,
> + uint32_t stripe_size,
> + struct dm_list *allocatable_pvs,
> + uint32_t mirrored_log)
> {
> struct logical_volume *log_lv;
> const char *suffix, *c;
> @@ -1324,11 +1331,20 @@
> }
>
> if (!(log_lv = _create_mirror_log(lv, ah, alloc,
> - (const char *) lv_name, suffix))) {
> + (const char *) lv_name, suffix, mirrored_log))) {
> log_error("Failed to create mirror log.");
> return NULL;
> }
>
> + if (mirrored_log) {
> + if (!lv_extend(log_lv, segtype, stripes, stripe_size,
> + 1u, 1u, NULL, 0u, 0u, allocatable_pvs, alloc))
> + return NULL;
> +
> + add_mirror_images(cmd, log_lv, segtype, mirrors, stripes,
> stripe_size,
> + region_size, allocatable_pvs, alloc, 0, 0);
> + }
> +
> if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
> log_error("Failed to create mirror log.");
> return NULL;
> @@ -1346,8 +1362,11 @@
> }
>
> int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
> + const struct segment_type *seg_type,
> uint32_t log_count, uint32_t region_size,
> - struct dm_list *allocatable_pvs, alloc_policy_t alloc)
> + struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> + uint32_t mirrored_log)
> {
> struct alloc_handle *ah;
> const struct segment_type *segtype;
> @@ -1410,8 +1429,10 @@
> else
> in_sync = 0;
>
> - if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
> - region_size, alloc, in_sync)))
> + if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count,
> + region_size, alloc, in_sync,
> + mirrors, stripes, stripe_size, allocatable_pvs,
> + mirrored_log)))
> goto_out;
>
> if (!attach_mirror_log(first_seg(lv), log_lv))
> @@ -1427,9 +1448,10 @@
> * Convert "linear" LV to "mirror".
> */
> int add_mirror_images(struct cmd_context *cmd, struct logical_volume
> *lv,
> - uint32_t mirrors, uint32_t stripes, uint32_t region_size,
> + const struct segment_type *seg_type, uint32_t mirrors,
> + uint32_t stripes, uint32_t stripe_size, uint32_t region_size,
> struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> - uint32_t log_count)
> + uint32_t log_count, uint32_t mirrored_log)
> {
> struct alloc_handle *ah;
> const struct segment_type *segtype;
> @@ -1452,9 +1474,18 @@
> if (!(segtype = get_segtype_from_string(cmd, "mirror")))
> return_0;
>
> - ah = allocate_extents(lv->vg, NULL, segtype,
> - stripes, mirrors, log_count, region_size, lv->le_count,
> - allocatable_pvs, alloc, parallel_areas);
> + if (mirrored_log)
> + /* Allocate mirror extents for the log */
> + ah = allocate_extents(lv->vg, NULL, segtype,
> + stripes, mirrors, 0,
> + region_size, 1,
> + allocatable_pvs, alloc, parallel_areas);
> + else
> + ah = allocate_extents(lv->vg, NULL, segtype,
> + stripes, mirrors, log_count,
> + region_size, lv->le_count,
> + allocatable_pvs, alloc, parallel_areas);
> +
> if (!ah) {
> log_error("Unable to allocate extents for mirror(s).");
> return 0;
> @@ -1463,11 +1494,25 @@
> /*
> * create and initialize mirror log
> */
> - if (log_count &&
> - !(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
> region_size,
> - alloc, mirror_in_sync()))) {
> - stack;
> - goto out_remove_images;
> + if (log_count) {
> + if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type,
> log_count, region_size,
> + alloc, mirror_in_sync(), mirrors, stripes,
> + stripe_size, allocatable_pvs, mirrored_log))) {
> + stack;
> + goto out_remove_images;
> + }
> + if (mirrored_log) {
> + /* Allocate extents for the mirror legs */
> + alloc_destroy(ah);
> + ah = allocate_extents(lv->vg, NULL, segtype,
> + stripes, mirrors, 0,
> + region_size, lv->le_count,
> + allocatable_pvs, alloc, parallel_areas);
> + if (!ah) {
> + stack;
> + goto out_remove_images;
> + }
> + }
> }
>
> /* The log initialization involves vg metadata commit.
> @@ -1529,9 +1574,11 @@
> * 'pvs' is either allocatable pvs.
> */
> int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
> - uint32_t mirrors, uint32_t stripes,
> + const struct segment_type *seg_type, uint32_t mirrors,
> + uint32_t stripes, uint32_t stripe_size,
> uint32_t region_size, uint32_t log_count,
> - struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags)
> + struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
> + uint32_t mirrored_log)
> {
> if (!mirrors && !log_count) {
> log_error("No conversion is requested");
> @@ -1564,11 +1611,13 @@
> region_size, pvs, alloc);
> } else if (flags & MIRROR_BY_LV) {
> if (!mirrors)
> - return add_mirror_log(cmd, lv, log_count,
> - region_size, pvs, alloc);
> - return add_mirror_images(cmd, lv, mirrors,
> - stripes, region_size,
> - pvs, alloc, log_count);
> + return add_mirror_log(cmd, lv, seg_type, log_count,
> + region_size, pvs, alloc, mirrors,
> + stripes, stripe_size, mirrored_log);
> + return add_mirror_images(cmd, lv, seg_type, mirrors,
> + stripes, stripe_size, region_size,
> + pvs, alloc, log_count,
> + mirrored_log);
> }
>
> log_error("Unsupported mirror conversion type");
> diff -r c70315774a35 tools/args.h
> --- a/tools/args.h Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/args.h Tue Sep 22 19:51:15 2009 -0700
> @@ -45,6 +45,7 @@
> arg(alloc_ARG, '\0', "alloc", alloc_arg, 0)
> arg(separator_ARG, '\0', "separator", string_arg, 0)
> arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0)
> +arg(mirroredlog_ARG, '\0', "mirroredlog", NULL, 0)
> arg(nosync_ARG, '\0', "nosync", NULL, 0)
> arg(resync_ARG, '\0', "resync", NULL, 0)
> arg(corelog_ARG, '\0', "corelog", NULL, 0)
> diff -r c70315774a35 tools/commands.h
> --- a/tools/commands.h Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/commands.h Tue Sep 22 19:51:15 2009 -0700
> @@ -95,8 +95,7 @@
> "Change logical volume layout",
> 0,
> "lvconvert "
> - "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
> - "\t[--repair [--use-policies]]\n"
> + "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog|--
> mirroredlog}]]\n"
> "\t[-R|--regionsize MirrorLogRegionSize]\n"
> "\t[--alloc AllocationPolicy]\n"
> "\t[-b|--background]\n"
> @@ -122,7 +121,7 @@
> "\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
>
> alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG,
> interval_ARG,
> - mirrorlog_ARG, mirrors_ARG, noudevsync_ARG, regionsize_ARG,
> repair_ARG,
> + mirrorlog_ARG, mirrors_ARG, noudevsync_ARG, regionsize_ARG,
> repair_ARG, mirroredlog_ARG,
> snapshot_ARG, test_ARG, use_policies_ARG, yes_ARG, force_ARG,
> zero_ARG)
>
> xx(lvcreate,
> @@ -139,7 +138,7 @@
> "\t{-l|--extents LogicalExtentsNumber |\n"
> "\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
> "\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
> - "\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--
> corelog}]]\n"
> + "\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--
> corelog|--mirroredlog}]]\n"
> "\t[-n|--name LogicalVolumeName]\n"
> "\t[--noudevsync]\n"
> "\t[-p|--permission {r|rw}]\n"
> @@ -173,9 +172,9 @@
> "\t[-t|--test]\n"
> "\t[-v|--verbose]\n"
> "\t[--version]\n"
> + "\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
>
> - "\t[PhysicalVolumePath...]\n\n",
> -
> + mirroredlog_ARG,
> addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG,
> contiguous_ARG,
> corelog_ARG, extents_ARG, major_ARG, minor_ARG, mirrorlog_ARG,
> mirrors_ARG,
> name_ARG, nosync_ARG, noudevsync_ARG, permission_ARG,
> persistent_ARG,
> diff -r c70315774a35 tools/lvconvert.c
> --- a/tools/lvconvert.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/lvconvert.c Tue Sep 22 19:51:15 2009 -0700
> @@ -31,6 +31,7 @@
> uint32_t region_size;
>
> uint32_t mirrors;
> + uint32_t mirrored_log;
> sign_t mirrors_sign;
>
> struct segment_type *segtype;
> @@ -507,13 +508,16 @@
> int corelog)
> {
> struct logical_volume *original_lv = _original_lv(lv);
> +
> if (_using_corelog(lv) && !corelog) {
> - if (!add_mirror_log(cmd, original_lv, 1,
> + if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
> adjusted_mirror_region_size(
> lv->vg->extent_size,
> lv->le_count,
> lp->region_size),
> - lp->pvh, lp->alloc))
> + lp->pvh, lp->alloc,
> + lp->mirrors, 0, 0,
> + lp->mirrored_log))
> return_0;
> } else if (!_using_corelog(lv) && corelog) {
> if (!remove_mirror_log(cmd, original_lv,
> @@ -538,6 +542,8 @@
> int repair = arg_count(cmd, repair_ARG);
> int replace_log = 1, replace_mirrors = 1;
>
> + lp->mirrored_log = arg_count(cmd, mirroredlog_ARG);
> +
> seg = first_seg(lv);
> existing_mirrors = lv_mirror_count(lv);
>
> @@ -696,13 +702,13 @@
> * currently taken by the mirror? Would make more sense from
> * user perspective.
> */
> - if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
> + if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, 1, 0,
> adjusted_mirror_region_size(
> lv->vg->extent_size,
> lv->le_count,
> lp->region_size),
> corelog ? 0U : 1U, lp->pvh, lp->alloc,
> - MIRROR_BY_LV))
> + MIRROR_BY_LV, lp->mirrored_log))
> return_0;
> if (lp->wait_completion)
> lp->need_polling = 1;
> @@ -726,13 +732,13 @@
> return 0;
> }
> /* FIXME: can't have multiple mlogs. force corelog. */
> - if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
> + if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors -
> existing_mirrors, 1, 0,
> adjusted_mirror_region_size(
> lv->vg->extent_size,
> lv->le_count,
> lp->region_size),
> 0U, lp->pvh, lp->alloc,
> - MIRROR_BY_LV))
> + MIRROR_BY_LV, lp->mirrored_log))
> return_0;
> lv->status |= CONVERTING;
> lp->need_polling = 1;
> @@ -743,6 +749,7 @@
> if (!_lv_update_log_type(cmd, lp, lv, corelog))
> return_0;
> } else {
> + /*malahal this needs rework...*/
> log_error("Logical volume %s already has %"
> PRIu32 " mirror(s).", lv->name,
> lp->mirrors - 1);
> diff -r c70315774a35 tools/lvcreate.c
> --- a/tools/lvcreate.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/lvcreate.c Tue Sep 22 19:51:15 2009 -0700
> @@ -367,6 +367,9 @@
> lp->region_size = region_size;
> }
>
> + if (arg_count(cmd, mirroredlog_ARG))
> + lp->mirrored_log = 1;
> +
> if (!_validate_mirror_params(cmd, lp))
> return 0;
>
> diff -r c70315774a35 tools/pvmove.c
> --- a/tools/pvmove.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/pvmove.c Tue Sep 22 19:51:15 2009 -0700
> @@ -244,8 +244,8 @@
> return NULL;
> }
>
> - if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, log_count,
> - allocatable_pvs, alloc, MIRROR_BY_SEG)) {
> + if (!lv_add_mirrors(cmd, lv_mirr, NULL, 1u, 1u, 0u, 0u, log_count,
> + allocatable_pvs, alloc, MIRROR_BY_SEG, 0)) {
> log_error("Failed to convert pvmove LV to mirrored");
> return_NULL;
> }
>
> --
> dm-devel mailing list
> dm-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-23 20:29 ` Jonathan Brassow
@ 2009-09-23 20:44 ` malahal
0 siblings, 0 replies; 19+ messages in thread
From: malahal @ 2009-09-23 20:44 UTC (permalink / raw)
To: dm-devel
Jonathan Brassow [jbrassow@redhat.com] wrote:
> It would be nice if we didn't have to use '--mirroredlog' (a new option),
> but instead '--mirrorlog mirrored' (continuing use of the preferred
> option).
We can definitely change that.
> I will be continuing to review this.
Thank you very much.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-23 3:03 [RFC] [PATCH] lvm2: mirroredlog support malahal
2009-09-23 20:29 ` Jonathan Brassow
@ 2009-09-24 5:22 ` Takahiro Yasui
2009-09-30 15:50 ` Jonathan Brassow
2 siblings, 0 replies; 19+ messages in thread
From: Takahiro Yasui @ 2009-09-24 5:22 UTC (permalink / raw)
To: dm-devel
malahal@us.ibm.com wrote:
> This patch adds '--mirroredlog' option to LVM commands to create a
> mirror with mirrored log device. Rebased to the latest LVM code
> (LVM2.2.02.51). Have not done 'lvconvert' related changes yet!
> Appreciate any comments.
Thank you for the update of your mirroredlog patch. I'll also review
and test it, and then give some feedback here.
Thanks,
Taka
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-23 3:03 [RFC] [PATCH] lvm2: mirroredlog support malahal
2009-09-23 20:29 ` Jonathan Brassow
2009-09-24 5:22 ` Takahiro Yasui
@ 2009-09-30 15:50 ` Jonathan Brassow
2009-09-30 16:35 ` Alasdair G Kergon
2009-10-01 0:13 ` malahal
2 siblings, 2 replies; 19+ messages in thread
From: Jonathan Brassow @ 2009-09-30 15:50 UTC (permalink / raw)
To: device-mapper development
Looking through the code before applying your patch, it seems that
someone has already thought about this issue - even if it hasn't been
implemented. For example, already in the top most function used to
create mirrors, 'lv_add_mirrors', we see a 'log_count' parameter.
That parameter can be traced down through 'add_mirror_images/log',
'_set_up_mirror_log', and even the allocation functions. In fact, the
first comment in 'add_mirror_log' is /* Unimplemented features */,
followed by a check to see if 'log_count > 1'. Your patch seems to
ignore 'log_count' and create new parameters (like mirroredlog), which
seem unnecessary to me... I don't understand why any of the new
parameters to the functions are necessary, can you explain? [I can
see new parameters for '_create_mirror_log' though, as it doesn't seem
to maintain the 'log_count' parameter - but you didn't do work in that
function.]
You also seem to have violated the allocation policies by ignoring the
line of work that has been done up to '_set_up_mirror_log' by simply
calling 'add_mirror_images'. This works, but it is oversimplified, I
think. You can see this is incorrect by simply testing:
prompt> lvcreate -m1 -L 500M -n lv vg /dev/sd[xy]1 # will fail
because there are only two devices
prompt> lvcreate ... --mirroredlog /dev/sd[xy]1 # should fail, but
succeeds due to ignoring previous allocation work
You may wish to push your enhancements into '_[create |
init]_mirror_log'?
Additionally, the 'log_count' parameter is more general than
'mirroredlog' and can support more log types. Consider the following:
--mirrorlog core => (log_count = 0)
--mirrorlog disk => (log_count = 1)
--mirrorlog redundant => (log_count = 2)
--mirrorlog fully_redundant => (log_count = # of mirror legs)
You are looking to add "redundant" (you can call it "mirrored" if you
like), but if we use 'log_count' in a general way, we get
"fully_redundant" (almost) for free.
I probably haven't given this code as much time as you have, so if
there are reasons for the way you implemented it, please help inform me.
As long as we are on the topic of mirror logs (and this is unrelated
to your patch), I'd like to complain about the current behavior of log
allocation vs the log policy. I don't think it should take
'alloc_anywhere' for a log to be placed on the same disk as one of the
mirror legs... that should be 'alloc_normal'. I think it should be
something like:
ALLOC_CONTIGUOUS: logs and images on all separate devices - no overlap
ALLOC_NORMAL: Allow logs to exist on the same devices as the mirror
images.
ALLOC_ANYWHERE: Should we allow mirror images on the same device!?!
(i.e. everything can be packed on one device)
It is silly to me that a user with two devices cannot create the
default mirror. It makes even less sense when you consider mirrors
with redundant logs, as this just adds to the number of devices you
need. I'd love to see this fixed, but overthrowing and established
policy may be difficult.
brassow
On Sep 22, 2009, at 10:03 PM, malahal@us.ibm.com wrote:
> This patch adds '--mirroredlog' option to LVM commands to create a
> mirror with mirrored log device. Rebased to the latest LVM code
> (LVM2.2.02.51). Have not done 'lvconvert' related changes yet!
> Appreciate any comments.
>
> diff -r c70315774a35 lib/activate/activate.c
> --- a/lib/activate/activate.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/activate/activate.c Tue Sep 22 19:51:15 2009 -0700
> @@ -979,6 +979,8 @@
> {
> struct logical_volume *lv;
> struct lvinfo info;
> + struct lv_segment *seg, *log_seg;
> + struct segment_type *type = get_segtype_from_string(cmd, "mirror");
> int r = 0;
>
> if (!activation())
> @@ -1012,6 +1014,20 @@
> if (!monitor_dev_for_events(cmd, lv, 0))
> stack;
>
> + if ( !dm_list_empty(&lv->segments) ) {
> + seg = dm_list_item(dm_list_first(&lv->segments), struct
> lv_segment);
> + if (seg->log_lv) {
> + log_very_verbose("lv %s is mirrored, check it's log %s...", lv-
> >name, seg->log_lv->name);
> + if ( !dm_list_empty(&seg->log_lv->segments) ) {
> + log_seg = dm_list_item(dm_list_first(&seg->log_lv->segments),
> struct lv_segment);
> + if (log_seg->segtype == type) {
> + log_verbose("log %s is mirrored, unregister for events",
> log_seg->lv->name);
> + monitor_dev_for_events(cmd, log_seg->lv, 0);
> + }
> + }
> + }
> + }
> +
> memlock_inc();
> r = _lv_deactivate(lv);
> memlock_dec();
> diff -r c70315774a35 lib/metadata/lv_manip.c
> --- a/lib/metadata/lv_manip.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/metadata/lv_manip.c Tue Sep 22 19:51:15 2009 -0700
> @@ -3029,14 +3029,16 @@
> return_0;
>
> if (lp->mirrors > 1) {
> - if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, lp->stripes,
> + if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1,
> + lp->stripes, lp->stripe_size,
> adjusted_mirror_region_size(
> vg->extent_size,
> lv->le_count,
> lp->region_size),
> lp->corelog ? 0U : 1U, lp->pvh, lp->alloc,
> MIRROR_BY_LV |
> - (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0))) {
> + (lp->nosync ? MIRROR_SKIP_INIT_SYNC : 0),
> + lp->mirrored_log)) {
> stack;
> goto revert_new_lv;
> }
> diff -r c70315774a35 lib/metadata/metadata-exported.h
> --- a/lib/metadata/metadata-exported.h Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/metadata/metadata-exported.h Tue Sep 22 19:51:15 2009 -0700
> @@ -528,6 +528,7 @@
> uint32_t region_size; /* mirror */
>
> uint32_t mirrors; /* mirror */
> + uint32_t mirrored_log; /* mirror */
>
> const struct segment_type *segtype; /* all */
>
> @@ -637,9 +638,11 @@
> */
> struct lv_segment *find_mirror_seg(struct lv_segment *seg);
> int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
> - uint32_t mirrors, uint32_t stripes,
> + const struct segment_type *segtype,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> uint32_t region_size, uint32_t log_count,
> - struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags);
> + struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
> + uint32_t mirrored_log);
> int lv_remove_mirrors(struct cmd_context *cmd, struct logical_volume
> *lv,
> uint32_t mirrors, uint32_t log_count,
> struct dm_list *pvs, uint32_t status_mask);
> @@ -658,16 +661,21 @@
> int remove_mirror_images(struct logical_volume *lv, uint32_t
> num_mirrors,
> struct dm_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,
> + const struct segment_type *segtype,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> + uint32_t region_size,
> struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> - uint32_t log_count);
> + uint32_t log_count, uint32_t mirrored_log);
> struct logical_volume *detach_mirror_log(struct lv_segment *seg);
> int attach_mirror_log(struct lv_segment *seg, struct logical_volume
> *lv);
> int remove_mirror_log(struct cmd_context *cmd, struct logical_volume
> *lv,
> struct dm_list *removable_pvs);
> int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
> + const struct segment_type *segtype,
> uint32_t log_count, uint32_t region_size,
> - struct dm_list *allocatable_pvs, alloc_policy_t alloc);
> + struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> + uint32_t mirrored_log);
>
> int reconfigure_mirror_images(struct lv_segment *mirrored_seg,
> uint32_t num_mirrors,
> struct dm_list *removable_pvs, unsigned remove_log);
> diff -r c70315774a35 lib/metadata/mirror.c
> --- a/lib/metadata/mirror.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/lib/metadata/mirror.c Tue Sep 22 19:51:15 2009 -0700
> @@ -1248,7 +1248,8 @@
> struct alloc_handle *ah,
> alloc_policy_t alloc,
> const char *lv_name,
> - const char *suffix)
> + const char *suffix,
> + uint32_t mirrored_log)
> {
> struct logical_volume *log_lv;
> char *log_name;
> @@ -1270,7 +1271,7 @@
> alloc, lv->vg)))
> return_NULL;
>
> - if (!lv_add_log_segment(ah, log_lv))
> + if (!mirrored_log && !lv_add_log_segment(ah, log_lv))
> return_NULL;
>
> return log_lv;
> @@ -1279,10 +1280,16 @@
> static struct logical_volume *_set_up_mirror_log(struct cmd_context
> *cmd,
> struct alloc_handle *ah,
> struct logical_volume *lv,
> + const struct segment_type *segtype,
> uint32_t log_count,
> - uint32_t region_size __attribute((unused)),
> + uint32_t region_size,
> alloc_policy_t alloc,
> - int in_sync)
> + int in_sync,
> + uint32_t mirrors,
> + uint32_t stripes,
> + uint32_t stripe_size,
> + struct dm_list *allocatable_pvs,
> + uint32_t mirrored_log)
> {
> struct logical_volume *log_lv;
> const char *suffix, *c;
> @@ -1324,11 +1331,20 @@
> }
>
> if (!(log_lv = _create_mirror_log(lv, ah, alloc,
> - (const char *) lv_name, suffix))) {
> + (const char *) lv_name, suffix, mirrored_log))) {
> log_error("Failed to create mirror log.");
> return NULL;
> }
>
> + if (mirrored_log) {
> + if (!lv_extend(log_lv, segtype, stripes, stripe_size,
> + 1u, 1u, NULL, 0u, 0u, allocatable_pvs, alloc))
> + return NULL;
> +
> + add_mirror_images(cmd, log_lv, segtype, mirrors, stripes,
> stripe_size,
> + region_size, allocatable_pvs, alloc, 0, 0);
> + }
> +
> if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
> log_error("Failed to create mirror log.");
> return NULL;
> @@ -1346,8 +1362,11 @@
> }
>
> int add_mirror_log(struct cmd_context *cmd, struct logical_volume *lv,
> + const struct segment_type *seg_type,
> uint32_t log_count, uint32_t region_size,
> - struct dm_list *allocatable_pvs, alloc_policy_t alloc)
> + struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> + uint32_t mirrors, uint32_t stripes, uint32_t stripe_size,
> + uint32_t mirrored_log)
> {
> struct alloc_handle *ah;
> const struct segment_type *segtype;
> @@ -1410,8 +1429,10 @@
> else
> in_sync = 0;
>
> - if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
> - region_size, alloc, in_sync)))
> + if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type, log_count,
> + region_size, alloc, in_sync,
> + mirrors, stripes, stripe_size, allocatable_pvs,
> + mirrored_log)))
> goto_out;
>
> if (!attach_mirror_log(first_seg(lv), log_lv))
> @@ -1427,9 +1448,10 @@
> * Convert "linear" LV to "mirror".
> */
> int add_mirror_images(struct cmd_context *cmd, struct logical_volume
> *lv,
> - uint32_t mirrors, uint32_t stripes, uint32_t region_size,
> + const struct segment_type *seg_type, uint32_t mirrors,
> + uint32_t stripes, uint32_t stripe_size, uint32_t region_size,
> struct dm_list *allocatable_pvs, alloc_policy_t alloc,
> - uint32_t log_count)
> + uint32_t log_count, uint32_t mirrored_log)
> {
> struct alloc_handle *ah;
> const struct segment_type *segtype;
> @@ -1452,9 +1474,18 @@
> if (!(segtype = get_segtype_from_string(cmd, "mirror")))
> return_0;
>
> - ah = allocate_extents(lv->vg, NULL, segtype,
> - stripes, mirrors, log_count, region_size, lv->le_count,
> - allocatable_pvs, alloc, parallel_areas);
> + if (mirrored_log)
> + /* Allocate mirror extents for the log */
> + ah = allocate_extents(lv->vg, NULL, segtype,
> + stripes, mirrors, 0,
> + region_size, 1,
> + allocatable_pvs, alloc, parallel_areas);
> + else
> + ah = allocate_extents(lv->vg, NULL, segtype,
> + stripes, mirrors, log_count,
> + region_size, lv->le_count,
> + allocatable_pvs, alloc, parallel_areas);
> +
> if (!ah) {
> log_error("Unable to allocate extents for mirror(s).");
> return 0;
> @@ -1463,11 +1494,25 @@
> /*
> * create and initialize mirror log
> */
> - if (log_count &&
> - !(log_lv = _set_up_mirror_log(cmd, ah, lv, log_count,
> region_size,
> - alloc, mirror_in_sync()))) {
> - stack;
> - goto out_remove_images;
> + if (log_count) {
> + if (!(log_lv = _set_up_mirror_log(cmd, ah, lv, seg_type,
> log_count, region_size,
> + alloc, mirror_in_sync(), mirrors, stripes,
> + stripe_size, allocatable_pvs, mirrored_log))) {
> + stack;
> + goto out_remove_images;
> + }
> + if (mirrored_log) {
> + /* Allocate extents for the mirror legs */
> + alloc_destroy(ah);
> + ah = allocate_extents(lv->vg, NULL, segtype,
> + stripes, mirrors, 0,
> + region_size, lv->le_count,
> + allocatable_pvs, alloc, parallel_areas);
> + if (!ah) {
> + stack;
> + goto out_remove_images;
> + }
> + }
> }
>
> /* The log initialization involves vg metadata commit.
> @@ -1529,9 +1574,11 @@
> * 'pvs' is either allocatable pvs.
> */
> int lv_add_mirrors(struct cmd_context *cmd, struct logical_volume *lv,
> - uint32_t mirrors, uint32_t stripes,
> + const struct segment_type *seg_type, uint32_t mirrors,
> + uint32_t stripes, uint32_t stripe_size,
> uint32_t region_size, uint32_t log_count,
> - struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags)
> + struct dm_list *pvs, alloc_policy_t alloc, uint32_t flags,
> + uint32_t mirrored_log)
> {
> if (!mirrors && !log_count) {
> log_error("No conversion is requested");
> @@ -1564,11 +1611,13 @@
> region_size, pvs, alloc);
> } else if (flags & MIRROR_BY_LV) {
> if (!mirrors)
> - return add_mirror_log(cmd, lv, log_count,
> - region_size, pvs, alloc);
> - return add_mirror_images(cmd, lv, mirrors,
> - stripes, region_size,
> - pvs, alloc, log_count);
> + return add_mirror_log(cmd, lv, seg_type, log_count,
> + region_size, pvs, alloc, mirrors,
> + stripes, stripe_size, mirrored_log);
> + return add_mirror_images(cmd, lv, seg_type, mirrors,
> + stripes, stripe_size, region_size,
> + pvs, alloc, log_count,
> + mirrored_log);
> }
>
> log_error("Unsupported mirror conversion type");
> diff -r c70315774a35 tools/args.h
> --- a/tools/args.h Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/args.h Tue Sep 22 19:51:15 2009 -0700
> @@ -45,6 +45,7 @@
> arg(alloc_ARG, '\0', "alloc", alloc_arg, 0)
> arg(separator_ARG, '\0', "separator", string_arg, 0)
> arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0)
> +arg(mirroredlog_ARG, '\0', "mirroredlog", NULL, 0)
> arg(nosync_ARG, '\0', "nosync", NULL, 0)
> arg(resync_ARG, '\0', "resync", NULL, 0)
> arg(corelog_ARG, '\0', "corelog", NULL, 0)
> diff -r c70315774a35 tools/commands.h
> --- a/tools/commands.h Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/commands.h Tue Sep 22 19:51:15 2009 -0700
> @@ -95,8 +95,7 @@
> "Change logical volume layout",
> 0,
> "lvconvert "
> - "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
> - "\t[--repair [--use-policies]]\n"
> + "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog|--
> mirroredlog}]]\n"
> "\t[-R|--regionsize MirrorLogRegionSize]\n"
> "\t[--alloc AllocationPolicy]\n"
> "\t[-b|--background]\n"
> @@ -122,7 +121,7 @@
> "\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
>
> alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG,
> interval_ARG,
> - mirrorlog_ARG, mirrors_ARG, noudevsync_ARG, regionsize_ARG,
> repair_ARG,
> + mirrorlog_ARG, mirrors_ARG, noudevsync_ARG, regionsize_ARG,
> repair_ARG, mirroredlog_ARG,
> snapshot_ARG, test_ARG, use_policies_ARG, yes_ARG, force_ARG,
> zero_ARG)
>
> xx(lvcreate,
> @@ -139,7 +138,7 @@
> "\t{-l|--extents LogicalExtentsNumber |\n"
> "\t -L|--size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n"
> "\t[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
> - "\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--
> corelog}]]\n"
> + "\t[-m|--mirrors Mirrors [--nosync] [{--mirrorlog {disk|core}|--
> corelog|--mirroredlog}]]\n"
> "\t[-n|--name LogicalVolumeName]\n"
> "\t[--noudevsync]\n"
> "\t[-p|--permission {r|rw}]\n"
> @@ -173,9 +172,9 @@
> "\t[-t|--test]\n"
> "\t[-v|--verbose]\n"
> "\t[--version]\n"
> + "\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
>
> - "\t[PhysicalVolumePath...]\n\n",
> -
> + mirroredlog_ARG,
> addtag_ARG, alloc_ARG, autobackup_ARG, chunksize_ARG,
> contiguous_ARG,
> corelog_ARG, extents_ARG, major_ARG, minor_ARG, mirrorlog_ARG,
> mirrors_ARG,
> name_ARG, nosync_ARG, noudevsync_ARG, permission_ARG,
> persistent_ARG,
> diff -r c70315774a35 tools/lvconvert.c
> --- a/tools/lvconvert.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/lvconvert.c Tue Sep 22 19:51:15 2009 -0700
> @@ -31,6 +31,7 @@
> uint32_t region_size;
>
> uint32_t mirrors;
> + uint32_t mirrored_log;
> sign_t mirrors_sign;
>
> struct segment_type *segtype;
> @@ -507,13 +508,16 @@
> int corelog)
> {
> struct logical_volume *original_lv = _original_lv(lv);
> +
> if (_using_corelog(lv) && !corelog) {
> - if (!add_mirror_log(cmd, original_lv, 1,
> + if (!add_mirror_log(cmd, original_lv, lp->segtype, 1,
> adjusted_mirror_region_size(
> lv->vg->extent_size,
> lv->le_count,
> lp->region_size),
> - lp->pvh, lp->alloc))
> + lp->pvh, lp->alloc,
> + lp->mirrors, 0, 0,
> + lp->mirrored_log))
> return_0;
> } else if (!_using_corelog(lv) && corelog) {
> if (!remove_mirror_log(cmd, original_lv,
> @@ -538,6 +542,8 @@
> int repair = arg_count(cmd, repair_ARG);
> int replace_log = 1, replace_mirrors = 1;
>
> + lp->mirrored_log = arg_count(cmd, mirroredlog_ARG);
> +
> seg = first_seg(lv);
> existing_mirrors = lv_mirror_count(lv);
>
> @@ -696,13 +702,13 @@
> * currently taken by the mirror? Would make more sense from
> * user perspective.
> */
> - if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
> + if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors - 1, 1, 0,
> adjusted_mirror_region_size(
> lv->vg->extent_size,
> lv->le_count,
> lp->region_size),
> corelog ? 0U : 1U, lp->pvh, lp->alloc,
> - MIRROR_BY_LV))
> + MIRROR_BY_LV, lp->mirrored_log))
> return_0;
> if (lp->wait_completion)
> lp->need_polling = 1;
> @@ -726,13 +732,13 @@
> return 0;
> }
> /* FIXME: can't have multiple mlogs. force corelog. */
> - if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
> + if (!lv_add_mirrors(cmd, lv, lp->segtype, lp->mirrors -
> existing_mirrors, 1, 0,
> adjusted_mirror_region_size(
> lv->vg->extent_size,
> lv->le_count,
> lp->region_size),
> 0U, lp->pvh, lp->alloc,
> - MIRROR_BY_LV))
> + MIRROR_BY_LV, lp->mirrored_log))
> return_0;
> lv->status |= CONVERTING;
> lp->need_polling = 1;
> @@ -743,6 +749,7 @@
> if (!_lv_update_log_type(cmd, lp, lv, corelog))
> return_0;
> } else {
> + /*malahal this needs rework...*/
> log_error("Logical volume %s already has %"
> PRIu32 " mirror(s).", lv->name,
> lp->mirrors - 1);
> diff -r c70315774a35 tools/lvcreate.c
> --- a/tools/lvcreate.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/lvcreate.c Tue Sep 22 19:51:15 2009 -0700
> @@ -367,6 +367,9 @@
> lp->region_size = region_size;
> }
>
> + if (arg_count(cmd, mirroredlog_ARG))
> + lp->mirrored_log = 1;
> +
> if (!_validate_mirror_params(cmd, lp))
> return 0;
>
> diff -r c70315774a35 tools/pvmove.c
> --- a/tools/pvmove.c Tue Sep 15 12:08:46 2009 -0700
> +++ b/tools/pvmove.c Tue Sep 22 19:51:15 2009 -0700
> @@ -244,8 +244,8 @@
> return NULL;
> }
>
> - if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, log_count,
> - allocatable_pvs, alloc, MIRROR_BY_SEG)) {
> + if (!lv_add_mirrors(cmd, lv_mirr, NULL, 1u, 1u, 0u, 0u, log_count,
> + allocatable_pvs, alloc, MIRROR_BY_SEG, 0)) {
> log_error("Failed to convert pvmove LV to mirrored");
> return_NULL;
> }
>
> --
> dm-devel mailing list
> dm-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-30 15:50 ` Jonathan Brassow
@ 2009-09-30 16:35 ` Alasdair G Kergon
2009-09-30 19:48 ` Jonathan Brassow
2009-10-01 0:13 ` malahal
1 sibling, 1 reply; 19+ messages in thread
From: Alasdair G Kergon @ 2009-09-30 16:35 UTC (permalink / raw)
To: device-mapper development
On Wed, Sep 30, 2009 at 10:50:06AM -0500, Jon Brassow wrote:
> As long as we are on the topic of mirror logs (and this is unrelated to
> your patch), I'd like to complain about the current behavior of log
> allocation vs the log policy. I don't think it should take
> 'alloc_anywhere' for a log to be placed on the same disk as one of the
> mirror legs... that should be 'alloc_normal'.
It was assumed that performance would be better this way, but I have
never seen any tests to prove or disprove that. Maybe someone could run
some?
One way we could handle this is by creating a new policy between
NORMAL and ANYWHERE that does this, then renaming the old NORMAL
to something else and the new policy to NORMAL.
Alasdair
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-30 16:35 ` Alasdair G Kergon
@ 2009-09-30 19:48 ` Jonathan Brassow
2009-09-30 21:18 ` Alasdair G Kergon
2009-09-30 21:19 ` malahal
0 siblings, 2 replies; 19+ messages in thread
From: Jonathan Brassow @ 2009-09-30 19:48 UTC (permalink / raw)
To: device-mapper development
On Sep 30, 2009, at 11:35 AM, Alasdair G Kergon wrote:
> On Wed, Sep 30, 2009 at 10:50:06AM -0500, Jon Brassow wrote:
>> As long as we are on the topic of mirror logs (and this is
>> unrelated to
>> your patch), I'd like to complain about the current behavior of log
>> allocation vs the log policy. I don't think it should take
>> 'alloc_anywhere' for a log to be placed on the same disk as one of
>> the
>> mirror legs... that should be 'alloc_normal'.
>
> It was assumed that performance would be better this way, but I have
> never seen any tests to prove or disprove that. Maybe someone could
> run
> some?
>
> One way we could handle this is by creating a new policy between
> NORMAL and ANYWHERE that does this, then renaming the old NORMAL
> to something else and the new policy to NORMAL.
In addition to performance, I would also think that "preserving
hardware" might be a minor priority. You don't want to go banging
around the heads of your hard-drives if you don't have to.
However, the user will get these benefits if they have 1 more device
than the mirror images they are trying to create... If not, it should
naturally fall back to allowing the overlap of images and logs.
Inserting a new allocation level is a possibility. I don't think it's
necessary to solve (what I see as) the problem. Do you have a reason
for this? (Remember, the change would only affect how mirrors behave
with the various allocation policies. If the user wanted the old
behavior, they could get it with ALLOC_CONTIGUOUS.... However, the
user would be stupid to choose that, because if they have enough
disks, they will get CONTIGUOUS, and if they don't it would fail...
Perhaps they would rather have the command fail then allow them to do
what they are trying?)
brassow
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-30 19:48 ` Jonathan Brassow
@ 2009-09-30 21:18 ` Alasdair G Kergon
2009-09-30 21:46 ` Alasdair G Kergon
2009-09-30 21:19 ` malahal
1 sibling, 1 reply; 19+ messages in thread
From: Alasdair G Kergon @ 2009-09-30 21:18 UTC (permalink / raw)
To: device-mapper development
On Wed, Sep 30, 2009 at 02:48:22PM -0500, Jon Brassow wrote:
> Inserting a new allocation level is a possibility. I don't think it's
> necessary to solve (what I see as) the problem. Do you have a reason
> for this?
It doesn't actually fit into the existing hierarchy very well at all - it's
pretty much an independent property (which the existing allocation routines
do not support). E.g. consider if you require 'cling' with the log on the
same disk as some of the mirror's data. Falling through to 'Normal' or
'anywhere' and allowing the log to share a disk could give you a wrong
layout. But you want to give priority to arrangements with the log on a
different disk where possible. So do you have to try all the policies twice,
first with the existing find_parallel_areas, and then with a new flag which
allows some specified areas to be 'anywhere' (almost doubling the number of
policies), or perhaps break it into two independent allocations at that point,
one for the data and then one for the log?
Alasdair
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-30 19:48 ` Jonathan Brassow
2009-09-30 21:18 ` Alasdair G Kergon
@ 2009-09-30 21:19 ` malahal
1 sibling, 0 replies; 19+ messages in thread
From: malahal @ 2009-09-30 21:19 UTC (permalink / raw)
To: dm-devel
Jonathan Brassow [jbrassow@redhat.com] wrote:
>
> On Sep 30, 2009, at 11:35 AM, Alasdair G Kergon wrote:
>
>> On Wed, Sep 30, 2009 at 10:50:06AM -0500, Jon Brassow wrote:
>>> As long as we are on the topic of mirror logs (and this is unrelated to
>>> your patch), I'd like to complain about the current behavior of log
>>> allocation vs the log policy. I don't think it should take
>>> 'alloc_anywhere' for a log to be placed on the same disk as one of the
>>> mirror legs... that should be 'alloc_normal'.
>>
>> It was assumed that performance would be better this way, but I have
>> never seen any tests to prove or disprove that. Maybe someone could run
>> some?
>>
>> One way we could handle this is by creating a new policy between
>> NORMAL and ANYWHERE that does this, then renaming the old NORMAL
>> to something else and the new policy to NORMAL.
>
> In addition to performance, I would also think that "preserving hardware"
> might be a minor priority. You don't want to go banging around the heads
> of your hard-drives if you don't have to.
>
> However, the user will get these benefits if they have 1 more device than
> the mirror images they are trying to create... If not, it should naturally
> fall back to allowing the overlap of images and logs.
>
> Inserting a new allocation level is a possibility. I don't think it's
> necessary to solve (what I see as) the problem. Do you have a reason for
> this? (Remember, the change would only affect how mirrors behave with the
> various allocation policies. If the user wanted the old behavior, they
> could get it with ALLOC_CONTIGUOUS.... However, the user would be stupid
> to choose that, because if they have enough disks, they will get
> CONTIGUOUS, and if they don't it would fail... Perhaps they would rather
> have the command fail then allow them to do what they are trying?)
Imagine that I have lots of PVs and only two of them have free space.
When I create a mirror, your proposal could put the log on a PV that
has one of the mirror legs. It is silent! Had it failed, I could have
extended any of the full PVs and re-ran lvcreate. I think I like the
current behaviour for that reason.
I would rather have a system that fail and tell me why it failed rather
than do something that I don't expect!
Maybe, a better failure message is an answer? If such default lvcreate
failures bother someone, he can probably ask for something in lvm.conf
he can set at one time to behave the way you want it.
Thanks, Malahal.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-30 21:18 ` Alasdair G Kergon
@ 2009-09-30 21:46 ` Alasdair G Kergon
0 siblings, 0 replies; 19+ messages in thread
From: Alasdair G Kergon @ 2009-09-30 21:46 UTC (permalink / raw)
To: device-mapper development
On Wed, Sep 30, 2009 at 10:18:26PM +0100, Alasdair G Kergon wrote:
> or perhaps break it into two independent allocations at that point,
> one for the data and then one for the log?
Perhaps that's the solution: a new lvm.conf/cmdline parm that permits
independent log placement.
Allocation is initially performed the same as currently.
But if it fails and this new setting was chosen, then the allocation is
re-attempted without the log, and if that succeeds, an independent
attempt is made to allocate the log.
Alasdair
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [RFC] [PATCH] lvm2: mirroredlog support
2009-09-30 15:50 ` Jonathan Brassow
2009-09-30 16:35 ` Alasdair G Kergon
@ 2009-10-01 0:13 ` malahal
1 sibling, 0 replies; 19+ messages in thread
From: malahal @ 2009-10-01 0:13 UTC (permalink / raw)
To: dm-devel, jbrassow; +Cc: agk
Jonathan Brassow [jbrassow@redhat.com] wrote:
> Looking through the code before applying your patch, it seems that someone
> has already thought about this issue - even if it hasn't been implemented.
> For example, already in the top most function used to create mirrors,
> 'lv_add_mirrors', we see a 'log_count' parameter. That parameter can be
> traced down through 'add_mirror_images/log', '_set_up_mirror_log', and even
> the allocation functions. In fact, the first comment in 'add_mirror_log'
> is /* Unimplemented features */, followed by a check to see if 'log_count >
> 1'. Your patch seems to ignore 'log_count' and create new parameters (like
> mirroredlog), which seem unnecessary to me...
Yes, I saw the log_count but not sure if I can use that for my purpose.
You can have multiple logs (reserved/standby mode implementations)
without the logs themselves mirrored.
> I don't understand why any
> of the new parameters to the functions are necessary, can you explain? [I
> can see new parameters for '_create_mirror_log' though, as it doesn't seem
> to maintain the 'log_count' parameter - but you didn't do work in that
> function.]
_set_up_mirror_log() needs those extra parameters while calling
lv_extend() in the patch.
> You also seem to have violated the allocation policies by ignoring the line
> of work that has been done up to '_set_up_mirror_log' by simply calling
> 'add_mirror_images'. This works, but it is oversimplified, I think. You
> can see this is incorrect by simply testing:
> prompt> lvcreate -m1 -L 500M -n lv vg /dev/sd[xy]1 # will fail because
> there are only two devices
> prompt> lvcreate ... --mirroredlog /dev/sd[xy]1 # should fail, but succeeds
> due to ignoring previous allocation work
> You may wish to push your enhancements into '_[create | init]_mirror_log'?
Thank you for spotting it. I will look into your suggestion.
> Additionally, the 'log_count' parameter is more general than 'mirroredlog'
> and can support more log types. Consider the following:
> --mirrorlog core => (log_count = 0)
> --mirrorlog disk => (log_count = 1)
> --mirrorlog redundant => (log_count = 2)
> --mirrorlog fully_redundant => (log_count = # of mirror legs)
> You are looking to add "redundant" (you can call it "mirrored" if you
> like), but if we use 'log_count' in a general way, we get "fully_redundant"
> (almost) for free.
The current patch actually creates fully_redundant log based what you
described.
If we are not going to use log_count for anything else other than
creating "mirrored" logs, I can use it. I remember Heinz implementing a
log device per mirror leg but the logs not not mirrored at all.
Alasdair, any comments?
Thanks, Malahal.
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2009-10-01 0:13 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-23 3:03 [RFC] [PATCH] lvm2: mirroredlog support malahal
2009-09-23 20:29 ` Jonathan Brassow
2009-09-23 20:44 ` malahal
2009-09-24 5:22 ` Takahiro Yasui
2009-09-30 15:50 ` Jonathan Brassow
2009-09-30 16:35 ` Alasdair G Kergon
2009-09-30 19:48 ` Jonathan Brassow
2009-09-30 21:18 ` Alasdair G Kergon
2009-09-30 21:46 ` Alasdair G Kergon
2009-09-30 21:19 ` malahal
2009-10-01 0:13 ` malahal
-- strict thread matches above, loose matches on Subject: below --
2008-12-30 0:10 malahal
2008-12-30 0:10 ` malahal
2009-01-19 22:56 ` Takahiro Yasui
2009-01-20 1:54 ` malahal
2009-01-20 22:12 ` Takahiro Yasui
2009-01-20 21:29 ` Takahiro Yasui
2009-01-20 22:14 ` malahal
2009-01-23 19:14 ` Jonathan Brassow
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.