2014-01-09 17:38:13 +01:00
|
|
|
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>
|
|
|
|
---
|
2014-09-25 10:31:10 +02:00
|
|
|
conf/example.conf.in | 17 +++++++++++++++++
|
2015-06-08 03:48:46 +02:00
|
|
|
lib/config/config_settings.h | 3 +++
|
2014-09-25 10:31:10 +02:00
|
|
|
lib/config/defaults.h | 1 +
|
2015-06-08 03:48:46 +02:00
|
|
|
lib/metadata/lv_manip.c | 35 +++++++++++++++++++++++++++++++++++
|
2014-09-25 10:31:10 +02:00
|
|
|
man/lvcreate.8.in | 4 ++++
|
2015-06-08 03:48:46 +02:00
|
|
|
5 files changed, 60 insertions(+)
|
2014-01-09 17:38:13 +01:00
|
|
|
|
2016-09-14 11:43:37 +02:00
|
|
|
Index: LVM2.2.02.165/conf/example.conf.in
|
2016-01-28 05:41:36 +01:00
|
|
|
===================================================================
|
2016-09-14 11:43:37 +02:00
|
|
|
--- LVM2.2.02.165.orig/conf/example.conf.in
|
|
|
|
+++ LVM2.2.02.165/conf/example.conf.in
|
2016-09-07 08:55:17 +02:00
|
|
|
@@ -372,6 +372,23 @@ allocation {
|
2016-01-28 05:41:36 +01:00
|
|
|
# or erased unless the --wipesignatures option is used directly.
|
2015-06-08 03:48:46 +02:00
|
|
|
wipe_signatures_when_zeroing_new_lvs = 1
|
2014-01-09 17:38:13 +01:00
|
|
|
|
2015-06-08 03:48:46 +02:00
|
|
|
+ # 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.
|
2014-01-09 17:38:13 +01:00
|
|
|
+
|
2015-06-08 03:48:46 +02:00
|
|
|
+ # 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
|
2014-01-09 17:38:13 +01:00
|
|
|
+
|
2015-06-08 03:48:46 +02:00
|
|
|
# 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.
|
2016-09-14 11:43:37 +02:00
|
|
|
Index: LVM2.2.02.165/lib/config/config_settings.h
|
2016-01-28 05:41:36 +01:00
|
|
|
===================================================================
|
2016-09-14 11:43:37 +02:00
|
|
|
--- LVM2.2.02.165.orig/lib/config/config_settings.h
|
|
|
|
+++ LVM2.2.02.165/lib/config/config_settings.h
|
2016-09-07 08:55:17 +02:00
|
|
|
@@ -473,6 +473,9 @@ cfg(allocation_raid_stripe_all_devices_C
|
|
|
|
"when the command does not specify the number of stripes to use.\n"
|
|
|
|
"This was the default behaviour until release 2.02.162.\n")
|
2015-06-08 03:48:46 +02:00
|
|
|
|
|
|
|
+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")
|
|
|
|
|
2016-09-14 11:43:37 +02:00
|
|
|
Index: LVM2.2.02.165/lib/config/defaults.h
|
2016-01-28 05:41:36 +01:00
|
|
|
===================================================================
|
2016-09-14 11:43:37 +02:00
|
|
|
--- LVM2.2.02.165.orig/lib/config/defaults.h
|
|
|
|
+++ LVM2.2.02.165/lib/config/defaults.h
|
|
|
|
@@ -158,6 +158,7 @@
|
2014-01-09 17:38:13 +01:00
|
|
|
#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
|
|
|
|
|
2016-09-14 11:43:37 +02:00
|
|
|
Index: LVM2.2.02.165/lib/metadata/lv_manip.c
|
2016-01-28 05:41:36 +01:00
|
|
|
===================================================================
|
2016-09-14 11:43:37 +02:00
|
|
|
--- LVM2.2.02.165.orig/lib/metadata/lv_manip.c
|
|
|
|
+++ LVM2.2.02.165/lib/metadata/lv_manip.c
|
2016-09-07 08:55:17 +02:00
|
|
|
@@ -1519,6 +1519,9 @@ struct alloc_handle {
|
2014-01-09 17:38:13 +01:00
|
|
|
|
|
|
|
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
|
2016-09-14 11:43:37 +02:00
|
|
|
@@ -2633,6 +2636,32 @@ static int _limit_to_one_area_per_tag(st
|
2014-01-09 17:38:13 +01:00
|
|
|
}
|
2015-06-08 03:48:46 +02:00
|
|
|
|
|
|
|
/*
|
2014-01-09 17:38:13 +01:00
|
|
|
+ * 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,
|
2016-09-14 11:43:37 +02:00
|
|
|
+ pva->map->pv, 0))
|
2014-01-09 17:38:13 +01:00
|
|
|
+ return i;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
2015-06-08 03:48:46 +02:00
|
|
|
+/*
|
2014-01-09 17:38:13 +01:00
|
|
|
* Returns 1 regardless of whether any space was found, except on error.
|
|
|
|
*/
|
2015-06-08 03:48:46 +02:00
|
|
|
static int _find_some_parallel_space(struct alloc_handle *ah,
|
2016-09-14 11:43:37 +02:00
|
|
|
@@ -2762,6 +2791,10 @@ static int _find_some_parallel_space(str
|
2014-01-09 17:38:13 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
case USE_AREA:
|
2016-01-28 05:41:36 +01:00
|
|
|
+ if(check_areas_separate_tags(ah, alloc_state, alloc_state->num_positional_areas,
|
|
|
|
+ ix + alloc_state->num_positional_areas, pva) >= 0)
|
2014-01-09 17:38:13 +01:00
|
|
|
+ goto next_pv;
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* Except with ALLOC_ANYWHERE, replace first area with this
|
|
|
|
* one which is smaller but still big enough.
|
2016-09-14 11:43:37 +02:00
|
|
|
@@ -3243,6 +3276,7 @@ static struct alloc_handle *_alloc_init(
|
2015-06-08 03:48:46 +02:00
|
|
|
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
|
2016-09-14 11:43:37 +02:00
|
|
|
@@ -3254,6 +3288,7 @@ static struct alloc_handle *_alloc_init(
|
2015-06-08 03:48:46 +02:00
|
|
|
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;
|
2016-09-14 11:43:37 +02:00
|
|
|
Index: LVM2.2.02.165/man/lvcreate.8.in
|
2016-01-28 05:41:36 +01:00
|
|
|
===================================================================
|
2016-09-14 11:43:37 +02:00
|
|
|
--- LVM2.2.02.165.orig/man/lvcreate.8.in
|
|
|
|
+++ LVM2.2.02.165/man/lvcreate.8.in
|
2016-09-07 08:55:17 +02:00
|
|
|
@@ -418,6 +418,10 @@ Using \fBcore\fP means the mirror is reg
|
2014-12-04 07:08:29 +01:00
|
|
|
from the first device each time the logical volume is activated,
|
|
|
|
like after every reboot.
|
2015-06-08 03:48:46 +02:00
|
|
|
.br
|
2014-01-09 17:38:13 +01:00
|
|
|
+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.
|
|
|
|
+
|
2015-06-08 03:48:46 +02:00
|
|
|
+.br
|
2016-01-28 05:41:36 +01:00
|
|
|
Using \fBmirrored\fP will create a persistent log that is itself mirrored.
|
|
|
|
.
|
|
|
|
.HP
|