master - locking: clarify read-only locking error message
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a05ac836412f1a...
Commit: a05ac836412f1a9ebc6bc90fe611ff6808d6d844
Parent: 1b607890203911a0f92e8f5d5f55e60b52d746ad
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Jul 25 14:06:02 2012 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Jul 25 14:06:02 2012 +0200
locking: clarify read-only locking error message
---
lib/locking/no_locking.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c
index cc57275..76d8f1f 100644
--- a/lib/locking/no_locking.c
+++ b/lib/locking/no_locking.c
@@ -74,7 +74,8 @@ static int _readonly_lock_resource(struct cmd_context *cmd,
(flags & LCK_SCOPE_MASK) == LCK_VG &&
!(flags & LCK_CACHE) &&
strcmp(resource, VG_GLOBAL)) {
- log_error("Write locks are prohibited with read-only locking.");
+ log_error("Read-only locking configured via global/locking_type setting. "
+ "Write locks are prohibited.");
return 0;
}
11 years, 9 months
master - Forgot to update WHATS_NEW for commit 5555d2a000ed4e3d5a694896f3dc6a7290543f43
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=1b607890203911...
Commit: 1b607890203911a0f92e8f5d5f55e60b52d746ad
Parent: 5555d2a000ed4e3d5a694896f3dc6a7290543f43
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Jul 24 22:28:23 2012 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Jul 24 22:28:23 2012 -0500
Forgot to update WHATS_NEW for commit 5555d2a000ed4e3d5a694896f3dc6a7290543f43
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index aa26622..bca890e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
+ Fix segfault when attempting to replace RAID 4/5/6 device (2.02.97).
Fix dumpconfig <node> to print only <node> without its siblings (2.02.89).
Do not issue "Failed to handle a client connection" error if lvmetad killed.
Support changing of discard and zeroing for thin pool.
11 years, 9 months
master - RAID: Fix segfault when attempting to replace RAID 4/5/6 device
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5555d2a000ed4e...
Commit: 5555d2a000ed4e3d5a694896f3dc6a7290543f43
Parent: 407198e17dc805dd9ce0583c8b1dbade71572af6
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Jul 24 19:02:06 2012 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Jul 24 19:02:06 2012 -0500
RAID: Fix segfault when attempting to replace RAID 4/5/6 device
Commit 8767435ef847831455fadc1f7e8f4d2d94aef0d5 allowed RAID 4/5/6
LV to be extended properly, but introduced a regression in device
replacement - a critical component of fault tolerance.
When only 1 or 2 drives are being replaced, the 'area_count' needed
can be equal to the parity_count. The 'area_multiple' for RAID 4/5/6
was computed as 'area_count - parity_devs', which could result in
'area_multiple' being 0. This would ultimately lead to a division by
zero error. Therefore, in calc_area_multiple, it is important to take
into account the number of areas that are being requested - just as
we already do in _alloc_init.
---
lib/metadata/lv_manip.c | 11 ++++++++++-
test/shell/lvconvert-repair.sh | 26 +++++++++++++++++++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 0d89b4a..daa90da 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -698,8 +698,17 @@ static uint32_t _calc_area_multiple(const struct segment_type *segtype,
return area_count;
/* Parity RAID (e.g. RAID 4/5/6) */
- if (segtype_is_raid(segtype) && segtype->parity_devs)
+ if (segtype_is_raid(segtype) && segtype->parity_devs) {
+ /*
+ * As articulated in _alloc_init, we can tell by
+ * the area_count whether a replacement drive is
+ * being allocated; and if this is the case, then
+ * there is no area_multiple that should be used.
+ */
+ if (area_count <= segtype->parity_devs)
+ return 1;
return area_count - segtype->parity_devs;
+ }
/* Mirrored stripes */
if (stripes)
diff --git a/test/shell/lvconvert-repair.sh b/test/shell/lvconvert-repair.sh
index 947998c..0aeeffa 100644
--- a/test/shell/lvconvert-repair.sh
+++ b/test/shell/lvconvert-repair.sh
@@ -23,7 +23,7 @@ aux lvmconf 'allocation/mirror_logs_require_separate_pvs = 1'
# fail multiple devices
# 4-way, disk log => 2-way, disk log
-aux prepare_vg 5
+aux prepare_vg 8
lvcreate -m 3 --ig -L 1 -n 4way $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5":0
aux disable_dev "$dev2" "$dev4"
echo n | lvconvert --repair $vg/4way 2>&1 | tee 4way.out
@@ -111,4 +111,28 @@ lvconvert -y --repair $vg/mirror
vgreduce --removemissing $vg
aux enable_dev "$dev3"
vgextend $vg "$dev3"
+lvremove -ff $vg
+
+# RAID5 single replace
+lvcreate --type raid5 -i 2 -l 2 -n $lv1 $vg "$dev1" "$dev2" "$dev3"
+aux wait_for_sync $vg $lv1
+aux disable_dev "$dev3"
+lvconvert -y --repair $vg/$lv1
+vgreduce --removemissing $vg
+aux enable_dev "$dev3"
+vgextend $vg "$dev3"
+lvremove -ff $vg
+
+# RAID6 double replace
+lvcreate --type raid5 -i 3 -l 2 -n $lv1 $vg \
+ "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
+aux wait_for_sync $vg $lv1
+aux disable_dev "$dev4" "$dev5"
+lvconvert -y --repair $vg/$lv1
+vgreduce --removemissing $vg
+aux enable_dev "$dev4"
+aux enable_dev "$dev5"
+vgextend $vg "$dev4" "$dev5"
+lvremove -ff $vg
+
vgremove -ff $vg
11 years, 9 months
master - TEST: Replace old sync test/wait functions with new library functions
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=407198e17dc805...
Commit: 407198e17dc805dd9ce0583c8b1dbade71572af6
Parent: 753cb9204d24ceb4d9f8184ceb4c0262b9aacb42
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Jul 24 14:20:30 2012 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Jul 24 14:20:30 2012 -0500
TEST: Replace old sync test/wait functions with new library functions
Generic sync test/wait functions have replaced the old mirror/raid functions.
---
test/shell/lvconvert-mirror.sh | 10 ++----
test/shell/lvconvert-raid.sh | 74 ++++-----------------------------------
test/shell/lvcreate-raid.sh | 47 ++-----------------------
3 files changed, 15 insertions(+), 116 deletions(-)
diff --git a/test/shell/lvconvert-mirror.sh b/test/shell/lvconvert-mirror.sh
index 3f572e5..4d587d9 100644
--- a/test/shell/lvconvert-mirror.sh
+++ b/test/shell/lvconvert-mirror.sh
@@ -11,10 +11,6 @@
. lib/test
-wait_for_mirror_in_sync_() {
- while test $(get lv_field $1 copy_percent) != "100.00"; do sleep 1; done
-}
-
aux prepare_pvs 5 10
# FIXME - test fails with extent size < 512k
vgcreate -c n -s 512k $vg $(cat DEVICES)
@@ -93,7 +89,7 @@ should not lvconvert -m-1 $vg/$lv1 "$dev1"
lvconvert $vg/$lv1 # wait
lvconvert -m2 $vg/$lv1 "$dev1" "$dev2" "$dev4" "$dev3:0" # If the above "should" failed...
-wait_for_mirror_in_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert -m-1 $vg/$lv1 "$dev1"
check mirror_images_on $lv1 "$dev2" "$dev4"
lvconvert -m-1 $vg/$lv1 "$dev2"
@@ -215,7 +211,7 @@ lvremove -ff $vg
# "rhbz440405: lvconvert -m0 incorrectly fails if all PEs allocated"
lvcreate -l`pvs --noheadings -ope_count "$dev1"` -m1 -n $lv1 $vg "$dev1" "$dev2" "$dev3:0"
-wait_for_mirror_in_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert -m0 $vg/$lv1 "$dev1"
check linear $vg $lv1
lvremove -ff $vg
@@ -237,7 +233,7 @@ lvremove -ff $vg
# BZ 463272: disk log mirror convert option is lost if downconvert option is also given
lvcreate -l1 -m2 --corelog -n $lv1 $vg "$dev1" "$dev2" "$dev3"
-wait_for_mirror_in_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert -m1 --mirrorlog disk $vg/$lv1
check mirror $vg $lv1
not check mirror $vg $lv1 core
diff --git a/test/shell/lvconvert-raid.sh b/test/shell/lvconvert-raid.sh
index a4ebac9..c63c141 100644
--- a/test/shell/lvconvert-raid.sh
+++ b/test/shell/lvconvert-raid.sh
@@ -11,65 +11,6 @@
. lib/test
-# is_in_sync <VG/LV>
-is_in_sync_() {
- local a
- local b
- local idx
- local dm_name=$(echo $1 | sed s:-:--: | sed s:/:-:)
-
- if ! a=(`dmsetup status $dm_name`); then
- echo "Unable to get sync status of $1"
- return 1
- elif [ ${a[2]} = "snapshot-origin" ]; then
- if ! a=(`dmsetup status ${dm_name}-real`); then
- echo "Unable to get sync status of $1"
- return 1
- fi
- fi
-
- # 6th argument is the sync ratio for RAID and mirror
- if [ ${a[2]} = "raid" ]; then
- # Last argument is the sync ratio for RAID
- idx=$((${#a[@]} - 1))
- elif [ ${a[2]} = "mirror" ]; then
- # 4th Arg tells us how far to the sync ratio
- idx=$((${a[3]} + 4))
- else
- echo "Unable to get sync ratio for target type '${a[2]}'"
- return 1
- fi
- b=( $(echo ${a[$idx]} | sed s:/:' ':) )
-
- if [ ${b[0]} != ${b[1]} ]; then
- echo "$dm_name (${a[3]}) is not in-sync"
- return 1
- fi
-
- if [[ ${a[$(($idx - 1))]} =~ a ]]; then
- echo "$dm_name in-sync, but 'a' characters in health status"
- return 1
- fi
-
- if [ ${a[2]} = "raid" ]; then
- echo "$dm_name (${a[3]}) is in-sync"
- else
- echo "$dm_name (${a[2]}) is in-sync"
- fi
-}
-
-# wait_for_sync <VG/LV>
-wait_for_sync_() {
- local i
- for i in {1..100} ; do
- is_in_sync_ $1 && return
- sleep 1
- done
-
- echo "Sync is taking too long - assume stuck"
- return 1
-}
-
########################################################
# MAIN
########################################################
@@ -108,7 +49,7 @@ for i in 1 2 3 4; do
lvcreate -l 2 -n $lv1 $vg
else
lvcreate --type raid1 -m $(($i - 1)) -l 2 -n $lv1 $vg
- wait_for_sync_ $vg/$lv1
+ aux wait_for_sync $vg $lv1
fi
if $under_snap; then
@@ -129,7 +70,7 @@ done
# 3-way to 2-way convert while specifying devices
lvcreate --type raid1 -m 2 -l 2 -n $lv1 $vg $dev1 $dev2 $dev3
-wait_for_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert -m1 $vg/$lv1 $dev2
lvremove -ff $vg
@@ -142,7 +83,7 @@ lvremove -ff $vg
###########################################
# 3-way to 2-way/linear
lvcreate --type raid1 -m 2 -l 2 -n $lv1 $vg
-wait_for_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert --splitmirrors 1 -n $lv2 $vg/$lv1
check lv_exists $vg $lv1
check linear $vg $lv2
@@ -151,7 +92,7 @@ lvremove -ff $vg
# 2-way to linear/linear
lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
-wait_for_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert --splitmirrors 1 -n $lv2 $vg/$lv1
check linear $vg $lv1
check linear $vg $lv2
@@ -160,8 +101,9 @@ lvremove -ff $vg
# 3-way to linear/2-way
lvcreate --type raid1 -m 2 -l 2 -n $lv1 $vg
-wait_for_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
# FIXME: Can't split off a RAID1 from a RAID1 yet
+# 'should' results in "warnings"
should lvconvert --splitmirrors 2 -n $lv2 $vg/$lv1
#check linear $vg $lv1
#check lv_exists $vg $lv2
@@ -173,7 +115,7 @@ lvremove -ff $vg
###########################################
# 3-way to 2-way/linear
lvcreate --type raid1 -m 2 -l 2 -n $lv1 $vg
-wait_for_sync_ $vg/$lv1
+aux wait_for_sync $vg $lv1
lvconvert --splitmirrors 1 --trackchanges $vg/$lv1
check lv_exists $vg $lv1
check linear $vg ${lv1}_rimage_2
@@ -186,7 +128,7 @@ lvremove -ff $vg
###########################################
for i in 1 2 3 ; do
lvcreate --type mirror -m $i -l 2 -n $lv1 $vg
- wait_for_sync_ $vg/$lv1
+ aux wait_for_sync $vg $lv1
lvconvert --type raid1 $vg/$lv1
lvremove -ff $vg
done
diff --git a/test/shell/lvcreate-raid.sh b/test/shell/lvcreate-raid.sh
index b6792c5..c26f694 100644
--- a/test/shell/lvcreate-raid.sh
+++ b/test/shell/lvcreate-raid.sh
@@ -11,45 +11,6 @@
. lib/test
-# is_raid_in_sync <VG/LV>
-function is_raid_in_sync()
-{
- local dm_name=$(echo $1 | sed s:-:--: | sed s:/:-:)
- local a
- local b
- local idx
-
- if ! a=(`dmsetup status $dm_name`); then
- echo "Unable to get sync status of $1"
- exit 1
- fi
- idx=$((${#a[@]} - 1))
- b=(`echo ${a[$idx]} | sed s:/:' ':`)
-
- if [ ${b[0]} != ${b[1]} ]; then
- echo "$dm_name (${a[3]}) is not in-sync"
- return 1
- fi
-
- echo "$dm_name (${a[3]}) is in-sync"
- return 0
-}
-
-# wait_for_raid_sync <VG/LV>
-function wait_for_raid_sync()
-{
- local i=0
-
- while ! is_raid_in_sync $1; do
- sleep 1
- i=$(($i + 1))
- if [ $i -gt 500 ]; then
- echo "Sync is taking too long - assume stuck"
- exit 1
- fi
- done
-}
-
########################################################
# MAIN
########################################################
@@ -64,17 +25,17 @@ vgcreate -c n -s 512k $vg $(cat DEVICES)
# Create RAID1 (implicit 2-way)
lvcreate --type raid1 -l 2 -n $lv1 $vg
-wait_for_raid_sync $vg/$lv1
+aux wait_for_sync $vg $lv1
lvremove -ff $vg
# Create RAID1 (explicit 2-way)
lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
-wait_for_raid_sync $vg/$lv1
+aux wait_for_sync $vg $lv1
lvremove -ff $vg
# Create RAID1 (explicit 3-way)
lvcreate --type raid1 -m 2 -l 2 -n $lv1 $vg
-wait_for_raid_sync $vg/$lv1
+aux wait_for_sync $vg $lv1
lvremove -ff $vg
# Create RAID 4/5/6 (explicit 3-stripe + parity devs)
@@ -83,7 +44,7 @@ for i in raid4 \
raid6 raid6_zr raid6_nr raid6_nc; do
lvcreate --type $i -l 3 -i 3 -n $lv1 $vg
- wait_for_raid_sync $vg/$lv1
+ aux wait_for_sync $vg $lv1
lvremove -ff $vg
done
11 years, 9 months
master - TEST: Add library functions for checking and waiting for sync
by Jonathan Brassow
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=753cb9204d24ce...
Commit: 753cb9204d24ceb4d9f8184ceb4c0262b9aacb42
Parent: 5e36b86c46f04eddae2d4b1f826e1f24995b3636
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Jul 24 14:17:54 2012 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Jul 24 14:17:54 2012 -0500
TEST: Add library functions for checking and waiting for sync
Add 'in_sync' and 'wait_for_sync' to test and wait for synchronization
of a mirror or RAID logical volume.
---
test/lib/aux.sh | 12 ++++++++++++
test/lib/check.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index 91f54c9..4128f30 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -479,6 +479,18 @@ udev_wait() {
fi
}
+# wait_for_sync <VG/LV>
+wait_for_sync() {
+ local i
+ for i in {1..500} ; do
+ check in_sync $1 $2 && return
+ sleep .2
+ done
+
+ echo "Sync is taking too long - assume stuck"
+ return 1
+}
+
#
# Check wheter kernel [dm module] target exist
# at least in expected version
diff --git a/test/lib/check.sh b/test/lib/check.sh
index 9c78728..95bba4b 100644
--- a/test/lib/check.sh
+++ b/test/lib/check.sh
@@ -151,6 +151,51 @@ linear() {
$(lvl $lv -o+devices)
}
+# in_sync <VG> <LV>
+# Works for "mirror" and "raid*"
+in_sync() {
+ local a
+ local b
+ local idx
+ local type
+ local lvm_name="$1/$2"
+ local dm_name=$(echo $lvm_name | sed s:-:--: | sed s:/:-:)
+
+ if ! a=(`dmsetup status $dm_name`); then
+ die "Unable to get sync status of $1"
+ elif [ ${a[2]} = "snapshot-origin" ]; then
+ if ! a=(`dmsetup status ${dm_name}-real`); then
+ die "Unable to get sync status of $1"
+ fi
+ fi
+
+ if [ ${a[2]} = "raid" ]; then
+ # Last argument is the sync ratio for RAID
+ idx=$((${#a[@]} - 1))
+ type=${a[3]}
+ elif [ ${a[2]} = "mirror" ]; then
+ # 4th Arg tells us how far to the sync ratio
+ idx=$((${a[3]} + 4))
+ type=${a[2]}
+ else
+ die "Unable to get sync ratio for target type '${a[2]}'"
+ fi
+
+ b=( $(echo ${a[$idx]} | sed s:/:' ':) )
+
+ if [ ${b[0]} != ${b[1]} ]; then
+ echo "$lvm_name ($type) is not in-sync"
+ return 1
+ fi
+
+ if [[ ${a[$(($idx - 1))]} =~ a ]]; then
+ die "$lvm_name in-sync, but 'a' characters in health status"
+ fi
+
+ echo "$lvm_name ($type) is in-sync"
+ return 0
+}
+
active() {
local lv=$1/$2
(get lv_field $lv attr | grep "^....a...$" >/dev/null) || \
11 years, 9 months
master - config: fix one-node dumpconfig, add dm_config_write_one_node
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5e36b86c46f04e...
Commit: 5e36b86c46f04eddae2d4b1f826e1f24995b3636
Parent: 8d5ae472e5226f87175d51722fb5942c531bb8bb
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jul 20 15:53:04 2012 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jul 20 15:53:04 2012 +0200
config: fix one-node dumpconfig, add dm_config_write_one_node
A regression introduced in 2.02.89 (11e520256b3005ed813ce83f8770aaab74edef3f)
caused the lvm dumpconfig <node> to print out
the node as well as its subsequent siblings.
The information about "only_one" mode got lost.
Before this patch (just an example node):
# lvm dumpconfig global/use_lvmetad
use_lvmetad=1
thin_check_executable="/usr/sbin/thin_check"
thin_check_options="-q"
(...all nodes to the end of the section)
With this patch applied:
# lvm dumpconfig global/use_lvmetad
use_lvmetad=1
---
WHATS_NEW | 1 +
WHATS_NEW_DM | 1 +
lib/config/config.c | 2 +-
libdm/libdevmapper.h | 3 +++
libdm/libdm-config.c | 15 +++++++++++++--
5 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 4f23c39..aa26622 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
+ Fix dumpconfig <node> to print only <node> without its siblings (2.02.89).
Do not issue "Failed to handle a client connection" error if lvmetad killed.
Support changing of discard and zeroing for thin pool.
Report used discard for thin pool and volume.
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 416beca..0bfd016 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.76 -
===============================
+ Add dm_config_write_one_node to libdevmapper.
Add support for thin pool message release/reserve_metadata_snap.
Add support for thin pool discard and external origin.
Add configure --enable-udev-rule-exec-detection to detect exec path in rules.
diff --git a/lib/config/config.c b/lib/config/config.c
index 67a8b04..60ae6c8 100644
--- a/lib/config/config.c
+++ b/lib/config/config.c
@@ -473,7 +473,7 @@ int config_write(struct dm_config_tree *cft, const char *file,
}
} else while (argc--) {
if ((cn = dm_config_find_node(cft->root, *argv))) {
- if (!dm_config_write_node(cn, _putline_fn, fp)) {
+ if (!dm_config_write_one_node(cn, _putline_fn, fp)) {
log_error("Failure while writing to %s", file);
r = 0;
}
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 549a635..02bf421 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -1488,7 +1488,10 @@ struct dm_config_tree *dm_config_remove_cascaded_tree(struct dm_config_tree *cft
void dm_config_destroy(struct dm_config_tree *cft);
typedef int (*dm_putline_fn)(const char *line, void *baton);
+/* Write the node and any subsequent siblings it has. */
int dm_config_write_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton);
+/* Write given node only without subsequent siblings. */
+int dm_config_write_one_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton);
struct dm_config_node *dm_config_find_node(const struct dm_config_node *cn, const char *path);
int dm_config_has_node(const struct dm_config_node *cn, const char *path);
diff --git a/libdm/libdm-config.c b/libdm/libdm-config.c
index d9d3882..8457497 100644
--- a/libdm/libdm-config.c
+++ b/libdm/libdm-config.c
@@ -331,14 +331,15 @@ static int _write_config(const struct dm_config_node *n, int only_one,
return 1;
}
-int dm_config_write_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton)
+static int _write_node(const struct dm_config_node *cn, int only_one,
+ dm_putline_fn putline, void *baton)
{
struct output_line outline;
if (!(outline.mem = dm_pool_create("config_line", 1024)))
return_0;
outline.putline = putline;
outline.putline_baton = baton;
- if (!_write_config(cn, 0, &outline, 0)) {
+ if (!_write_config(cn, only_one, &outline, 0)) {
dm_pool_destroy(outline.mem);
return_0;
}
@@ -346,6 +347,16 @@ int dm_config_write_node(const struct dm_config_node *cn, dm_putline_fn putline,
return 1;
}
+int dm_config_write_one_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton)
+{
+ return _write_node(cn, 1, putline, baton);
+}
+
+int dm_config_write_node(const struct dm_config_node *cn, dm_putline_fn putline, void *baton)
+{
+ return _write_node(cn, 0, putline, baton);
+}
+
/*
* parser
11 years, 9 months
master - daemon-server: fix error message on daemon shutdown
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8d5ae472e5226f...
Commit: 8d5ae472e5226f87175d51722fb5942c531bb8bb
Parent: 48367c5be9b39cd118caeb6b8e554be347d2fd8c
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jul 19 16:45:08 2012 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jul 19 16:45:08 2012 +0200
daemon-server: fix error message on daemon shutdown
If a daemon (like lvmetad that is using common daemon-server code)
received a kill signal that was supposed to shut the daemon down,
a spurious message was issued: "Failed to handle a client connection".
This happened if the kill signal came just in the middle of waiting
for a client request in "select" - the request that was supposed to
be handled was blank at that moment of course.
---
WHATS_NEW | 1 +
libdaemon/server/daemon-server.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 925ae23..4f23c39 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
+ Do not issue "Failed to handle a client connection" error if lvmetad killed.
Support changing of discard and zeroing for thin pool.
Report used discard for thin pool and volume.
Add support for controlling discard behavior of thin pool.
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c
index 65b28e4..5ca9231 100644
--- a/libdaemon/server/daemon-server.c
+++ b/libdaemon/server/daemon-server.c
@@ -510,7 +510,7 @@ void daemon_start(daemon_state s)
if (select(FD_SETSIZE, &in, NULL, NULL, NULL) < 0 && errno != EINTR)
perror("select error");
if (FD_ISSET(s.socket_fd, &in))
- if (!handle_connect(s))
+ if (!_shutdown_requested && !handle_connect(s))
syslog(LOG_ERR, "Failed to handle a client connection.");
}
11 years, 9 months
master - thin: add lvchange for discard and zero change
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=48367c5be9b39c...
Commit: 48367c5be9b39cd118caeb6b8e554be347d2fd8c
Parent: 46b9cc1248941cc43f953e1a6b285ebe64a62077
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 28 14:52:23 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Jul 18 14:38:34 2012 +0200
thin: add lvchange for discard and zero change
Update lvchange to allow change of 'zero' flag for thinpool.
Add support for changing discard handling.
N.B. from/to ignore could be only changed for inactive pool.
---
WHATS_NEW | 1 +
man/lvchange.8.in | 14 ++++++++-
tools/commands.h | 7 +++-
tools/lvchange.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7811b6d..925ae23 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
+ Support changing of discard and zeroing for thin pool.
Report used discard for thin pool and volume.
Add support for controlling discard behavior of thin pool.
Detect features for new 1.1 thin pool target.
diff --git a/man/lvchange.8.in b/man/lvchange.8.in
index bf9ef48..beb77a8 100644
--- a/man/lvchange.8.in
+++ b/man/lvchange.8.in
@@ -16,6 +16,8 @@ lvchange \- change attributes of a logical volume
.RB [ \-d | \-\-debug ]
.RB [ \-\-deltag
.IR Tag ]
+.RB [ \-\-discard
+.RI { ignore | nopassdown | passdown }]
.RB [ \-\-resync ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
@@ -37,7 +39,9 @@ lvchange \- change attributes of a logical volume
.RI { ReadAheadSectors | auto | none }]
.RB [ \-\-refresh ]
.RB [ \-t | \-\-test ]
-.RB [ \-v | \-\-verbose]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-Z | \-\-zero
+.RI { y | n }]
.I LogicalVolumePath
.RI [ LogicalVolumePath ...]
.SH DESCRIPTION
@@ -68,6 +72,9 @@ logical volumes. It's only possible to change a non-contiguous
logical volume's allocation policy to contiguous, if all of the
allocated physical extents are already contiguous.
.TP
+.BR \-\-discard " {" \fIignore | \fInopassdown | \fIpassdown }
+Change discard behavior.
+.TP
.B \-\-resync
Forces the complete resynchronization of a mirror. In normal
circumstances you should not need this option because synchronization
@@ -142,6 +149,11 @@ If the logical volume is active, reload its metadata.
This is not necessary in normal operation, but may be useful
if something has gone wrong or if you're doing clustering
manually without a clustered lock manager.
+.TP
+.BR \-Z ", " \-\-zero " {" \fIy | \fIn }
+Set zeroing mode for thin pool. Note: already provisioned blocks from pool
+in non-zero mode are not cleared in unwritten parts when setting zero to
+\fIy\fP.
.SH Examples
Changes the permission on volume lvol1 in volume group vg00 to be read-only:
.sp
diff --git a/tools/commands.h b/tools/commands.h
index fe7403d..88c170a 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -69,6 +69,7 @@ xx(lvchange,
"\t[--deltag Tag]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
+ "\t[--discard {ignore|nopassdown|passdown}]\n"
"\t[--ignorelockingfailure]\n"
"\t[--ignoremonitoring]\n"
"\t[--monitor {y|n}]\n"
@@ -84,14 +85,16 @@ xx(lvchange,
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
"\t[-y|--yes]\n"
- "\t[--version]" "\n"
+ "\t[--version]\n"
+ "\t[-Z|--zero {y|n}]\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
alloc_ARG, autobackup_ARG, activate_ARG, available_ARG, contiguous_ARG,
force_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG, major_ARG,
minor_ARG, monitor_ARG, noudevsync_ARG, partial_ARG, permission_ARG,
persistent_ARG, poll_ARG, readahead_ARG, resync_ARG, refresh_ARG,
- addtag_ARG, deltag_ARG, sysinit_ARG, test_ARG, yes_ARG)
+ addtag_ARG, deltag_ARG, sysinit_ARG, test_ARG, yes_ARG,
+ discard_ARG, zero_ARG)
xx(lvconvert,
"Change logical volume layout",
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 9054ac7..a24d26c 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -89,6 +89,77 @@ out:
return r;
}
+static int lvchange_pool_update(struct cmd_context *cmd,
+ struct logical_volume *lv)
+{
+ int r = 0;
+ int update = 0;
+ unsigned val;
+ thin_discard_t discard;
+
+ if (!lv_is_thin_pool(lv)) {
+ log_error("Logical volume \"%s\" is not a thinpool.", lv->name);
+ return 0;
+ }
+
+ if (arg_count(cmd, discard_ARG)) {
+ discard = arg_uint_value(cmd, discard_ARG, 0);
+ if (discard != first_seg(lv)->discard) {
+ if (((discard == THIN_DISCARD_IGNORE) ||
+ (first_seg(lv)->discard == THIN_DISCARD_IGNORE)) &&
+ lv_is_active(lv))
+ log_error("Cannot change discard state for active "
+ "logical volume \"%s\".", lv->name);
+ else {
+ first_seg(lv)->discard = discard;
+ update++;
+ }
+ } else
+ log_error("Logical volume \"%s\" already uses discard %s.",
+ lv->name, get_pool_discard_name(discard));
+ }
+
+ if (arg_count(cmd, zero_ARG)) {
+ val = arg_uint_value(cmd, zero_ARG, 1);
+ if (val != first_seg(lv)->zero_new_blocks) {
+ first_seg(lv)->zero_new_blocks = val;
+ update++;
+ } else
+ log_error("Logical volume \"%s\" already %szero new blocks.",
+ lv->name, val ? "" : "does not ");
+ }
+
+ if (!update)
+ return 0;
+
+ log_very_verbose("Updating logical volume \"%s\" on disk(s).", lv->name);
+ if (!vg_write(lv->vg))
+ return_0;
+
+ if (!suspend_lv_origin(cmd, lv)) {
+ log_error("Failed to update active %s/%s (deactivation is needed).",
+ lv->vg->name, lv->name);
+ vg_revert(lv->vg);
+ goto out;
+ }
+
+ if (!vg_commit(lv->vg)) {
+ if (!resume_lv_origin(cmd, lv))
+ stack;
+ goto_out;
+ }
+
+ if (!resume_lv_origin(cmd, lv)) {
+ log_error("Problem reactivating %s.", lv->name);
+ goto out;
+ }
+
+ r = 1;
+out:
+ backup(lv->vg);
+ return r;
+}
+
static int lvchange_monitoring(struct cmd_context *cmd,
struct logical_volume *lv)
{
@@ -545,6 +616,8 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!(lv->vg->status & LVM_WRITE) &&
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
+ arg_count(cmd, discard_ARG) ||
+ arg_count(cmd, zero_ARG) ||
arg_count(cmd, alloc_ARG))) {
log_error("Only -a permitted with read-only volume "
"group \"%s\"", lv->vg->name);
@@ -670,6 +743,17 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
+ if (arg_count(cmd, discard_ARG) ||
+ arg_count(cmd, zero_ARG)) {
+ if (!archived && !archive(lv->vg)) {
+ stack;
+ return ECMD_FAILED;
+ }
+ archived = 1;
+ doit += lvchange_pool_update(cmd, lv);
+ docmds++;
+ }
+
/* add tag */
if (arg_count(cmd, addtag_ARG)) {
if (!archived && !archive(lv->vg)) {
@@ -747,7 +831,9 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) ||
- arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG);
+ arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG) ||
+ arg_count(cmd, discard_ARG) ||
+ arg_count(cmd, zero_ARG);
if (!update &&
!arg_count(cmd, activate_ARG) && !arg_count(cmd, refresh_ARG) &&
11 years, 9 months
master - thin: add reporting of discard for thin pool
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=46b9cc1248941c...
Commit: 46b9cc1248941cc43f953e1a6b285ebe64a62077
Parent: ebbf7d8e68f37c1a1e448a07676cca0a6e7f1430
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jul 9 16:48:28 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Jul 18 14:37:44 2012 +0200
thin: add reporting of discard for thin pool
New field "discard" is added for lvs reporting of lv segment.
Reported as one character:
(i)gnore
(n)opassdown
(p)assdown
lvs -o+discard
---
WHATS_NEW | 1 +
lib/report/columns.h | 1 +
lib/report/properties.c | 2 ++
lib/report/report.c | 30 ++++++++++++++++++++++++++++++
man/lvs.8.in | 1 +
5 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 41b52be..7811b6d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
+ Report used discard for thin pool and volume.
Add support for controlling discard behavior of thin pool.
Detect features for new 1.1 thin pool target.
Count percentage of completeness upwards when merging a snapshot volume.
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 579f029..7bcaaab 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -140,6 +140,7 @@ FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, region_size, "For mirror
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, chunksize, "For snapshots, the unit of data used when tracking changes.", 0)
FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, chunk_size, "For snapshots, the unit of data used when tracking changes.", 0)
FIELD(SEGS, seg, NUM, "#Thins", list, 4, thincount, thin_count, "For thin pools, the number of thin volumes in this pool.", 0)
+FIELD(SEGS, seg, NUM, "Dis", list, 3, discard, discard, "For thin pools, discard handling (i)ignore, (n)o_passdown, (p)assdown.", 0)
FIELD(SEGS, seg, NUM, "Zero", list, 4, thinzero, zero, "For thin pools, if zeroing is enabled.", 0)
FIELD(SEGS, seg, NUM, "TransId", list, 4, transactionid, transaction_id, "For thin pools, the transaction id.", 0)
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, seg_start, "Offset within the LV to the start of the segment in current units.", 0)
diff --git a/lib/report/properties.c b/lib/report/properties.c
index 0855f95..d78ad64 100644
--- a/lib/report/properties.c
+++ b/lib/report/properties.c
@@ -277,6 +277,8 @@ GET_LVSEG_NUM_PROPERTY_FN(zero, lvseg->zero_new_blocks)
#define _zero_set _not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(transaction_id, lvseg->transaction_id)
#define _transaction_id_set _not_implemented_set
+GET_LVSEG_NUM_PROPERTY_FN(discard, lvseg->discard)
+#define _discard_set _not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(seg_start, lvseg_start(lvseg))
#define _seg_start_set _not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(seg_start_pe, lvseg->le)
diff --git a/lib/report/report.c b/lib/report/report.c
index 97e75b6..3121db3 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -564,6 +564,36 @@ static int _transactionid_disp(struct dm_report *rh, struct dm_pool *mem,
return dm_report_field_uint64(rh, field, &seg->transaction_id);
}
+static int _discard_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ static const struct {
+ const char c[2];
+ unsigned val;
+ thin_discard_t discard;
+ } const arr[] = {
+ { "p", 0, THIN_DISCARD_PASSDOWN },
+ { "n", 1, THIN_DISCARD_NO_PASSDOWN },
+ { "i", 2, THIN_DISCARD_IGNORE },
+ { "" }
+ };
+ const struct lv_segment *seg = (const struct lv_segment *) data;
+ unsigned i = 0;
+
+ if (seg_is_thin_volume(seg))
+ seg = first_seg(seg->pool_lv);
+
+ if (seg_is_thin_pool(seg)) {
+ while (arr[i].c[0] && seg->discard != arr[i].discard)
+ i++;
+
+ dm_report_field_set_value(field, arr[i].c, &arr[i].val);
+ } else
+ dm_report_field_set_value(field, "", NULL);
+
+ return 1;
+}
static int _originsize_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
diff --git a/man/lvs.8.in b/man/lvs.8.in
index 9a4bb4d..f492835 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -80,6 +80,7 @@ convert_lv,
copy_percent,
data_lv,
devices,
+discard,
lv_attr,
lv_host,
lv_kernel_major,
11 years, 9 months
master - thin: add discard support for thin pool
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ebbf7d8e68f37c...
Commit: ebbf7d8e68f37c1a1e448a07676cca0a6e7f1430
Parent: 260e8f24768d7a6e7c6a8018b5c2b08e7a35e35c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 28 14:47:34 2012 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Jul 18 14:36:57 2012 +0200
thin: add discard support for thin pool
Add arg support for discard.
Add discard ignore, nopassdown, passdown (=default) support.
Flags could be set per pool.
lvcreate [--discard {ignore|no_passdown|passdown}] vg/thinlv
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 9 +++++++
lib/metadata/thin_manip.c | 35 ++++++++++++++++++++++++++++++
lib/thin/thin.c | 44 ++++++++++++++++++++++++++++++++++++++
man/lvcreate.8.in | 6 +++++
tools/args.h | 1 +
tools/commands.h | 6 ++++-
tools/lvmcmdline.c | 13 +++++++++++
tools/tools.h | 1 +
9 files changed, 115 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 54ae73b..41b52be 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.97 -
===============================
+ Add support for controlling discard behavior of thin pool.
Detect features for new 1.1 thin pool target.
Count percentage of completeness upwards when merging a snapshot volume.
Skip activation when using vg/lvchange --sysinit -a ay and lvmetad is active.
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 8c655c7..d2afdb1 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -166,6 +166,12 @@ typedef enum {
DONT_PROMPT_OVERRIDE = 2 /* Skip prompt + override a second condition */
} force_t;
+typedef enum {
+ THIN_DISCARD_PASSDOWN,
+ THIN_DISCARD_NO_PASSDOWN,
+ THIN_DISCARD_IGNORE,
+} thin_discard_t;
+
struct cmd_context;
struct format_handler;
struct labeller;
@@ -347,6 +353,7 @@ struct lv_segment {
uint64_t transaction_id; /* For thin_pool, thin */
uint64_t low_water_mark; /* For thin_pool */
unsigned zero_new_blocks; /* For thin_pool */
+ thin_discard_t discard; /* For thin_pool */
struct dm_list thin_messages; /* For thin_pool */
struct logical_volume *pool_lv; /* For thin */
uint32_t device_id; /* For thin, 24bit */
@@ -558,6 +565,8 @@ uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size,
uint32_t extent_size);
int update_pool_lv(struct logical_volume *lv, int activate);
+int get_pool_discard(const char *str, thin_discard_t *discard);
+const char *get_pool_discard_name(thin_discard_t discard);
/*
* Activation options
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index ae8d509..8d1744c 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -428,3 +428,38 @@ int update_pool_lv(struct logical_volume *lv, int activate)
return 1;
}
+
+int get_pool_discard(const char *str, thin_discard_t *discard)
+{
+ if (!strcasecmp(str, "passdown"))
+ *discard = THIN_DISCARD_PASSDOWN;
+ /* Allow some variation in thin parameter */
+ else if (!strcasecmp(str, "nopassdown") ||
+ !strcasecmp(str, "no-passdown") ||
+ !strcasecmp(str, "no_passdown"))
+ *discard = THIN_DISCARD_NO_PASSDOWN;
+ else if (!strcasecmp(str, "ignore"))
+ *discard = THIN_DISCARD_IGNORE;
+ else {
+ log_error("Thin pool discard type %s is unknown.", str);
+ return 0;
+ }
+
+ return 1;
+}
+
+const char *get_pool_discard_name(thin_discard_t discard)
+{
+ switch (discard) {
+ case THIN_DISCARD_PASSDOWN:
+ return "passdown";
+ case THIN_DISCARD_NO_PASSDOWN:
+ return "nopassdown";
+ case THIN_DISCARD_IGNORE:
+ return "ignore";
+ }
+
+ log_error(INTERNAL_ERROR "Uknown discard type.");
+
+ return NULL;
+}
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 974293c..27ce6f5 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -39,6 +39,10 @@
log_error(t " segment %s of logical volume %s.", ## p, \
dm_config_parent_name(sn), seg->lv->name), 0;
+static int _thin_target_present(struct cmd_context *cmd,
+ const struct lv_segment *seg,
+ unsigned *attributes);
+
static const char *_thin_pool_name(const struct lv_segment *seg)
{
return seg->segtype->name;
@@ -83,6 +87,7 @@ static int _thin_pool_text_import(struct lv_segment *seg,
{
const char *lv_name;
struct logical_volume *pool_data_lv, *pool_metadata_lv;
+ const char *discard = NULL;
if (!dm_config_get_str(sn, "metadata", &lv_name))
return SEG_LOG_ERROR("Metadata must be a string in");
@@ -109,6 +114,15 @@ static int _thin_pool_text_import(struct lv_segment *seg,
if (!dm_config_get_uint32(sn, "chunk_size", &seg->chunk_size))
return SEG_LOG_ERROR("Could not read chunk_size");
+ if (dm_config_has_node(sn, "discard") &&
+ !dm_config_get_str(sn, "discard", &discard))
+ return SEG_LOG_ERROR("Could not read discard for");
+
+ if (!discard)
+ seg->discard = THIN_DISCARD_PASSDOWN;
+ else if (!get_pool_discard(discard, &seg->discard))
+ return SEG_LOG_ERROR("Discard option unsupported for");
+
if (dm_config_has_node(sn, "low_water_mark") &&
!dm_config_get_uint64(sn, "low_water_mark", &seg->low_water_mark))
return SEG_LOG_ERROR("Could not read low_water_mark");
@@ -149,6 +163,19 @@ static int _thin_pool_text_export(const struct lv_segment *seg, struct formatter
outsize(f, (uint64_t) seg->chunk_size,
"chunk_size = %u", seg->chunk_size);
+ switch (seg->discard) {
+ case THIN_DISCARD_PASSDOWN:
+ /* nothing to do */
+ break;
+ case THIN_DISCARD_NO_PASSDOWN:
+ case THIN_DISCARD_IGNORE:
+ outf(f, "discard = \"%s\"", get_pool_discard_name(seg->discard));
+ break;
+ default:
+ log_error(INTERNAL_ERROR "Unexportable discard.");
+ return 0;
+ }
+
if (seg->low_water_mark)
outf(f, "low_water_mark = %" PRIu64, seg->low_water_mark);
@@ -207,11 +234,16 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
struct dm_tree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count __attribute__((unused)))
{
+ static int _no_discard = 0;
char *metadata_dlid, *pool_dlid;
const struct lv_thin_message *lmsg;
const struct logical_volume *origin;
struct lvinfo info;
uint64_t transaction_id = 0;
+ unsigned attr;
+
+ if (!_thin_target_present(cmd, seg, &attr))
+ return_0;
if (!laopts->real_pool) {
if (!(pool_dlid = build_dm_uuid(mem, seg->lv->lvid.s, "tpool"))) {
@@ -246,6 +278,18 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
seg->zero_new_blocks ? 0 : 1))
return_0;
+ if (seg->discard != THIN_DISCARD_PASSDOWN) {
+ if (attr & THIN_FEATURE_DISCARD) {
+ /* FIXME: Check whether underlaying dev supports discard */
+ if (!dm_tree_node_set_thin_pool_discard(node,
+ seg->discard == THIN_DISCARD_IGNORE,
+ seg->discard == THIN_DISCARD_NO_PASSDOWN))
+ return_0;
+ } else
+ log_warn_suppress(_no_discard++, "WARNING: Thin pool target does "
+ "not support discard (needs kernel >= 3.4).");
+ }
+
/*
* Add messages only for activation tree.
* Otherwise avoid checking for existence of suspended origin.
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 2917775..1911605 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -54,6 +54,8 @@ lvcreate \- create a logical volume in an existing volume group
.RB [ \-T | \-\-thin
.RB [ \-c | \-\-chunksize
.IR ChunkSize ]
+.RB [ \-\-discard
+.RI { ignore | nopassdown | passdown }]
.RB [ \-\-poolmetadatasize
.IR MetadataSize [ bBsSkKmMgG ]]]
.RB [ \-\-thinpool
@@ -138,6 +140,10 @@ Sets or resets the contiguous allocation policy for
logical volumes. Default is no contiguous allocation based
on a next free principle.
.TP
+.BR \-\-discard " {" \fIignore | \fInopassdown | \fIpassdown }
+Set discard behavior.
+Default is \fIpassdown\fP.
+.TP
.BR \-i ", " \-\-stripes " " \fIStripes
Gives the number of stripes.
This is equal to the number of physical volumes to scatter
diff --git a/tools/args.h b/tools/args.h
index 2ce3c36..4909f9e 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -72,6 +72,7 @@ arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", size_mb_arg, 0)
arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0)
arg(poll_ARG, '\0', "poll", yes_no_arg, 0)
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0)
+arg(discard_ARG, '\0', "discard", discard_arg, 0)
arg(stripes_long_ARG, '\0', "stripes", int_arg, 0)
arg(sysinit_ARG, '\0', "sysinit", NULL, 0)
arg(thinpool_ARG, '\0', "thinpool", string_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 3454951..fe7403d 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -177,6 +177,10 @@ xx(lvcreate,
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
+ "\t[-T|--thin [-c|--chunksize ChunkSize]\n"
+ "\t [--discard {ignore|nopassdown|passdown}]\n"
+ "\t [--poolmetadatasize MetadataSize[bBsSkKmMgG]]]\n"
+ "\t[--thinpool ThinPoolLogicalVolume{Name|Path}]\n"
"\t[-t|--test]\n"
"\t[--type VolumeType]\n"
"\t[-v|--verbose]\n"
@@ -215,7 +219,7 @@ xx(lvcreate,
"\t[PhysicalVolumePath...]\n\n",
addtag_ARG, alloc_ARG, autobackup_ARG, activate_ARG, available_ARG,
- chunksize_ARG, contiguous_ARG, corelog_ARG, extents_ARG,
+ chunksize_ARG, contiguous_ARG, corelog_ARG, extents_ARG, discard_ARG,
ignoremonitoring_ARG, major_ARG, minor_ARG, mirrorlog_ARG, mirrors_ARG,
monitor_ARG, name_ARG, nosync_ARG, noudevsync_ARG, permission_ARG,
persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG, snapshot_ARG,
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 16e15a1..0e6a51c 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -216,6 +216,19 @@ int activation_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_v
return 1;
}
+int discard_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
+{
+ thin_discard_t discard;
+
+ if (!get_pool_discard(av->value, &discard))
+ return_0;
+
+ av->i_value = discard;
+ av->ui_value = discard;
+
+ return 1;
+}
+
int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av)
{
return get_format_by_name(cmd, av->value) ? 1 : 0;
diff --git a/tools/tools.h b/tools/tools.h
index 7a44651..f92abd5 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -139,6 +139,7 @@ void usage(const char *name);
/* the argument verify/normalise functions */
int yes_no_arg(struct cmd_context *cmd, struct arg_values *av);
int activation_arg(struct cmd_context *cmd, struct arg_values *av);
+int discard_arg(struct cmd_context *cmd, struct arg_values *av);
int size_kb_arg(struct cmd_context *cmd, struct arg_values *av);
int size_mb_arg(struct cmd_context *cmd, struct arg_values *av);
int int_arg(struct cmd_context *cmd, struct arg_values *av);
11 years, 9 months