master - tests: add helper routine for pvmove status check
by okozina
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7c66850ce506d9...
Commit: 7c66850ce506d9a8bdae74f999a658507943d57c
Parent: c8caa04b1c58e1590654b405d1a6d34cd30c7b4f
Author: Ondrej Kozina <okozina(a)redhat.com>
AuthorDate: Fri Mar 27 14:24:16 2015 +0100
Committer: Ondrej Kozina <okozina(a)redhat.com>
CommitterDate: Mon Mar 30 18:38:50 2015 +0200
tests: add helper routine for pvmove status check
---
test/lib/aux.sh | 12 ++++++++++++
test/shell/pvmove-restart.sh | 7 ++-----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index cdd9a2d..b9f63b5 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -902,6 +902,18 @@ dmsetup_wrapped() {
dmsetup "$@"
}
+wait_pvmove_lv_ready() {
+ # given sleep .1 this is about 60 secs of waiting
+ local retries=${2:-600}
+ while : ; do
+ test $retries -le 0 && die "Waiting for pvmove LV to get activated has timed out"
+ dmsetup info -c -o tables_loaded $1 > out || true;
+ not grep Live out || break
+ sleep .1
+ retries=$((retries-1))
+ done
+}
+
test -z "$LVM_TEST_AUX_TRACE" || set -x
test -f DEVICES && devs=$(< DEVICES)
diff --git a/test/shell/pvmove-restart.sh b/test/shell/pvmove-restart.sh
index 06455f5..ca26779 100644
--- a/test/shell/pvmove-restart.sh
+++ b/test/shell/pvmove-restart.sh
@@ -34,11 +34,8 @@ aux delay_dev "$dev3" 0 200
pvmove -i0 -n $vg/$lv1 "$dev1" "$dev3" $mode &
PVMOVE=$!
# Let's wait a bit till pvmove starts and kill it
-while : ; do
- dmsetup info -c -o tables_loaded "$vg-pvmove0" > out || true;
- not grep Live out || break
- sleep .1
-done
+aux wait_pvmove_lv_ready "$vg-pvmove0" 300
+
kill -9 $PVMOVE
wait
9 years
master - tests: fix check for existence of a pvmove Lv
by okozina
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c8caa04b1c58e1...
Commit: c8caa04b1c58e1590654b405d1a6d34cd30c7b4f
Parent: f1e3e9916966a2ebdaf9315f929c1f34e326f6e0
Author: Ondrej Kozina <okozina(a)redhat.com>
AuthorDate: Fri Mar 27 15:42:11 2015 +0100
Committer: Ondrej Kozina <okozina(a)redhat.com>
CommitterDate: Mon Mar 30 18:38:50 2015 +0200
tests: fix check for existence of a pvmove Lv
---
test/shell/pvmove-basic.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/shell/pvmove-basic.sh b/test/shell/pvmove-basic.sh
index e5add05..1b9b63f 100644
--- a/test/shell/pvmove-basic.sh
+++ b/test/shell/pvmove-basic.sh
@@ -69,8 +69,8 @@ check_and_cleanup_lvs_() {
check dev_md5sum $vg $lv1
check dev_md5sum $vg $lv2
check dev_md5sum $vg $lv3
- get lv_field $vg name >out
- not grep ^pvmove out
+ get lv_field $vg name -a >out
+ not grep "^\[pvmove" out
vgchange -an $vg
lvremove -ff $vg
(dm_table | not grep $vg) || \
9 years
master - alloc: Log PV tags when reserving areas.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f1e3e9916966a2...
Commit: f1e3e9916966a2ebdaf9315f929c1f34e326f6e0
Parent: e8fa3354f09c137b14fe2d11f0892de5f7cedec6
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Mar 26 21:13:26 2015 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Mar 26 21:13:26 2015 +0000
alloc: Log PV tags when reserving areas.
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 80 +++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index f2d5b80..0a5d797 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.119 -
==================================
+ Log relevant PV tags when using cling allocation.
Add str_list_add_list() to combine two lists.
Fix LV processing with selection to always do the selection on initial state.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index b80bcae..11a46e1 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1976,15 +1976,24 @@ static int _is_same_pv(struct pv_match *pvmatch __attribute((unused)), struct pv
/*
* Does PV area have a tag listed in allocation/cling_tag_list that
* matches a tag of the PV of the existing segment?
+ * If tags_list_str is set, then instead we generate a list of matching tags for printing.
*/
static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
struct physical_volume *pv1,
struct physical_volume *pv2,
- unsigned validate_only)
+ unsigned validate_only,
+ struct dm_pool *mem, const char **tags_list_str)
{
const struct dm_config_value *cv;
const char *str;
const char *tag_matched;
+ struct dm_str_list *sl;
+ unsigned first_tag = 1;
+
+ if (tags_list_str && !dm_pool_begin_object(mem, 256)) {
+ log_error("PV tags string allocation failed");
+ return 0;
+ }
for (cv = cling_tag_list_cn->v; cv; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
@@ -2022,6 +2031,22 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
/* Wildcard matches any tag against any tag. */
if (!strcmp(str, "*")) {
+ if (tags_list_str) {
+ dm_list_iterate_items(sl, &pv1->tags) {
+ if (!first_tag && !dm_pool_grow_object(mem, ",", 0)) {
+ dm_pool_abandon_object(mem);
+ log_error("PV tags string extension failed.");
+ return 0;
+ }
+ first_tag = 0;
+ if (!dm_pool_grow_object(mem, sl->str, 0)) {
+ dm_pool_abandon_object(mem);
+ log_error("PV tags string extension failed.");
+ return 0;
+ }
+ }
+ continue;
+ }
if (!str_list_match_list(&pv1->tags, &pv2->tags, &tag_matched))
continue;
else {
@@ -2032,21 +2057,55 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
}
if (!str_list_match_item(&pv1->tags, str) ||
- !str_list_match_item(&pv2->tags, str))
+ (pv2 && !str_list_match_item(&pv2->tags, str)))
continue;
else {
+ if (tags_list_str) {
+ if (!first_tag && !dm_pool_grow_object(mem, ",", 0)) {
+ dm_pool_abandon_object(mem);
+ log_error("PV tags string extension failed.");
+ return 0;
+ }
+ first_tag = 0;
+ if (!dm_pool_grow_object(mem, str, 0)) {
+ dm_pool_abandon_object(mem);
+ log_error("PV tags string extension failed.");
+ return 0;
+ }
+ continue;
+ }
log_debug_alloc("Matched allocation PV tag %s on existing %s with free space on %s.",
str, pv_dev_name(pv1), pv_dev_name(pv2));
return 1;
}
}
+ if (tags_list_str) {
+ if (!dm_pool_grow_object(mem, "\0", 1)) {
+ dm_pool_abandon_object(mem);
+ log_error("PV tags string extension failed.");
+ return 0;
+ }
+ *tags_list_str = dm_pool_end_object(mem);
+ return 1;
+ }
+
return 0;
}
static int _validate_tag_list(const struct dm_config_node *cling_tag_list_cn)
{
- return _match_pv_tags(cling_tag_list_cn, NULL, NULL, 1);
+ return _match_pv_tags(cling_tag_list_cn, NULL, NULL, 1, NULL, NULL);
+}
+
+static const char *_tags_list_str(struct alloc_handle *ah, struct physical_volume *pv1)
+{
+ const char *tags_list_str;
+
+ if (!_match_pv_tags(ah->cling_tag_list_cn, pv1, NULL, 0, ah->mem, &tags_list_str))
+ return_NULL;
+
+ return tags_list_str;
}
/*
@@ -2056,7 +2115,7 @@ static int _validate_tag_list(const struct dm_config_node *cling_tag_list_cn)
static int _pvs_have_matching_tag(const struct dm_config_node *cling_tag_list_cn,
struct physical_volume *pv1, struct physical_volume *pv2)
{
- return _match_pv_tags(cling_tag_list_cn, pv1, pv2, 0);
+ return _match_pv_tags(cling_tag_list_cn, pv1, pv2, 0, NULL, NULL);
}
static int _has_matching_pv_tag(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva)
@@ -2082,12 +2141,21 @@ static void _reserve_area(struct alloc_handle *ah, struct alloc_state *alloc_sta
uint32_t required, uint32_t ix_pva, uint32_t unreserved)
{
struct pv_area_used *area_used = &alloc_state->areas[ix_pva];
+ const char *pv_tag_list = NULL;
+
+ if (ah->cling_tag_list_cn)
+ pv_tag_list = _tags_list_str(ah, pva->map->pv);
log_debug_alloc("%s allocation area %" PRIu32 " %s %s start PE %" PRIu32
- " length %" PRIu32 " leaving %" PRIu32 ".",
+ " length %" PRIu32 " leaving %" PRIu32 "%s%s.",
area_used->pva ? "Changing " : "Considering",
ix_pva, area_used->pva ? "to" : "as",
- dev_name(pva->map->pv->dev), pva->start, required, unreserved);
+ dev_name(pva->map->pv->dev), pva->start, required, unreserved,
+ pv_tag_list ? " with PV tags: " : "",
+ pv_tag_list ? : "");
+
+ if (pv_tag_list)
+ dm_pool_free(ah->mem, (void *)pv_tag_list);
area_used->pva = pva;
area_used->used = required;
9 years
master - alloc: Pass alloc_handle through to _reserve_area.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e8fa3354f09c13...
Commit: e8fa3354f09c137b14fe2d11f0892de5f7cedec6
Parent: f9d74ba3d1601e55da48e34a3a9d7587d0ec3fe4
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Mar 26 20:32:59 2015 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Mar 26 20:32:59 2015 +0000
alloc: Pass alloc_handle through to _reserve_area.
---
lib/metadata/lv_manip.c | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 67f5f91..b80bcae 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1955,6 +1955,7 @@ static int _comp_area(const void *l, const void *r)
struct pv_match {
int (*condition)(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva);
+ struct alloc_handle *ah;
struct alloc_state *alloc_state;
struct pv_area *pva;
const struct dm_config_node *cling_tag_list_cn;
@@ -2077,8 +2078,8 @@ static int _is_contiguous(struct pv_match *pvmatch __attribute((unused)), struct
return 1;
}
-static void _reserve_area(struct alloc_state *alloc_state, struct pv_area *pva, uint32_t required,
- uint32_t ix_pva, uint32_t unreserved)
+static void _reserve_area(struct alloc_handle *ah, struct alloc_state *alloc_state, struct pv_area *pva,
+ uint32_t required, uint32_t ix_pva, uint32_t unreserved)
{
struct pv_area_used *area_used = &alloc_state->areas[ix_pva];
@@ -2092,8 +2093,8 @@ static void _reserve_area(struct alloc_state *alloc_state, struct pv_area *pva,
area_used->used = required;
}
-static int _reserve_required_area(struct alloc_state *alloc_state, struct pv_area *pva, uint32_t required,
- uint32_t ix_pva, uint32_t unreserved)
+static int _reserve_required_area(struct alloc_handle *ah, struct alloc_state *alloc_state, struct pv_area *pva,
+ uint32_t required, uint32_t ix_pva, uint32_t unreserved)
{
uint32_t s;
@@ -2108,7 +2109,7 @@ static int _reserve_required_area(struct alloc_state *alloc_state, struct pv_are
alloc_state->areas[s].pva = NULL;
}
- _reserve_area(alloc_state, pva, required, ix_pva, unreserved);
+ _reserve_area(ah, alloc_state, pva, required, ix_pva, unreserved);
return 1;
}
@@ -2134,7 +2135,7 @@ static int _is_condition(struct cmd_context *cmd __attribute__((unused)),
* so it's safe to say all the available space is used.
*/
if (positional)
- _reserve_required_area(pvmatch->alloc_state, pvmatch->pva, pvmatch->pva->count, s, 0);
+ _reserve_required_area(pvmatch->ah, pvmatch->alloc_state, pvmatch->pva, pvmatch->pva->count, s, 0);
return 2; /* Finished */
}
@@ -2151,6 +2152,7 @@ static int _check_cling(struct alloc_handle *ah,
int r;
uint32_t le, len;
+ pvmatch.ah = ah;
pvmatch.condition = cling_tag_list_cn ? _has_matching_pv_tag : _is_same_pv;
pvmatch.alloc_state = alloc_state;
pvmatch.pva = pva;
@@ -2181,20 +2183,21 @@ static int _check_cling(struct alloc_handle *ah,
/*
* Is pva contiguous to any existing areas or on the same PV?
*/
-static int _check_contiguous(struct cmd_context *cmd,
+static int _check_contiguous(struct alloc_handle *ah,
struct lv_segment *prev_lvseg, struct pv_area *pva,
struct alloc_state *alloc_state)
{
struct pv_match pvmatch;
int r;
+ pvmatch.ah = ah;
pvmatch.condition = _is_contiguous;
pvmatch.alloc_state = alloc_state;
pvmatch.pva = pva;
pvmatch.cling_tag_list_cn = NULL;
/* FIXME Cope with stacks by flattening */
- if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
+ if (!(r = _for_each_pv(ah->cmd, prev_lvseg->lv,
prev_lvseg->le + prev_lvseg->len - 1, 1, NULL, NULL,
0, 0, -1, 1,
_is_condition, &pvmatch)))
@@ -2230,7 +2233,7 @@ static int _check_cling_to_alloced(struct alloc_handle *ah, const struct dm_conf
if ((!cling_tag_list_cn && (pva->map->pv == aa[0].pv)) ||
(cling_tag_list_cn && _pvs_have_matching_tag(cling_tag_list_cn, pva->map->pv, aa[0].pv))) {
if (positional)
- _reserve_required_area(alloc_state, pva, pva->count, s, 0);
+ _reserve_required_area(ah, alloc_state, pva, pva->count, s, 0);
return 1;
}
}
@@ -2279,7 +2282,7 @@ static area_use_t _check_pva(struct alloc_handle *ah, struct pv_area *pva, uint3
/* Contiguous? */
if (((alloc_parms->flags & A_CONTIGUOUS_TO_LVSEG) ||
(ah->maximise_cling && (alloc_parms->flags & A_AREA_COUNT_MATCHES))) &&
- _check_contiguous(ah->cmd, alloc_parms->prev_lvseg, pva, alloc_state))
+ _check_contiguous(ah, alloc_parms->prev_lvseg, pva, alloc_state))
goto found;
/* Try next area on same PV if looking for contiguous space */
@@ -2556,7 +2559,7 @@ static int _find_some_parallel_space(struct alloc_handle *ah,
/* Reserve required amount of pva */
required = _calc_required_extents(ah, pva, ix + ix_offset - 1, max_to_allocate, alloc_parms->alloc);
- if (!_reserve_required_area(alloc_state, pva, required, ix + ix_offset - 1, pva->unreserved))
+ if (!_reserve_required_area(ah, alloc_state, pva, required, ix + ix_offset - 1, pva->unreserved))
return_0;
}
9 years
master - alloc: Only report cling tag errors once.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f9d74ba3d1601e...
Commit: f9d74ba3d1601e55da48e34a3a9d7587d0ec3fe4
Parent: 4b1219ee876b5a27e9fa08a1153632dda0f8efd1
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Mar 26 19:43:51 2015 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Mar 26 19:43:51 2015 +0000
alloc: Only report cling tag errors once.
---
lib/metadata/lv_manip.c | 46 ++++++++++++++++++++++++++++++++++++----------
1 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 2b6855a..67f5f91 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1976,7 +1976,10 @@ static int _is_same_pv(struct pv_match *pvmatch __attribute((unused)), struct pv
* Does PV area have a tag listed in allocation/cling_tag_list that
* matches a tag of the PV of the existing segment?
*/
-static int _pvs_have_matching_tag(const struct dm_config_node *cling_tag_list_cn, struct physical_volume *pv1, struct physical_volume *pv2)
+static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
+ struct physical_volume *pv1,
+ struct physical_volume *pv2,
+ unsigned validate_only)
{
const struct dm_config_value *cv;
const char *str;
@@ -1984,31 +1987,38 @@ static int _pvs_have_matching_tag(const struct dm_config_node *cling_tag_list_cn
for (cv = cling_tag_list_cn->v; cv; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
- log_error("Ignoring invalid string in config file entry "
- "allocation/cling_tag_list");
+ if (validate_only)
+ log_warn("WARNING: Ignoring invalid string in config file entry "
+ "allocation/cling_tag_list");
continue;
}
str = cv->v.str;
if (!*str) {
- log_error("Ignoring empty string in config file entry "
- "allocation/cling_tag_list");
+ if (validate_only)
+ log_warn("WARNING: Ignoring empty string in config file entry "
+ "allocation/cling_tag_list");
continue;
}
if (*str != '@') {
- log_error("Ignoring string not starting with @ in config file entry "
- "allocation/cling_tag_list: %s", str);
+ if (validate_only)
+ log_warn("WARNING: Ignoring string not starting with @ in config file entry "
+ "allocation/cling_tag_list: %s", str);
continue;
}
str++;
if (!*str) {
- log_error("Ignoring empty tag in config file entry "
- "allocation/cling_tag_list");
+ if (validate_only)
+ log_warn("WARNING: Ignoring empty tag in config file entry "
+ "allocation/cling_tag_list");
continue;
}
+ if (validate_only)
+ continue;
+
/* Wildcard matches any tag against any tag. */
if (!strcmp(str, "*")) {
if (!str_list_match_list(&pv1->tags, &pv2->tags, &tag_matched))
@@ -2033,6 +2043,21 @@ static int _pvs_have_matching_tag(const struct dm_config_node *cling_tag_list_cn
return 0;
}
+static int _validate_tag_list(const struct dm_config_node *cling_tag_list_cn)
+{
+ return _match_pv_tags(cling_tag_list_cn, NULL, NULL, 1);
+}
+
+/*
+ * Does PV area have a tag listed in allocation/cling_tag_list that
+ * matches a tag of the PV of the existing segment?
+ */
+static int _pvs_have_matching_tag(const struct dm_config_node *cling_tag_list_cn,
+ struct physical_volume *pv1, struct physical_volume *pv2)
+{
+ return _match_pv_tags(cling_tag_list_cn, pv1, pv2, 0);
+}
+
static int _has_matching_pv_tag(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva)
{
return _pvs_have_matching_tag(pvmatch->cling_tag_list_cn, pvseg->pv, pva->map->pv);
@@ -3043,7 +3068,8 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
ah->parallel_areas = parallel_areas;
- ah->cling_tag_list_cn = find_config_tree_node(cmd, allocation_cling_tag_list_CFG, NULL);
+ if ((ah->cling_tag_list_cn = find_config_tree_node(cmd, allocation_cling_tag_list_CFG, NULL)))
+ (void) _validate_tag_list(ah->cling_tag_list_cn);
ah->maximise_cling = find_config_tree_bool(cmd, allocation_maximise_cling_CFG, NULL);
9 years
master - metadata: Move alloc_handle init/destroy fns.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4b1219ee876b5a...
Commit: 4b1219ee876b5a27e9fa08a1153632dda0f8efd1
Parent: 9506760c7ec86448e54803a74ade58d24d975ff1
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Mar 26 18:44:24 2015 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Mar 26 18:44:24 2015 +0000
metadata: Move alloc_handle init/destroy fns.
---
lib/metadata/lv_manip.c | 362 +++++++++++++++++++++++-----------------------
1 files changed, 181 insertions(+), 181 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 99fb91f..2b6855a 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1553,187 +1553,6 @@ static uint32_t mirror_log_extents(uint32_t region_size, uint32_t pe_size, uint3
(region_size / pe_size);
}
-/*
- * Preparation for a specific allocation attempt
- * stripes and mirrors refer to the parallel areas used for data.
- * If log_area_count > 1 it is always mirrored (not striped).
- */
-static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
- struct dm_pool *mem,
- const struct segment_type *segtype,
- alloc_policy_t alloc, int approx_alloc,
- uint32_t existing_extents,
- uint32_t new_extents,
- uint32_t mirrors,
- uint32_t stripes,
- uint32_t metadata_area_count,
- uint32_t extent_size,
- uint32_t region_size,
- struct dm_list *parallel_areas)
-{
- struct alloc_handle *ah;
- uint32_t s, area_count, alloc_count, parity_count, total_extents;
- size_t size = 0;
-
- /* FIXME Caller should ensure this */
- if (mirrors && !stripes)
- stripes = 1;
-
- if (segtype_is_virtual(segtype))
- area_count = 0;
- else if (mirrors > 1)
- area_count = mirrors * stripes;
- else
- area_count = stripes;
-
- size = sizeof(*ah);
-
- /*
- * It is a requirement that RAID 4/5/6 are created with a number of
- * stripes that is greater than the number of parity devices. (e.g
- * RAID4/5 must have at least 2 stripes and RAID6 must have at least
- * 3.) It is also a constraint that, when replacing individual devices
- * in a RAID 4/5/6 array, no more devices can be replaced than
- * there are parity devices. (Otherwise, there would not be enough
- * redundancy to maintain the array.) Understanding these two
- * constraints allows us to infer whether the caller of this function
- * is intending to allocate an entire array or just replacement
- * component devices. In the former case, we must account for the
- * necessary parity_count. In the later case, we do not need to
- * account for the extra parity devices because the array already
- * exists and they only want replacement drives.
- */
- parity_count = (area_count <= segtype->parity_devs) ? 0 : segtype->parity_devs;
- alloc_count = area_count + parity_count;
- if (segtype_is_raid(segtype) && metadata_area_count)
- /* RAID has a meta area for each device */
- alloc_count *= 2;
- else
- /* mirrors specify their exact log count */
- alloc_count += metadata_area_count;
-
- size += sizeof(ah->alloced_areas[0]) * alloc_count;
-
- if (!(ah = dm_pool_zalloc(mem, size))) {
- log_error("allocation handle allocation failed");
- return NULL;
- }
-
- ah->cmd = cmd;
-
- if (segtype_is_virtual(segtype))
- return ah;
-
- if (!(area_count + metadata_area_count)) {
- log_error(INTERNAL_ERROR "_alloc_init called for non-virtual segment with no disk space.");
- return NULL;
- }
-
- if (!(ah->mem = dm_pool_create("allocation", 1024))) {
- log_error("allocation pool creation failed");
- return NULL;
- }
-
- ah->area_count = area_count;
- ah->parity_count = parity_count;
- ah->region_size = region_size;
- ah->alloc = alloc;
-
- /*
- * For the purposes of allocation, area_count and parity_count are
- * kept separately. However, the 'area_count' field in an
- * lv_segment includes both; and this is what '_calc_area_multiple'
- * is calculated from. So, we must pass in the total count to get
- * a correct area_multiple.
- */
- 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);
-
- if (mirrors || stripes)
- total_extents = new_extents;
- else
- total_extents = 0;
-
- if (segtype_is_raid(segtype)) {
- if (metadata_area_count) {
- if (metadata_area_count != area_count)
- log_error(INTERNAL_ERROR
- "Bad metadata_area_count");
- ah->metadata_area_count = area_count;
- ah->alloc_and_split_meta = 1;
-
- ah->log_len = RAID_METADATA_AREA_LEN;
-
- /*
- * We need 'log_len' extents for each
- * RAID device's metadata_area
- */
- total_extents += (ah->log_len * ah->area_multiple);
- } else {
- ah->log_area_count = 0;
- ah->log_len = 0;
- }
- } else if (segtype_is_thin_pool(segtype)) {
- /*
- * thin_pool uses ah->region_size to
- * pass metadata size in extents
- */
- ah->log_len = ah->region_size;
- ah->log_area_count = metadata_area_count;
- ah->region_size = 0;
- ah->mirror_logs_separate =
- find_config_tree_bool(cmd, allocation_thin_pool_metadata_require_separate_pvs_CFG, NULL);
- } else if (segtype_is_cache_pool(segtype)) {
- /*
- * Like thin_pool, cache_pool uses ah->region_size to
- * pass metadata size in extents
- */
- ah->log_len = ah->region_size;
- /* use metadata_area_count, not log_area_count */
- ah->metadata_area_count = metadata_area_count;
- ah->region_size = 0;
- ah->mirror_logs_separate =
- find_config_tree_bool(cmd, allocation_cache_pool_metadata_require_separate_pvs_CFG, NULL);
- if (!ah->mirror_logs_separate) {
- ah->alloc_and_split_meta = 1;
- total_extents += ah->log_len;
- }
- } else {
- ah->log_area_count = metadata_area_count;
- ah->log_len = !metadata_area_count ? 0 :
- mirror_log_extents(ah->region_size, extent_size,
- (existing_extents + total_extents) / ah->area_multiple);
- }
-
- log_debug("Adjusted allocation request to %" PRIu32 " logical extents. Existing size %" PRIu32 ". New size %" PRIu32 ".",
- total_extents, existing_extents, total_extents + existing_extents);
-
- if (mirrors || stripes)
- total_extents += existing_extents;
-
- ah->new_extents = total_extents;
-
- for (s = 0; s < alloc_count; s++)
- dm_list_init(&ah->alloced_areas[s]);
-
- ah->parallel_areas = parallel_areas;
-
- ah->cling_tag_list_cn = find_config_tree_node(cmd, allocation_cling_tag_list_CFG, NULL);
-
- ah->maximise_cling = find_config_tree_bool(cmd, allocation_maximise_cling_CFG, NULL);
-
- ah->approx_alloc = approx_alloc;
-
- return ah;
-}
-
-void alloc_destroy(struct alloc_handle *ah)
-{
- if (ah->mem)
- dm_pool_destroy(ah->mem);
-}
-
/* Is there enough total space or should we give up immediately? */
static int _sufficient_pes_free(struct alloc_handle *ah, struct dm_list *pvms,
uint32_t allocated, uint32_t extents_still_needed)
@@ -3059,6 +2878,187 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
}
/*
+ * Preparation for a specific allocation attempt
+ * stripes and mirrors refer to the parallel areas used for data.
+ * If log_area_count > 1 it is always mirrored (not striped).
+ */
+static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
+ struct dm_pool *mem,
+ const struct segment_type *segtype,
+ alloc_policy_t alloc, int approx_alloc,
+ uint32_t existing_extents,
+ uint32_t new_extents,
+ uint32_t mirrors,
+ uint32_t stripes,
+ uint32_t metadata_area_count,
+ uint32_t extent_size,
+ uint32_t region_size,
+ struct dm_list *parallel_areas)
+{
+ struct alloc_handle *ah;
+ uint32_t s, area_count, alloc_count, parity_count, total_extents;
+ size_t size = 0;
+
+ /* FIXME Caller should ensure this */
+ if (mirrors && !stripes)
+ stripes = 1;
+
+ if (segtype_is_virtual(segtype))
+ area_count = 0;
+ else if (mirrors > 1)
+ area_count = mirrors * stripes;
+ else
+ area_count = stripes;
+
+ size = sizeof(*ah);
+
+ /*
+ * It is a requirement that RAID 4/5/6 are created with a number of
+ * stripes that is greater than the number of parity devices. (e.g
+ * RAID4/5 must have at least 2 stripes and RAID6 must have at least
+ * 3.) It is also a constraint that, when replacing individual devices
+ * in a RAID 4/5/6 array, no more devices can be replaced than
+ * there are parity devices. (Otherwise, there would not be enough
+ * redundancy to maintain the array.) Understanding these two
+ * constraints allows us to infer whether the caller of this function
+ * is intending to allocate an entire array or just replacement
+ * component devices. In the former case, we must account for the
+ * necessary parity_count. In the later case, we do not need to
+ * account for the extra parity devices because the array already
+ * exists and they only want replacement drives.
+ */
+ parity_count = (area_count <= segtype->parity_devs) ? 0 : segtype->parity_devs;
+ alloc_count = area_count + parity_count;
+ if (segtype_is_raid(segtype) && metadata_area_count)
+ /* RAID has a meta area for each device */
+ alloc_count *= 2;
+ else
+ /* mirrors specify their exact log count */
+ alloc_count += metadata_area_count;
+
+ size += sizeof(ah->alloced_areas[0]) * alloc_count;
+
+ if (!(ah = dm_pool_zalloc(mem, size))) {
+ log_error("allocation handle allocation failed");
+ return NULL;
+ }
+
+ ah->cmd = cmd;
+
+ if (segtype_is_virtual(segtype))
+ return ah;
+
+ if (!(area_count + metadata_area_count)) {
+ log_error(INTERNAL_ERROR "_alloc_init called for non-virtual segment with no disk space.");
+ return NULL;
+ }
+
+ if (!(ah->mem = dm_pool_create("allocation", 1024))) {
+ log_error("allocation pool creation failed");
+ return NULL;
+ }
+
+ ah->area_count = area_count;
+ ah->parity_count = parity_count;
+ ah->region_size = region_size;
+ ah->alloc = alloc;
+
+ /*
+ * For the purposes of allocation, area_count and parity_count are
+ * kept separately. However, the 'area_count' field in an
+ * lv_segment includes both; and this is what '_calc_area_multiple'
+ * is calculated from. So, we must pass in the total count to get
+ * a correct area_multiple.
+ */
+ 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);
+
+ if (mirrors || stripes)
+ total_extents = new_extents;
+ else
+ total_extents = 0;
+
+ if (segtype_is_raid(segtype)) {
+ if (metadata_area_count) {
+ if (metadata_area_count != area_count)
+ log_error(INTERNAL_ERROR
+ "Bad metadata_area_count");
+ ah->metadata_area_count = area_count;
+ ah->alloc_and_split_meta = 1;
+
+ ah->log_len = RAID_METADATA_AREA_LEN;
+
+ /*
+ * We need 'log_len' extents for each
+ * RAID device's metadata_area
+ */
+ total_extents += (ah->log_len * ah->area_multiple);
+ } else {
+ ah->log_area_count = 0;
+ ah->log_len = 0;
+ }
+ } else if (segtype_is_thin_pool(segtype)) {
+ /*
+ * thin_pool uses ah->region_size to
+ * pass metadata size in extents
+ */
+ ah->log_len = ah->region_size;
+ ah->log_area_count = metadata_area_count;
+ ah->region_size = 0;
+ ah->mirror_logs_separate =
+ find_config_tree_bool(cmd, allocation_thin_pool_metadata_require_separate_pvs_CFG, NULL);
+ } else if (segtype_is_cache_pool(segtype)) {
+ /*
+ * Like thin_pool, cache_pool uses ah->region_size to
+ * pass metadata size in extents
+ */
+ ah->log_len = ah->region_size;
+ /* use metadata_area_count, not log_area_count */
+ ah->metadata_area_count = metadata_area_count;
+ ah->region_size = 0;
+ ah->mirror_logs_separate =
+ find_config_tree_bool(cmd, allocation_cache_pool_metadata_require_separate_pvs_CFG, NULL);
+ if (!ah->mirror_logs_separate) {
+ ah->alloc_and_split_meta = 1;
+ total_extents += ah->log_len;
+ }
+ } else {
+ ah->log_area_count = metadata_area_count;
+ ah->log_len = !metadata_area_count ? 0 :
+ mirror_log_extents(ah->region_size, extent_size,
+ (existing_extents + total_extents) / ah->area_multiple);
+ }
+
+ log_debug("Adjusted allocation request to %" PRIu32 " logical extents. Existing size %" PRIu32 ". New size %" PRIu32 ".",
+ total_extents, existing_extents, total_extents + existing_extents);
+
+ if (mirrors || stripes)
+ total_extents += existing_extents;
+
+ ah->new_extents = total_extents;
+
+ for (s = 0; s < alloc_count; s++)
+ dm_list_init(&ah->alloced_areas[s]);
+
+ ah->parallel_areas = parallel_areas;
+
+ ah->cling_tag_list_cn = find_config_tree_node(cmd, allocation_cling_tag_list_CFG, NULL);
+
+ ah->maximise_cling = find_config_tree_bool(cmd, allocation_maximise_cling_CFG, NULL);
+
+ ah->approx_alloc = approx_alloc;
+
+ return ah;
+}
+
+void alloc_destroy(struct alloc_handle *ah)
+{
+ if (ah->mem)
+ dm_pool_destroy(ah->mem);
+}
+
+/*
* Entry point for all extent allocations.
*/
struct alloc_handle *allocate_extents(struct volume_group *vg,
9 years
master - datastruct: Add str_list_add_list.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9506760c7ec864...
Commit: 9506760c7ec86448e54803a74ade58d24d975ff1
Parent: 8a87fadbb026ca121c8af8669e68673aece46eb2
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Mar 26 18:30:37 2015 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Mar 26 18:30:37 2015 +0000
datastruct: Add str_list_add_list.
---
WHATS_NEW | 1 +
lib/datastruct/str_list.c | 15 +++++++++++++++
lib/datastruct/str_list.h | 1 +
3 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 4010e67..f2d5b80 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.119 -
==================================
+ Add str_list_add_list() to combine two lists.
Fix LV processing with selection to always do the selection on initial state.
Version 2.02.118 - 23rd March 2015
diff --git a/lib/datastruct/str_list.c b/lib/datastruct/str_list.c
index feec8b6..1d3f08a 100644
--- a/lib/datastruct/str_list.c
+++ b/lib/datastruct/str_list.c
@@ -71,6 +71,21 @@ int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str)
return str_list_add_no_dup_check(mem, sll, str);
}
+/* Add contents of sll2 to sll */
+int str_list_add_list(struct dm_pool *mem, struct dm_list *sll, struct dm_list *sll2)
+{
+ struct dm_str_list *sl;
+
+ if (!sll2)
+ return_0;
+
+ dm_list_iterate_items(sl, sll2)
+ if (!str_list_add(mem, sll, sl->str))
+ return_0;
+
+ return 1;
+}
+
void str_list_del(struct dm_list *sll, const char *str)
{
struct dm_list *slh, *slht;
diff --git a/lib/datastruct/str_list.h b/lib/datastruct/str_list.h
index 0046fe4..3121a28 100644
--- a/lib/datastruct/str_list.h
+++ b/lib/datastruct/str_list.h
@@ -21,6 +21,7 @@ struct dm_pool;
struct dm_list *str_list_create(struct dm_pool *mem);
int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str);
+int str_list_add_list(struct dm_pool *mem, struct dm_list *sll, struct dm_list *sll2);
int str_list_add_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str);
int str_list_add_h_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str);
void str_list_del(struct dm_list *sll, const char *str);
9 years
master - tests: drop vg2 at end of test
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8a87fadbb026ca...
Commit: 8a87fadbb026ca121c8af8669e68673aece46eb2
Parent: 22d43ee14a1a9700b76960da2c983ff55cc3630c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 26 16:11:29 2015 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Mar 26 16:11:29 2015 +0100
tests: drop vg2 at end of test
---
test/shell/select-tools.sh | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/test/shell/select-tools.sh b/test/shell/select-tools.sh
index d04ed0a..b9e4b2f 100644
--- a/test/shell/select-tools.sh
+++ b/test/shell/select-tools.sh
@@ -273,3 +273,4 @@ pvchange -a --deltag 309 --deltag tag
# iterates over LVs with process_each_lv_in_vg - so internally it actually
# operates per-LV, but we still need the selection to be done per-VG)
vgremove --yes -S 'lv_name=lv2' # should remove whole vg1, not just the lv2
+vgremove --yes $vg2
9 years
master - tests: skip system_id test in cluster
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=22d43ee14a1a97...
Commit: 22d43ee14a1a9700b76960da2c983ff55cc3630c
Parent: 147b0a17005f632647b31394dda402483322ccad
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 26 16:10:48 2015 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Mar 26 16:10:48 2015 +0100
tests: skip system_id test in cluster
Let's see what we can do in cluster for system_id,
until resolved skip test for check_cluster.
---
test/shell/system_id.sh | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/test/shell/system_id.sh b/test/shell/system_id.sh
index d866675..ad8871a 100644
--- a/test/shell/system_id.sh
+++ b/test/shell/system_id.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2008-2013 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
@@ -13,6 +13,9 @@ test_description='Test system_id'
. lib/inittest
+# Should 'system_id' be usable in cluster ??
+test -e LOCAL_CLVMD && skip
+
aux prepare_devs 1
# create vg with system_id using each source
9 years
master - tests: pvmove better delay check
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=147b0a17005f63...
Commit: 147b0a17005f632647b31394dda402483322ccad
Parent: d24b6cfb1ff1f29eec49c3113f8cef9904cf4a8b
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 26 16:03:24 2015 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Mar 26 16:03:24 2015 +0100
tests: pvmove better delay check
Improve testing for condition that pvmove0 is already running in the
table (so we do not kill pvmove while it has loaded target, but
it's not yet Live).
Also delay_dev for 200ms.
---
test/shell/lvresize-rounding.sh | 1 -
test/shell/pvmove-restart.sh | 10 +++++++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/test/shell/lvresize-rounding.sh b/test/shell/lvresize-rounding.sh
index 24ca00b..5c30539 100644
--- a/test/shell/lvresize-rounding.sh
+++ b/test/shell/lvresize-rounding.sh
@@ -11,7 +11,6 @@
. lib/inittest
-# 15 extents
aux prepare_pvs 3 22
vgcreate -s 32K $vg $(cat DEVICES)
diff --git a/test/shell/pvmove-restart.sh b/test/shell/pvmove-restart.sh
index 022e7c8..06455f5 100644
--- a/test/shell/pvmove-restart.sh
+++ b/test/shell/pvmove-restart.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2013-2015 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
@@ -29,12 +29,16 @@ lvextend -l+5 $vg/$lv1 "$dev1"
lvextend -l+10 $vg/$lv1 "$dev2"
# Slowdown writes
-aux delay_dev "$dev3" 0 100
+aux delay_dev "$dev3" 0 200
pvmove -i0 -n $vg/$lv1 "$dev1" "$dev3" $mode &
PVMOVE=$!
# Let's wait a bit till pvmove starts and kill it
-while not dmsetup status "$vg-pvmove0"; do sleep .1; done
+while : ; do
+ dmsetup info -c -o tables_loaded "$vg-pvmove0" > out || true;
+ not grep Live out || break
+ sleep .1
+done
kill -9 $PVMOVE
wait
9 years