master - test: for issue fixed in previous commit 2f7f6932dcd450ba75fe590aba8c09838d2618dc
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7049eeeb839b59...
Commit: 7049eeeb839b59314d07c0bac250c89cf8ac78f8
Parent: 2f7f6932dcd450ba75fe590aba8c09838d2618dc
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Oct 27 11:53:01 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Oct 27 11:53:01 2014 +0100
test: for issue fixed in previous commit 2f7f6932dcd450ba75fe590aba8c09838d2618dc
---
test/shell/report-select.sh | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/test/shell/report-select.sh b/test/shell/report-select.sh
index 11a4efd..70e5366 100644
--- a/test/shell/report-select.sh
+++ b/test/shell/report-select.sh
@@ -183,6 +183,11 @@ lvs_sel 'name="vol1"' "vol1"
# check reserved values are accepted for certain fields as well as usual values
vgs_sel 'vg_mda_copies=unmanaged' "$vg2 $vg3"
vgs_sel 'vg_mda_copies=2' "$vg1"
+# also, we must match only vg1, not including vg2 and vg3
+# when comparing ranges - unamanged is mapped onto 2^64 - 1 internally,
+# so we need to skip this internal value if it matches with selection criteria!
+vgs_sel 'vg_mda_copies>=2' "$vg1"
+not vgs_sel 'vg_mda_copies=18446744073709551615'
lvs_sel 'lv_read_ahead=auto' "vol1 vol2 orig snap"
lvs_sel 'lv_read_ahead=256k' "abc xyz"
8 years, 11 months
master - report: selection: fix selection criteria to not match reserved values when using >, <, >=, <
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=2f7f6932dcd450...
Commit: 2f7f6932dcd450ba75fe590aba8c09838d2618dc
Parent: e223c801fc3eb12c2a4502aee471f18a0b903de8
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Oct 27 11:25:08 2014 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Oct 27 11:25:08 2014 +0100
report: selection: fix selection criteria to not match reserved values when using >, <, >=, <
Some values are reserved for special purpose like 'undefined', 'unmanaged' etc.
When using >, <, >= and < comparison operators where the range is considered,
do not include reserved values as proper values in this range which
would otherwise result in not so obvious criteria match (as the reserved value is
actually transparent for the user). It's incorrect.
Example scenario:
$ vgs -o vg_name,vg_mda_copies vg1 vg2
VG #VMdaCps
vg1 1
vg2 unmanaged
The "unmanaged" is actually mapped onto reserved value
18446744073709551615 (2^64 - 1) internally.
Such reseved value is already caught on selection criteria input
properly:
$ vgs -o name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies=18446744073709551615'
Numeric value 18446744073709551615 found in selection is reserved.
However, we still need to fix situaton where the reserved value may be
included in resulting range:
Before this patch:
$ vgs -o vg_name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies >= 1'
VG #VMdaCps
vg1 1
vg2 unmanaged
With this patch applied:
$ vgs -o vg_name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies >= 1'
VG #VMdaCps
vg1 1
>From the examples above, we can see that without this patch applied,
the vg_mda_copies >= 1 also matched the reserved value 18446744073709551615
(which is represented by the "unamanged" string on report). When
applying the operators, such values must be skipped! They're meant to
be matched only against their string representation only, e.g.:
$ vgs -o name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies=unmanaged'
VG #VMdaCps
vg2 unmanaged
...or any synonyms:
$ vgs -o name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies=undefined'
VG #VMdaCps
vg2 unmanaged
---
WHATS_NEW_DM | 1 +
libdm/libdm-report.c | 118 ++++++++++++++++++++++++++------------------------
2 files changed, 62 insertions(+), 57 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 5ab34c1..6981f8f 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.91 -
====================================
+ Fix selection criteria to not match reserved values when using >, <, >=, <.
Add DM_LIST_HEAD_INIT macro to libdevmapper.h
Fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 8c27c5b..f68aa85 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1234,7 +1234,49 @@ static void *_report_get_implicit_field_data(struct dm_report *rh __attribute__(
return NULL;
}
-static int _cmp_field_int(const char *field_id, uint64_t a, uint64_t b, uint32_t flags)
+static int _close_enough(double d1, double d2)
+{
+ return fabs(d1 - d2) < DBL_EPSILON;
+}
+
+/*
+ * Used to check whether a value of certain type used in selection is reserved.
+ */
+static int _check_value_is_reserved(struct dm_report *rh, unsigned type, const void *value)
+{
+ const struct dm_report_reserved_value *iter = rh->reserved_values;
+
+ if (!iter)
+ return 0;
+
+ while (iter->type) {
+ if (iter->type & type) {
+ switch (type) {
+ case DM_REPORT_FIELD_TYPE_NUMBER:
+ if (*(uint64_t *)iter->value == *(uint64_t *)value)
+ return 1;
+ break;
+ case DM_REPORT_FIELD_TYPE_STRING:
+ if (!strcmp((const char *)iter->value, (const char *) value))
+ return 1;
+ break;
+ case DM_REPORT_FIELD_TYPE_SIZE:
+ if (_close_enough(*(double *)iter->value, *(double *) value))
+ return 1;
+ break;
+ case DM_REPORT_FIELD_TYPE_STRING_LIST:
+ // TODO: add comparison for string list
+ break;
+ }
+ }
+ iter++;
+ }
+
+ return 0;
+}
+
+static int _cmp_field_int(struct dm_report *rh, const char *field_id,
+ uint64_t a, uint64_t b, uint32_t flags)
{
switch(flags & FLD_CMP_MASK) {
case FLD_CMP_EQUAL:
@@ -1242,13 +1284,13 @@ static int _cmp_field_int(const char *field_id, uint64_t a, uint64_t b, uint32_t
case FLD_CMP_NOT|FLD_CMP_EQUAL:
return a != b;
case FLD_CMP_NUMBER|FLD_CMP_GT:
- return a > b;
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_NUMBER, &a) ? 0 : a > b;
case FLD_CMP_NUMBER|FLD_CMP_GT|FLD_CMP_EQUAL:
- return a >= b;
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_NUMBER, &a) ? 0 : a >= b;
case FLD_CMP_NUMBER|FLD_CMP_LT:
- return a < b;
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_NUMBER, &a) ? 0 : a < b;
case FLD_CMP_NUMBER|FLD_CMP_LT|FLD_CMP_EQUAL:
- return a <= b;
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_NUMBER, &a) ? 0 : a <= b;
default:
log_error(INTERNAL_ERROR "_cmp_field_int: unsupported number "
"comparison type for field %s", field_id);
@@ -1257,12 +1299,8 @@ static int _cmp_field_int(const char *field_id, uint64_t a, uint64_t b, uint32_t
return 0;
}
-static int _close_enough(double d1, double d2)
-{
- return fabs(d1 - d2) < DBL_EPSILON;
-}
-
-static int _cmp_field_double(const char *field_id, double a, double b, uint32_t flags)
+static int _cmp_field_double(struct dm_report *rh, const char *field_id,
+ double a, double b, uint32_t flags)
{
switch(flags & FLD_CMP_MASK) {
case FLD_CMP_EQUAL:
@@ -1270,13 +1308,13 @@ static int _cmp_field_double(const char *field_id, double a, double b, uint32_t
case FLD_CMP_NOT|FLD_CMP_EQUAL:
return !_close_enough(a, b);
case FLD_CMP_NUMBER|FLD_CMP_GT:
- return (a > b) && !_close_enough(a, b);
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_SIZE, &a) ? 0 : (a > b) && !_close_enough(a, b);
case FLD_CMP_NUMBER|FLD_CMP_GT|FLD_CMP_EQUAL:
- return (a > b) || _close_enough(a, b);
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_SIZE, &a) ? 0 : (a > b) || _close_enough(a, b);
case FLD_CMP_NUMBER|FLD_CMP_LT:
- return (a < b) && !_close_enough(a, b);
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_SIZE, &a) ? 0 : (a < b) && !_close_enough(a, b);
case FLD_CMP_NUMBER|FLD_CMP_LT|FLD_CMP_EQUAL:
- return a < b || _close_enough(a, b);
+ return _check_value_is_reserved(rh, DM_REPORT_FIELD_TYPE_SIZE, &a) ? 0 : a < b || _close_enough(a, b);
default:
log_error(INTERNAL_ERROR "_cmp_field_double: unsupported number "
"comparison type for selection field %s", field_id);
@@ -1285,7 +1323,8 @@ static int _cmp_field_double(const char *field_id, double a, double b, uint32_t
return 0;
}
-static int _cmp_field_string(const char *field_id, const char *a, const char *b, uint32_t flags)
+static int _cmp_field_string(struct dm_report *rh __attribute__((unused)), const char *field_id,
+ const char *a, const char *b, uint32_t flags)
{
switch (flags & FLD_CMP_MASK) {
case FLD_CMP_EQUAL:
@@ -1377,7 +1416,8 @@ static int _cmp_field_string_list_any(const struct str_list_sort_value *val,
return 0;
}
-static int _cmp_field_string_list(const char *field_id,
+static int _cmp_field_string_list(struct dm_report *rh __attribute__((unused)),
+ const char *field_id,
const struct str_list_sort_value *value,
const struct selection_str_list *selection, uint32_t flags)
{
@@ -1447,16 +1487,16 @@ static int _compare_selection_field(struct dm_report *rh,
return 0;
/* fall through */
case DM_REPORT_FIELD_TYPE_NUMBER:
- r = _cmp_field_int(field_id, *(const uint64_t *) f->sort_value, fs->v.i, fs->flags);
+ r = _cmp_field_int(rh, field_id, *(const uint64_t *) f->sort_value, fs->v.i, fs->flags);
break;
case DM_REPORT_FIELD_TYPE_SIZE:
- r = _cmp_field_double(field_id, *(const uint64_t *) f->sort_value, fs->v.d, fs->flags);
+ r = _cmp_field_double(rh, field_id, *(const uint64_t *) f->sort_value, fs->v.d, fs->flags);
break;
case DM_REPORT_FIELD_TYPE_STRING:
- r = _cmp_field_string(field_id, (const char *) f->sort_value, fs->v.s, fs->flags);
+ r = _cmp_field_string(rh, field_id, (const char *) f->sort_value, fs->v.s, fs->flags);
break;
case DM_REPORT_FIELD_TYPE_STRING_LIST:
- r = _cmp_field_string_list(field_id, (const struct str_list_sort_value *) f->sort_value,
+ r = _cmp_field_string_list(rh, field_id, (const struct str_list_sort_value *) f->sort_value,
fs->v.l, fs->flags);
break;
default:
@@ -1851,42 +1891,6 @@ static const char *_get_reserved(struct dm_report *rh, unsigned type,
return s;
}
-/*
- * Used to check whether a value of certain type used in selection is reserved.
- */
-static int _check_value_is_reserved(struct dm_report *rh, unsigned type, const void *value)
-{
- const struct dm_report_reserved_value *iter = rh->reserved_values;
-
- if (!iter)
- return 0;
-
- while (iter->type) {
- if (iter->type & type) {
- switch (type) {
- case DM_REPORT_FIELD_TYPE_NUMBER:
- if (*(uint64_t *)iter->value == *(uint64_t *)value)
- return 1;
- break;
- case DM_REPORT_FIELD_TYPE_STRING:
- if (!strcmp((const char *)iter->value, (const char *) value))
- return 1;
- break;
- case DM_REPORT_FIELD_TYPE_SIZE:
- if (_close_enough(*(double *)iter->value, *(double *) value))
- return 1;
- break;
- case DM_REPORT_FIELD_TYPE_STRING_LIST:
- // TODO: add comparison for string list
- break;
- }
- }
- iter++;
- }
-
- return 0;
-}
-
float dm_percent_to_float(dm_percent_t percent)
{
return (float) percent / DM_PERCENT_1;
8 years, 11 months
master - pools: workaround hints
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e223c801fc3eb1...
Commit: e223c801fc3eb12c2a4502aee471f18a0b903de8
Parent: c28a7706ed00c135e6fb06d22dde1c374f32f847
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 19:45:17 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 19:45:17 2014 +0100
pools: workaround hints
Missing code for stacked hint estimation
---
lib/metadata/pool_manip.c | 29 +++++++++++++++++++----------
test/shell/lvconvert-cache-raid.sh | 1 +
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index b84950c..d1b4497 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -324,16 +324,25 @@ int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
pool_data_lv = seg_lv(first_seg(pool_lv), 0);
dm_list_iterate_items(seg, &pool_data_lv->segments) {
- pv = seg_pv(seg, 0);
- if (chunk_size_calc_policy == THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE)
- hint = dev_optimal_io_size(cmd->dev_types, pv_dev(pv));
- else
- hint = dev_minimum_io_size(cmd->dev_types, pv_dev(pv));
- if (!hint)
- continue;
- if (previous_hint)
- hint = _lcm(previous_hint, hint);
- previous_hint = hint;
+ switch (seg_type(seg, 0)) {
+ case AREA_PV:
+ pv = seg_pv(seg, 0);
+ if (chunk_size_calc_policy == THIN_CHUNK_SIZE_CALC_METHOD_PERFORMANCE)
+ hint = dev_optimal_io_size(cmd->dev_types, pv_dev(pv));
+ else
+ hint = dev_minimum_io_size(cmd->dev_types, pv_dev(pv));
+ if (!hint)
+ continue;
+
+ if (previous_hint)
+ hint = _lcm(previous_hint, hint);
+ previous_hint = hint;
+ break;
+ case AREA_LV:
+ /* FIXME: hint for stacked (raid) LVs - estimate geometry from LV ?? */
+ default:
+ break;
+ }
}
if (!hint)
diff --git a/test/shell/lvconvert-cache-raid.sh b/test/shell/lvconvert-cache-raid.sh
index 3ac2d0b..16dd38e 100644
--- a/test/shell/lvconvert-cache-raid.sh
+++ b/test/shell/lvconvert-cache-raid.sh
@@ -46,6 +46,7 @@ lvremove -f $vg
lvcreate -n cpool_meta -m 1 --type raid1 -l 10 $vg
lvcreate -n cpool -m 1 --type raid1 -l 10 $vg
+lvs -a -o+seg_pe_ranges $vg
lvconvert --yes --type cache-pool --poolmetadata $vg/cpool_meta $vg/cpool
lvcreate -n corigin --type cache --cachepool $vg/cpool -l 10
8 years, 11 months
master - tests: update cache creation tests
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c28a7706ed00c1...
Commit: c28a7706ed00c135e6fb06d22dde1c374f32f847
Parent: 7bbf3cf3066a62c19e5ec439f658ae5253edaace
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 16:19:30 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
tests: update cache creation tests
---
test/shell/lvcreate-cache.sh | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/test/shell/lvcreate-cache.sh b/test/shell/lvcreate-cache.sh
index 69d0534..b37f321 100644
--- a/test/shell/lvcreate-cache.sh
+++ b/test/shell/lvcreate-cache.sh
@@ -202,6 +202,27 @@ check lv_attr_bit perm $vg/$lv6 "r"
lvremove -f $vg
+########################################
+# Validate args are properly preserved #
+########################################
+lvcreate --type cache-pool -L10 --chunksize 256 --cachemode writeback $vg/cpool1
+lvcreate -H -L10 $vg/cpool1
+check lv_field $vg/cpool1 chunksize "256.00k"
+check lv_field $vg/cpool1 cachemode "writeback"
+
+lvcreate --type cache-pool -L10 --chunksize 256 --cachemode writethrough $vg/cpool2
+lvcreate -H -L10 --chunksize 512 --cachemode writeback $vg/cpool2
+check lv_field $vg/cpool2 chunksize "512.00k"
+check lv_field $vg/cpool2 cachemode "writeback"
+
+# Chunk bigger then pool size
+fail lvcreate --type cache-pool -l1 --chunksize 1G $vg/cpool3
+
+lvcreate --type cache-pool -L10 $vg/cpool4
+fail lvcreate -H -L10 --chunksize 16M $vg/cpool4
+
+lvremove -f $vg
+
##############################
# Test things that should fail
8 years, 11 months
master - tests: lvcreate-update
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=7bbf3cf3066a62...
Commit: 7bbf3cf3066a62c19e5ec439f658ae5253edaace
Parent: 70616187b32ee890eae8e8607c2d247d16cd6787
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 07:29:25 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
tests: lvcreate-update
Test with old mirror type.
---
test/shell/lvcreate-usage.sh | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/test/shell/lvcreate-usage.sh b/test/shell/lvcreate-usage.sh
index c2b7112..05f2515 100644
--- a/test/shell/lvcreate-usage.sh
+++ b/test/shell/lvcreate-usage.sh
@@ -114,10 +114,10 @@ lvremove -f $vg
# - nonzero (bz186013)
# - a power of 2 and a multiple of page size
# - <= size of LV
-invalid lvcreate -m 1 -L 32m -n $lv -R 0 $vg 2>err
+invalid lvcreate --type mirror -m 1 -L 32m -n $lv -R 0 $vg 2>err
grep "may not be zero" err
-invalid lvcreate -m 1 -L 32m -n $lv -R 11k $vg
-invalid lvcreate -m 1 -L 32m -n $lv -R 1k $vg
+invalid lvcreate --type mirror -m 1 -L 32m -n $lv -R 11k $vg
+invalid lvcreate --type mirror -m 1 -L 32m -n $lv -R 1k $vg
lvcreate -aey -L 32m -n $lv --regionsize 128m --type mirror -m 1 $vg
check lv_field $vg/$lv regionsize "32.00m"
lvremove -f $vg
8 years, 11 months
master - tests: pytest update
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=70616187b32ee8...
Commit: 70616187b32ee890eae8e8607c2d247d16cd6787
Parent: 205e3ff88898848b6e5dcfde74bff829bd27bf83
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 07:27:23 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
tests: pytest update
---
test/api/pytest.sh | 3 +++
test/api/python_lvm_unit.py | 2 +-
2 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/test/api/pytest.sh b/test/api/pytest.sh
index 7b6085f..36f55fa 100644
--- a/test/api/pytest.sh
+++ b/test/api/pytest.sh
@@ -21,6 +21,9 @@
# thus it needs dmeventd
#
+# Example of using 'gdb' with python:
+# gdb -ex r --args python FULL_PATH/lvm2/test/api/python_lvm_unit.py -v TestLvm.test_lv_active_inactive
+
#Locate the python binding library to use.
python_lib=$(find $abs_top_builddir -name lvm.so)
# Unable to test python bindings if library not available
diff --git a/test/api/python_lvm_unit.py b/test/api/python_lvm_unit.py
index ab2e86f..c338775 100755
--- a/test/api/python_lvm_unit.py
+++ b/test/api/python_lvm_unit.py
@@ -132,7 +132,7 @@ class TestLvm(unittest.TestCase):
vg.extend(d)
vg.createLvThinpool(pool_name, vg.getSize()/2, 0, 0,
- lvm.THIN_DISCARDS_PASSDOWN, 1)
+ lvm.THIN_DISCARDS_PASSDOWN, 1)
return vg
@staticmethod
8 years, 11 months
master - lvcreate: delay check for free extents
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=205e3ff8889884...
Commit: 205e3ff88898848b6e5dcfde74bff829bd27bf83
Parent: c9fbbf48baf9866dc57b336f9ca2b54346fb9827
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 16:18:53 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
lvcreate: delay check for free extents
As the rounding for cache creation may change the value of extents
postpone check for free extents.
---
lib/metadata/lv_manip.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 1ab47c6..36bc2d8 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6636,14 +6636,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
- if (!seg_is_virtual(lp) && !lp->approx_alloc &&
- (vg->free_count < lp->extents)) {
- log_error("Volume group \"%s\" has insufficient free space "
- "(%u extents): %u required.",
- vg->name, vg->free_count, lp->extents);
- return NULL;
- }
-
if ((lp->alloc != ALLOC_ANYWHERE) && (lp->stripes > dm_list_size(lp->pvh))) {
log_error("Number of stripes (%u) must not exceed "
"number of physical volumes (%d)", lp->stripes,
@@ -6836,6 +6828,14 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
lp->wipe_signatures = 0;
}
+ if (!seg_is_virtual(lp) && !lp->approx_alloc &&
+ (vg->free_count < lp->extents)) {
+ log_error("Volume group \"%s\" has insufficient free space "
+ "(%u extents): %u required.",
+ vg->name, vg->free_count, lp->extents);
+ return NULL;
+ }
+
if (!archive(vg))
return_NULL;
8 years, 11 months
master - cache: support more args
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c9fbbf48baf986...
Commit: c9fbbf48baf9866dc57b336f9ca2b54346fb9827
Parent: ff2e8b0de6aafcf304b30e5f90501f3638ead22f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 16:17:14 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
cache: support more args
Unlike with thin-pool - with cache we support all args also
directly when create cache volume.
So the result of 'separate' cache-pool creation and setting its
options should give same result as specifying those args
during cache creation.
Cache-pool values are used as defaults if the params are
not specified with cache creation.
---
lib/metadata/lv_manip.c | 11 ++++++-----
tools/lvcreate.c | 16 +++++++++++-----
2 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 1e9d1c6..1ab47c6 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6629,7 +6629,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return_NULL;
}
- if (seg_is_pool(lp) &&
+ if ((seg_is_pool(lp) || seg_is_cache(lp)) &&
((uint64_t)lp->extents * vg->extent_size < lp->chunk_size)) {
log_error("Unable to create %s smaller than 1 chunk.",
lp->segtype->name);
@@ -6876,11 +6876,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
/* Unlock memory if possible */
memlock_unlock(vg->cmd);
- if (seg_is_cache_pool(lp)) {
- first_seg(lv)->chunk_size = lp->chunk_size;
- first_seg(lv)->feature_flags = lp->feature_flags;
+ if (seg_is_cache_pool(lp) || seg_is_cache(lp)) {
+ pool_lv = pool_lv ? : lv;
+ first_seg(pool_lv)->chunk_size = lp->chunk_size;
+ first_seg(pool_lv)->feature_flags = lp->feature_flags;
/* TODO: some calc_policy solution for cache ? */
- if (!recalculate_pool_chunk_size_with_dev_hints(lv, lp->passed_args,
+ if (!recalculate_pool_chunk_size_with_dev_hints(pool_lv, lp->passed_args,
THIN_CHUNK_SIZE_CALC_METHOD_GENERIC)) {
stack;
goto revert_new_lv;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 199636c..78b6898 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1035,6 +1035,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
static int _determine_cache_argument(struct volume_group *vg,
struct lvcreate_params *lp)
{
+ struct cmd_context *cmd = vg->cmd;
struct logical_volume *lv;
if (!lp->pool_name) {
@@ -1045,19 +1046,24 @@ static int _determine_cache_argument(struct volume_group *vg,
/* Pool exists, create cache volume */
lp->create_pool = 0;
lp->origin_name = NULL;
+ /* If cache args not given, use those from cache pool */
+ if (!arg_is_set(cmd, chunksize_ARG))
+ lp->chunk_size = first_seg(lv)->chunk_size;
+ if (!arg_is_set(cmd, cachemode_ARG))
+ lp->feature_flags = first_seg(lv)->feature_flags;
} else if (lv) {
/* Origin exists, create cache pool volume */
if (!validate_lv_cache_create_origin(lv))
return_0;
- if (arg_is_set(vg->cmd, permission_ARG) &&
+ if (arg_is_set(cmd, permission_ARG) &&
((lp->permission & LVM_WRITE) != (lv->status & LVM_WRITE))) {
/* Reverting permissions on all error path is very complicated */
log_error("Change of volume permission is unsupported with cache conversion, use lvchange.");
return 0;
}
/* FIXME: how to handle skip flag */
- if (arg_from_list_is_set(vg->cmd, "is unsupported with cache conversion",
+ if (arg_from_list_is_set(cmd, "is unsupported with cache conversion",
setactivationskip_ARG,
ignoreactivationskip_ARG,
-1))
@@ -1066,16 +1072,16 @@ static int _determine_cache_argument(struct volume_group *vg,
/* Put origin into resulting activation state first */
if (is_change_activating(lp->activate)) {
if ((lp->activate == CHANGE_AAY) &&
- !lv_passes_auto_activation_filter(vg->cmd, lv)) {
+ !lv_passes_auto_activation_filter(cmd, lv)) {
log_verbose("Skipping activation of cache origin %s.",
display_lvname(lv));
return 1;
- } else if (!activate_lv_excl_local(vg->cmd, lv)) {
+ } else if (!activate_lv_excl_local(cmd, lv)) {
log_error("Cannot activate cache origin %s.",
display_lvname(lv));
return 0;
}
- } else if (!deactivate_lv(vg->cmd, lv)) {
+ } else if (!deactivate_lv(cmd, lv)) {
log_error("Cannot deactivate activate cache origin %s.",
display_lvname(lv));
return 0;
8 years, 11 months
master - thin: simplify thin volume creation
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ff2e8b0de6aafc...
Commit: ff2e8b0de6aafcf304b30e5f90501f3638ead22f
Parent: 52dfa6dd4491fd6f584b83d0924b82bea3bc1092
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 08:13:59 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
thin: simplify thin volume creation
Move code for creation of thin volume into a single place
out of lv_extend(). This allows to drop extra pool arg
for alloc_lv_segment() && lv_extend() and makes code
more easier to read and follow.
---
lib/format1/import-extents.c | 4 +-
lib/format_pool/import_export.c | 4 +-
lib/format_text/import_vsn1.c | 2 +-
lib/metadata/lv_alloc.h | 5 +-
lib/metadata/lv_manip.c | 135 ++++++++++++-------------------------
lib/metadata/merge.c | 2 +-
lib/metadata/metadata-exported.h | 2 +-
lib/metadata/pool_manip.c | 2 +-
tools/lvconvert.c | 2 +-
9 files changed, 54 insertions(+), 104 deletions(-)
diff --git a/lib/format1/import-extents.c b/lib/format1/import-extents.c
index f0f4f65..bfcf0de 100644
--- a/lib/format1/import-extents.c
+++ b/lib/format1/import-extents.c
@@ -226,7 +226,7 @@ static int _read_linear(struct cmd_context *cmd, struct lv_map *lvm)
len = _area_length(lvm, le);
if (!(seg = alloc_lv_segment(segtype, lvm->lv, le, len, 0, 0,
- NULL, NULL, 1, len, 0, 0, 0, NULL))) {
+ NULL, 1, len, 0, 0, 0, NULL))) {
log_error("Failed to allocate linear segment.");
return 0;
}
@@ -298,7 +298,7 @@ static int _read_stripes(struct cmd_context *cmd, struct lv_map *lvm)
if (!(seg = alloc_lv_segment(segtype, lvm->lv,
lvm->stripes * first_area_le,
lvm->stripes * area_len,
- 0, lvm->stripe_size, NULL, NULL,
+ 0, lvm->stripe_size, NULL,
lvm->stripes,
area_len, 0, 0, 0, NULL))) {
log_error("Failed to allocate striped segment.");
diff --git a/lib/format_pool/import_export.c b/lib/format_pool/import_export.c
index 6ef0757..1aeabe2 100644
--- a/lib/format_pool/import_export.c
+++ b/lib/format_pool/import_export.c
@@ -194,7 +194,7 @@ static int _add_stripe_seg(struct dm_pool *mem,
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len * usp->num_devs, 0,
- usp->striping, NULL, NULL, usp->num_devs,
+ usp->striping, NULL, usp->num_devs,
area_len, 0, 0, 0, NULL))) {
log_error("Unable to allocate striped lv_segment structure");
return 0;
@@ -234,7 +234,7 @@ static int _add_linear_seg(struct dm_pool *mem,
if (!(seg = alloc_lv_segment(segtype, lv, *le_cur,
area_len, 0, usp->striping,
- NULL, NULL, 1, area_len,
+ NULL, 1, area_len,
POOL_PE_SIZE, 0, 0, NULL))) {
log_error("Unable to allocate linear lv_segment "
"structure");
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 1783b1e..c6a0cf9 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -363,7 +363,7 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
return_0;
if (!(seg = alloc_lv_segment(segtype, lv, start_extent,
- extent_count, 0, 0, NULL, NULL, area_count,
+ extent_count, 0, 0, NULL, area_count,
extent_count, 0, 0, 0, NULL))) {
log_error("Segment allocation failed");
return 0;
diff --git a/lib/metadata/lv_alloc.h b/lib/metadata/lv_alloc.h
index 9824c67..1ac3f1f 100644
--- a/lib/metadata/lv_alloc.h
+++ b/lib/metadata/lv_alloc.h
@@ -24,7 +24,6 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
uint64_t status,
uint32_t stripe_size,
struct logical_volume *log_lv,
- struct logical_volume *thin_pool_lv,
uint32_t area_count,
uint32_t area_len,
uint32_t chunk_size,
@@ -79,9 +78,7 @@ int lv_add_mirror_lvs(struct logical_volume *lv,
int lv_add_log_segment(struct alloc_handle *ah, uint32_t first_area,
struct logical_volume *log_lv, uint64_t status);
int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
- uint32_t extents,
- const struct segment_type *segtype,
- const char *thin_pool_name);
+ uint32_t extents, const struct segment_type *segtype);
void alloc_destroy(struct alloc_handle *ah);
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index b12af6c..1e9d1c6 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -921,7 +921,6 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
uint64_t status,
uint32_t stripe_size,
struct logical_volume *log_lv,
- struct logical_volume *thin_pool_lv,
uint32_t area_count,
uint32_t area_len,
uint32_t chunk_size,
@@ -967,26 +966,6 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
dm_list_init(&seg->tags);
dm_list_init(&seg->thin_messages);
- if (thin_pool_lv) {
- /* If this is thin volume, thin snapshot is being created */
- if (lv_is_thin_volume(thin_pool_lv)) {
- seg->transaction_id = first_seg(first_seg(thin_pool_lv)->pool_lv)->transaction_id;
- if (!attach_pool_lv(seg, first_seg(thin_pool_lv)->pool_lv, thin_pool_lv, NULL))
- return_NULL;
- /* Use the same external origin */
- if (!attach_thin_external_origin(seg, first_seg(thin_pool_lv)->external_lv))
- return_NULL;
- } else if (lv_is_thin_pool(thin_pool_lv)) {
- seg->transaction_id = first_seg(thin_pool_lv)->transaction_id;
- if (!attach_pool_lv(seg, thin_pool_lv, NULL, NULL))
- return_NULL;
- } else {
- log_error(INTERNAL_ERROR "Volume %s is not thin volume or thin pool",
- thin_pool_lv->name);
- return NULL;
- }
- }
-
if (log_lv && !attach_mirror_log(seg, log_lv))
return_NULL;
@@ -1013,7 +992,7 @@ struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv,
if (!(seg = alloc_lv_segment(segtype, lv, old_le_count,
lv->le_count - old_le_count, status, 0,
- NULL, NULL, 0, lv->le_count - old_le_count,
+ NULL, 0, lv->le_count - old_le_count,
0, 0, 0, NULL))) {
log_error("Couldn't allocate new snapshot segment.");
return NULL;
@@ -1369,7 +1348,7 @@ int replace_lv_with_error_segment(struct logical_volume *lv)
/* FIXME Check for any attached LVs that will become orphans e.g. mirror logs */
- if (!lv_add_virtual_segment(lv, 0, len, get_segtype_from_string(lv->vg->cmd, "error"), NULL))
+ if (!lv_add_virtual_segment(lv, 0, len, get_segtype_from_string(lv->vg->cmd, "error")))
return_0;
return 1;
@@ -1859,7 +1838,7 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint64_t status,
if (!(seg = alloc_lv_segment(segtype, lv, lv->le_count,
aa[0].len * area_multiple,
- status, stripe_size, NULL, NULL,
+ status, stripe_size, NULL,
area_count,
aa[0].len, 0u, region_size, 0u, NULL))) {
log_error("Couldn't allocate new LV segment.");
@@ -3011,21 +2990,9 @@ static int _allocate(struct alloc_handle *ah,
}
int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
- uint32_t extents, const struct segment_type *segtype,
- const char *thin_pool_name)
+ uint32_t extents, const struct segment_type *segtype)
{
struct lv_segment *seg;
- struct logical_volume *thin_pool_lv = NULL;
- struct lv_list *lvl;
-
- if (thin_pool_name) {
- if (!(lvl = find_lv_in_vg(lv->vg, thin_pool_name))) {
- log_error("Unable to find existing pool LV %s in VG %s.",
- thin_pool_name, lv->vg->name);
- return 0;
- }
- thin_pool_lv = lvl->lv;
- }
if (!dm_list_empty(&lv->segments) &&
(seg = last_seg(lv)) && (seg->segtype == segtype)) {
@@ -3033,9 +3000,9 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
seg->len += extents;
} else {
if (!(seg = alloc_lv_segment(segtype, lv, lv->le_count, extents,
- status, 0, NULL, thin_pool_lv, 0,
+ status, 0, NULL, 0,
extents, 0, 0, 0, NULL))) {
- log_error("Couldn't allocate new zero segment.");
+ log_error("Couldn't allocate new %s segment.", segtype->name);
return 0;
}
lv->status |= VIRTUAL;
@@ -3171,7 +3138,7 @@ static struct lv_segment *_convert_seg_to_mirror(struct lv_segment *seg,
if (!(newseg = alloc_lv_segment(get_segtype_from_string(seg->lv->vg->cmd, "mirror"),
seg->lv, seg->le, seg->len,
seg->status, seg->stripe_size,
- log_lv, NULL,
+ log_lv,
seg->area_count, seg->area_len,
seg->chunk_size, region_size,
seg->extents_copied, NULL))) {
@@ -3273,7 +3240,7 @@ int lv_add_segmented_mirror_image(struct alloc_handle *ah,
if (!(new_seg = alloc_lv_segment(segtype, copy_lv,
seg->le, seg->len, PVMOVE, 0,
- NULL, NULL, 1, seg->len,
+ NULL, 1, seg->len,
0, 0, 0, NULL)))
return_0;
@@ -3473,7 +3440,7 @@ static int _lv_insert_empty_sublvs(struct logical_volume *lv,
* First, create our top-level segment for our top-level LV
*/
if (!(mapseg = alloc_lv_segment(segtype, lv, 0, 0, lv->status,
- stripe_size, NULL, NULL,
+ stripe_size, NULL,
devices, 0, 0, region_size, 0, NULL))) {
log_error("Failed to create mapping segment for %s", lv->name);
return 0;
@@ -3665,7 +3632,7 @@ int lv_extend(struct logical_volume *lv,
const struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size,
uint32_t mirrors, uint32_t region_size,
- uint32_t extents, const char *thin_pool_name,
+ uint32_t extents,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
int approx_alloc)
{
@@ -3679,16 +3646,12 @@ int lv_extend(struct logical_volume *lv,
log_very_verbose("Adding segment of type %s to LV %s.", segtype->name, lv->name);
if (segtype_is_virtual(segtype))
- return lv_add_virtual_segment(lv, 0u, extents, segtype, thin_pool_name);
+ return lv_add_virtual_segment(lv, 0u, extents, segtype);
- if (!lv->le_count &&
- (segtype_is_thin_pool(segtype) ||
- segtype_is_cache_pool(segtype))) {
+ if (!lv->le_count && segtype_is_pool(segtype)) {
/*
- * Thinpool and cache_pool allocations treat the metadata
- * device like a mirror log.
+ * Pool allocations treat the metadata device like a mirror log.
*/
- /* FIXME Allow pool and data on same device with NORMAL */
/* FIXME Support striped metadata pool */
log_count = 1;
} else if (segtype_is_raid(segtype) && !lv->le_count)
@@ -3704,7 +3667,7 @@ int lv_extend(struct logical_volume *lv,
if (segtype_is_raid(segtype))
new_extents -= ah->log_len * ah->area_multiple;
- if (segtype_is_thin_pool(segtype) || segtype_is_cache_pool(segtype)) {
+ if (segtype_is_pool(segtype)) {
if (!(r = create_pool(lv, segtype, ah, stripes, stripe_size)))
stack;
} else if (!segtype_is_mirrored(segtype) && !segtype_is_raid(segtype)) {
@@ -4293,7 +4256,7 @@ static int _lvresize_poolmetadata(struct cmd_context *cmd, struct volume_group *
mseg->stripe_size,
seg_mirrors,
mseg->region_size,
- lp->poolmetadataextents - lv->le_count, NULL,
+ lp->poolmetadataextents - lv->le_count,
pvh, alloc, 0))
return_0;
@@ -4932,7 +4895,7 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
!lv_extend(lv, lp->segtype,
lp->stripes, lp->stripe_size,
lp->mirrors, first_seg(lv)->region_size,
- lp->extents - lv->le_count, NULL,
+ lp->extents - lv->le_count,
pvh, alloc, lp->approx_alloc))
return_NULL;
@@ -6017,7 +5980,7 @@ int remove_layer_from_lv(struct logical_volume *lv,
/* Replace the empty layer with error segment */
if (!(segtype = get_segtype_from_string(lv->vg->cmd, "error")))
return_0;
- if (!lv_add_virtual_segment(layer_lv, 0, parent->le_count, segtype, NULL))
+ if (!lv_add_virtual_segment(layer_lv, 0, parent->le_count, segtype))
return_0;
return 1;
@@ -6066,7 +6029,7 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
segtype = get_segtype_from_string(cmd, "error");
- if (!lv_add_virtual_segment(layer_lv, 0, lv_where->le_count, segtype, NULL)) {
+ if (!lv_add_virtual_segment(layer_lv, 0, lv_where->le_count, segtype)) {
log_error("Creation of transient LV %s for mirror conversion in VG %s failed.", name, lv_where->vg->name);
return NULL;
}
@@ -6117,7 +6080,7 @@ struct logical_volume *insert_layer_for_lv(struct cmd_context *cmd,
/* allocate a new linear segment */
if (!(mapseg = alloc_lv_segment(segtype, lv_where, 0, layer_lv->le_count,
- status, 0, NULL, NULL, 1, layer_lv->le_count,
+ status, 0, NULL, 1, layer_lv->le_count,
0, 0, 0, NULL)))
return_NULL;
@@ -6174,7 +6137,7 @@ static int _extend_layer_lv_for_segment(struct logical_volume *layer_lv,
/* allocate a new segment */
if (!(mapseg = alloc_lv_segment(segtype, layer_lv, layer_lv->le_count,
seg->area_len, status, 0,
- NULL, NULL, 1, seg->area_len, 0, 0, 0, seg)))
+ NULL, 1, seg->area_len, 0, 0, 0, seg)))
return_0;
/* map the new segment to the original underlying are */
@@ -6445,7 +6408,7 @@ static struct logical_volume *_create_virtual_origin(struct cmd_context *cmd,
return_NULL;
if (!lv_extend(lv, segtype, 1, 0, 1, 0, voriginextents,
- NULL, NULL, ALLOC_INHERIT, 0))
+ NULL, ALLOC_INHERIT, 0))
return_NULL;
/* store vg on disk(s) */
@@ -6594,9 +6557,9 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
uint64_t status = lp->permission | VISIBLE_LV;
const struct segment_type *create_segtype = lp->segtype;
struct logical_volume *lv, *origin_lv = NULL;
- struct logical_volume *pool_lv;
+ struct logical_volume *pool_lv = NULL;
struct logical_volume *tmp_lv;
- const char *thin_name = NULL;
+ struct lv_segment *seg, *pool_seg;
if (new_lv_name && find_lv_in_vg(vg, new_lv_name)) {
log_error("Logical volume \"%s\" already exists in "
@@ -6785,19 +6748,12 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
- thin_name = lp->pool_name;
-
if (origin_lv) {
if (lv_is_locked(origin_lv)) {
log_error("Snapshots of locked devices are not supported.");
return NULL;
}
- /* For thin snapshot we must have matching pool */
- if (lv_is_thin_volume(origin_lv) &&
- (strcmp(first_seg(origin_lv)->pool_lv->name, lp->pool_name) == 0))
- thin_name = origin_lv->name;
-
lp->voriginextents = origin_lv->le_count;
/*
@@ -6883,7 +6839,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (!archive(vg))
return_NULL;
- if (seg_is_thin_volume(lp)) {
+ if (pool_lv && seg_is_thin_volume(lp)) {
/* Ensure all stacked messages are submitted */
if ((pool_is_active(pool_lv) || is_change_activating(lp->activate)) &&
!update_pool_lv(pool_lv, 1))
@@ -6914,7 +6870,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
lp->mirrors,
seg_is_pool(lp) ? lp->pool_metadata_extents : lp->region_size,
seg_is_thin_volume(lp) ? lp->voriginextents : lp->extents,
- thin_name, lp->pvh, lp->alloc, lp->approx_alloc))
+ lp->pvh, lp->alloc, lp->approx_alloc))
return_NULL;
/* Unlock memory if possible */
@@ -6943,32 +6899,29 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
stack;
goto revert_new_lv;
}
- } else if (seg_is_thin_volume(lp)) {
- pool_lv = first_seg(lv)->pool_lv;
- if (!(first_seg(lv)->device_id =
- get_free_pool_device_id(first_seg(pool_lv))))
+ } else if (pool_lv && seg_is_thin_volume(lp)) {
+ seg = first_seg(lv);
+ pool_seg = first_seg(pool_lv);
+ if (!(seg->device_id = get_free_pool_device_id(pool_seg)))
return_NULL;
- /*
- * Check if using 'external origin' or the 'normal' snapshot
- * within the same thin pool
- */
- if (origin_lv && (first_seg(origin_lv)->pool_lv != pool_lv)) {
- if (!pool_supports_external_origin(first_seg(pool_lv), origin_lv))
- return_0;
- if (origin_lv->status & LVM_WRITE) {
- log_error("Cannot use writable LV as the external origin.");
- return 0; // TODO conversion for inactive
- }
- if (lv_is_active(origin_lv) && !lv_is_external_origin(origin_lv)) {
- log_error("Cannot use active LV for the external origin.");
- return 0; // We can't be sure device is read-only
- }
- if (!attach_thin_external_origin(first_seg(lv), origin_lv))
+ seg->transaction_id = pool_seg->transaction_id;
+ if (origin_lv && lv_is_thin_volume(origin_lv) &&
+ (first_seg(origin_lv)->pool_lv == pool_lv)) {
+ /* For thin snapshot pool must match */
+ if (!attach_pool_lv(seg, pool_lv, origin_lv, NULL))
+ return_NULL;
+ /* Use the same external origin */
+ if (!attach_thin_external_origin(seg, first_seg(origin_lv)->external_lv))
+ return_NULL;
+ } else {
+ if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
+ return_NULL;
+ /* If there is an external origin... */
+ if (!attach_thin_external_origin(seg, origin_lv))
return_NULL;
}
- if (!attach_pool_message(first_seg(pool_lv),
- DM_THIN_MESSAGE_CREATE_THIN, lv, 0, 0))
+ if (!attach_pool_message(pool_seg, DM_THIN_MESSAGE_CREATE_THIN, lv, 0, 0))
return_NULL;
}
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index c8c9543..5e09123 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -489,7 +489,7 @@ static int _lv_split_segment(struct logical_volume *lv, struct lv_segment *seg,
if (!(split_seg = alloc_lv_segment(seg->segtype,
seg->lv, seg->le, seg->len,
seg->status, seg->stripe_size,
- seg->log_lv, seg->pool_lv,
+ seg->log_lv,
seg->area_count, seg->area_len,
seg->chunk_size, seg->region_size,
seg->extents_copied, seg->pvmove_source_seg))) {
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index d05333c..5ac68bf 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -709,7 +709,7 @@ int lv_extend(struct logical_volume *lv,
const struct segment_type *segtype,
uint32_t stripes, uint32_t stripe_size,
uint32_t mirrors, uint32_t region_size,
- uint32_t extents, const char *thin_pool_name,
+ uint32_t extents,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
int approx_alloc);
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index b4259a8..b84950c 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -638,7 +638,7 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
seg->stripe_size,
seg_mirrors,
seg->region_size,
- extents - lv->le_count, NULL,
+ extents - lv->le_count,
pvh, lv->alloc, 0))
return_0;
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 6d6d305..f22c84b 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3088,7 +3088,7 @@ static int _lvconvert_pool(struct cmd_context *cmd,
/* Allocate a new pool segment */
if (!(seg = alloc_lv_segment(lp->segtype, pool_lv, 0, data_lv->le_count,
- pool_lv->status, 0, NULL, NULL, 1,
+ pool_lv->status, 0, NULL, 1,
data_lv->le_count, 0, 0, 0, NULL)))
return_0;
8 years, 11 months
master - cache: apply chunk rounding also for cache creation.
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=52dfa6dd4491fd...
Commit: 52dfa6dd4491fd6f584b83d0924b82bea3bc1092
Parent: 25307e4add1e3f25cf5ae00d942df61afa46fe60
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Oct 26 18:17:59 2014 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sun Oct 26 18:37:13 2014 +0100
cache: apply chunk rounding also for cache creation.
When we create volumes with chunk size bigger then extent size
we try to round up to some nearest chunk boundary.
Until now we did this for thins - use same logic for
cache volumes.
---
lib/metadata/lv_manip.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 8523b58..b12af6c 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -3017,7 +3017,6 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
struct lv_segment *seg;
struct logical_volume *thin_pool_lv = NULL;
struct lv_list *lvl;
- uint32_t size;
if (thin_pool_name) {
if (!(lvl = find_lv_in_vg(lv->vg, thin_pool_name))) {
@@ -3026,17 +3025,6 @@ int lv_add_virtual_segment(struct logical_volume *lv, uint64_t status,
return 0;
}
thin_pool_lv = lvl->lv;
- size = first_seg(thin_pool_lv)->chunk_size;
- if (lv->vg->extent_size < size) {
- /* Align extents on chunk boundary size */
- size = ((uint64_t)lv->vg->extent_size * extents + size - 1) /
- size * size / lv->vg->extent_size;
- if (size != extents) {
- log_print_unless_silent("Rounding size (%d extents) up to chunk boundary "
- "size (%d extents).", extents, size);
- extents = size;
- }
- }
}
if (!dm_list_empty(&lv->segments) &&
@@ -6722,6 +6710,20 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
display_lvname(pool_lv));
return NULL;
}
+
+ /* Validate volume size to to aling on chunk for small extents */
+ /* Cache chunk size is always set */
+ size = seg_is_cache(lp) ? lp->chunk_size : first_seg(pool_lv)->chunk_size;
+ if (size > vg->extent_size) {
+ /* Align extents on chunk boundary size */
+ size = ((uint64_t)vg->extent_size * lp->extents + size - 1) /
+ size * size / vg->extent_size;
+ if (size != lp->extents) {
+ log_print_unless_silent("Rounding size (%d extents) up to chunk boundary "
+ "size (%d extents).", lp->extents, size);
+ lp->extents = size;
+ }
+ }
}
/* Resolve origin volume */
8 years, 11 months