b4c433fdb0
- Update to 2.02.120 - Fixed numerous bugs(see WHATS_NEW for full details) - Deleted dab3ebce-devices-Do-not-support-unpartitioned-DASD.patch (upstream) OBS-URL: https://build.opensuse.org/request/show/310530 OBS-URL: https://build.opensuse.org/package/show/Base:System/lvm2?expand=0&rev=130
161 lines
6.0 KiB
Diff
161 lines
6.0 KiB
Diff
From 49a5da732c74b8b96bc123a541d590c4fd06d7af Mon Sep 17 00:00:00 2001
|
|
From: Guangliang Zhao <gzhao@suse.com>
|
|
Date: Mon, 12 Nov 2012 15:28:11 +0800
|
|
Subject: [PATCH 1/2] mirror: make mirror legs on different tag pvs
|
|
|
|
The mirror legs could be placed on the PVs(with different
|
|
tags) from the other mirror legs with this patch.
|
|
|
|
The lvcreate allocates the replica "randomly" when creating
|
|
a mirrored logical volume now, so it could happen that both
|
|
copies end up on the same array (or on the same site), clearly
|
|
undesired.
|
|
|
|
We can't control the fist allocation, because didn't restrict
|
|
the areas into parallel space. This patch add the limit when
|
|
finding areas for parallel space, so that mirror legs will
|
|
always be placed on pvs with differnt tags.
|
|
|
|
Signed-off-by: Guangliang Zhao <gzhao@suse.com>
|
|
---
|
|
conf/example.conf.in | 17 +++++++++++++++++
|
|
lib/config/config_settings.h | 3 +++
|
|
lib/config/defaults.h | 1 +
|
|
lib/metadata/lv_manip.c | 35 +++++++++++++++++++++++++++++++++++
|
|
man/lvcreate.8.in | 4 ++++
|
|
5 files changed, 60 insertions(+)
|
|
|
|
--- a/conf/example.conf.in
|
|
+++ b/conf/example.conf.in
|
|
@@ -359,6 +359,23 @@ allocation {
|
|
# option is used directly.
|
|
wipe_signatures_when_zeroing_new_lvs = 1
|
|
|
|
+ # Set to 1 to guarantee that mirror leg will always be placed on
|
|
+ # different PVs(with different tags) from the other mirror legs.
|
|
+ #
|
|
+ # If you want to enable this feature, the following conditions
|
|
+ # must be met:
|
|
+ # 1) The mirror_legs_require_separate_pvs must be set to 1, the
|
|
+ # default value is 0.
|
|
+ # 2) The cling_tag_list must be activated.
|
|
+ # 3) The length of all pvs with same tag must greater than or equal
|
|
+ # to the mirror's.
|
|
+
|
|
+ # This feature is only for the first allocation, on the other hand
|
|
+ # when creating new mirrored lvs.
|
|
+ # Please note that the commond may fail if the number of all tags
|
|
+ # on the pvs less than the mirror legs number.
|
|
+ mirror_legs_require_separate_pvs = 0
|
|
+
|
|
# Configuration option allocation/mirror_logs_require_separate_pvs.
|
|
# Mirror logs and images will always use different PVs.
|
|
# The default setting changed in version 2.02.85.
|
|
--- a/lib/config/config_settings.h
|
|
+++ b/lib/config/config_settings.h
|
|
@@ -457,6 +457,9 @@ cfg(allocation_mirror_logs_require_separ
|
|
"Mirror logs and images will always use different PVs.\n"
|
|
"The default setting changed in version 2.02.85.\n")
|
|
|
|
+cfg(allocation_mirror_legs_require_separate_pvs_CFG, "mirror_legs_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MIRROR_LEGS_REQUIRE_SEPARATE_PVS, vsn(2, 2, 98), NULL, 0, NULL,
|
|
+ "Mirror legs will always use different PVs.\n")
|
|
+
|
|
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL, 0, NULL,
|
|
"Cache pool metadata and data will always use different PVs.\n")
|
|
|
|
--- a/lib/config/defaults.h
|
|
+++ b/lib/config/defaults.h
|
|
@@ -132,6 +132,7 @@
|
|
#define DEFAULT_MAX_LV 0
|
|
#define DEFAULT_ALLOC_POLICY ALLOC_NORMAL
|
|
#define DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS 0
|
|
+#define DEFAULT_MIRROR_LEGS_REQUIRE_SEPARATE_PVS 0
|
|
#define DEFAULT_MAXIMISE_CLING 1
|
|
#define DEFAULT_CLUSTERED 0
|
|
|
|
--- a/lib/metadata/lv_manip.c
|
|
+++ b/lib/metadata/lv_manip.c
|
|
@@ -1447,6 +1447,9 @@ struct alloc_handle {
|
|
|
|
unsigned maximise_cling;
|
|
unsigned mirror_logs_separate; /* Force mirror logs on separate PVs? */
|
|
+ unsigned mirror_legs_separate; /* Force mirror *legs* on separate PVs*/
|
|
+
|
|
+ const struct segment_type *segtype;
|
|
|
|
/*
|
|
* RAID devices require a metadata area that accompanies each
|
|
@@ -2542,6 +2545,32 @@ static int _limit_to_one_area_per_tag(st
|
|
}
|
|
|
|
/*
|
|
+ * Return -1 if we don't need check tags, or there aren't any areas in alloc_status
|
|
+ * have the same tag with pva, the index otherwise.
|
|
+ */
|
|
+static int check_areas_separate_tags(struct alloc_handle *ah,
|
|
+ struct alloc_state *alloc_state,
|
|
+ unsigned ix_start,
|
|
+ unsigned ix_end,
|
|
+ struct pv_area *pva)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ if (!segtype_is_mirrored(ah->segtype) ||
|
|
+ alloc_state->allocated ||
|
|
+ !ah->mirror_legs_separate ||
|
|
+ !ah->cling_tag_list_cn)
|
|
+ return -1;
|
|
+
|
|
+ for (i = ix_start; i < ix_end; i++)
|
|
+ if(_pvs_have_matching_tag(ah->cling_tag_list_cn,
|
|
+ alloc_state->areas[i].pva->map->pv,
|
|
+ pva->map->pv))
|
|
+ return i;
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+/*
|
|
* Returns 1 regardless of whether any space was found, except on error.
|
|
*/
|
|
static int _find_some_parallel_space(struct alloc_handle *ah,
|
|
@@ -2671,6 +2700,10 @@ static int _find_some_parallel_space(str
|
|
continue;
|
|
|
|
case USE_AREA:
|
|
+ if(check_areas_separate_tags(ah, alloc_state, ix_offset,
|
|
+ ix + ix_offset, pva) >= 0)
|
|
+ goto next_pv;
|
|
+
|
|
/*
|
|
* Except with ALLOC_ANYWHERE, replace first area with this
|
|
* one which is smaller but still big enough.
|
|
@@ -3151,6 +3184,7 @@ static struct alloc_handle *_alloc_init(
|
|
ah->parity_count = parity_count;
|
|
ah->region_size = region_size;
|
|
ah->alloc = alloc;
|
|
+ ah->segtype = segtype;
|
|
|
|
/*
|
|
* For the purposes of allocation, area_count and parity_count are
|
|
@@ -3162,6 +3196,7 @@ static struct alloc_handle *_alloc_init(
|
|
ah->area_multiple = _calc_area_multiple(segtype, area_count + parity_count, stripes);
|
|
//FIXME: s/mirror_logs_separate/metadata_separate/ so it can be used by others?
|
|
ah->mirror_logs_separate = find_config_tree_bool(cmd, allocation_mirror_logs_require_separate_pvs_CFG, NULL);
|
|
+ ah->mirror_legs_separate = find_config_tree_bool(cmd, allocation_mirror_legs_require_separate_pvs_CFG, NULL);
|
|
|
|
if (mirrors || stripes)
|
|
total_extents = new_extents;
|
|
--- a/man/lvcreate.8.in
|
|
+++ b/man/lvcreate.8.in
|
|
@@ -333,6 +333,10 @@ Using \fIcore\fP means the mirror is reg
|
|
from the first device each time the logical volume is activated,
|
|
like after every reboot.
|
|
.br
|
|
+Every leg of the mirrored logical volume could be placed on the pvs with
|
|
+same tag, see details(mirror_legs_require_separate_pvs) in lvm.conf.
|
|
+
|
|
+.br
|
|
Using \fImirrored\fP will create a persistent log that is itself mirrored.
|
|
.TP
|
|
.BR \-\-monitor " {" \fIy | \fIn }
|