97abc4b700
- Update to 2.02.114 - Removed cmirrord-fix-s390-endian-issue.patch - Renumbered patches to allow for upstream patches to be applied before local ones. OBS-URL: https://build.opensuse.org/request/show/263775 OBS-URL: https://build.opensuse.org/package/show/Base:System/lvm2?expand=0&rev=111
160 lines
6.6 KiB
Diff
160 lines
6.6 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 | 1 +
|
|
lib/config/defaults.h | 1 +
|
|
lib/metadata/lv_manip.c | 36 ++++++++++++++++++++++++++++++++++++
|
|
man/lvcreate.8.in | 4 ++++
|
|
5 files changed, 59 insertions(+)
|
|
|
|
--- a/conf/example.conf.in
|
|
+++ b/conf/example.conf.in
|
|
@@ -315,6 +315,23 @@ allocation {
|
|
#
|
|
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
|
|
+
|
|
# Set to 1 to guarantee that mirror logs will always be placed on
|
|
# different PVs from the mirror images. This was the default
|
|
# until version 2.02.85.
|
|
--- a/lib/config/config_settings.h
|
|
+++ b/lib/config/config_settings.h
|
|
@@ -119,6 +119,7 @@ cfg(allocation_maximise_cling_CFG, "maxi
|
|
cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 105), NULL)
|
|
cfg(allocation_wipe_signatures_when_zeroing_new_lvs_CFG, "wipe_signatures_when_zeroing_new_lvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 105), NULL)
|
|
cfg(allocation_mirror_logs_require_separate_pvs_CFG, "mirror_logs_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS, vsn(2, 2, 85), NULL)
|
|
+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)
|
|
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)
|
|
cfg(allocation_cache_pool_cachemode_CFG, "cache_pool_cachemode", allocation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_CACHE_POOL_CACHEMODE, vsn(2, 2, 113), NULL)
|
|
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), NULL)
|
|
--- a/lib/config/defaults.h
|
|
+++ b/lib/config/defaults.h
|
|
@@ -125,6 +125,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
|
|
@@ -1409,6 +1409,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
|
|
@@ -1598,6 +1601,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
|
|
@@ -1609,6 +1613,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;
|
|
@@ -2533,6 +2538,33 @@ static void _report_needed_allocation_sp
|
|
(metadata_count == 1) ? "" : "s",
|
|
metadata_size);
|
|
}
|
|
+
|
|
+/*
|
|
+ * 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.
|
|
*/
|
|
@@ -2663,6 +2695,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.
|
|
--- a/man/lvcreate.8.in
|
|
+++ b/man/lvcreate.8.in
|
|
@@ -284,6 +284,10 @@ will create a persistent log that is its
|
|
Using \fIcore\fP means the mirror is regenerated by copying the data
|
|
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
|