All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] fsadm: add support to resize & check btrfs filesystem
@ 2021-06-30 14:32 Heming Zhao
  2021-06-30 14:32 ` [PATCH 2/3] man: add support for btrfs Heming Zhao
  2021-06-30 14:32 ` [PATCH 3/3] tests: new test suite of fsadm " Heming Zhao
  0 siblings, 2 replies; 3+ messages in thread
From: Heming Zhao @ 2021-06-30 14:32 UTC (permalink / raw)
  To: lvm-devel

resize:
btrfs volume may spanning across multiple block devices. resize action should
specific subvolume to not to break the filesystem on LV about to get resized
with lvresize.

this patch finds the mount point first and resizes the filesystem after
getting the device id since there are maybe several devices underneath btrfs
filesystem

check:
check the data integrity.
this patch mounts the device first and then runs `btrfs filesystem scrub
start -B` command

refer legacy patches:
- Ondrej Kozina <okozina@redhat.com>
  https://listman.redhat.com/archives/lvm-devel/2012-November/msg00052.html
- Lidong Zhong <lzhong@suse.com>
  https://listman.redhat.com/archives/lvm-devel/2015-March/msg00053.html

Signed-off-by: Heming Zhao <heming.zhao@suse.com>
---
 scripts/fsadm.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 2 deletions(-)

diff --git a/scripts/fsadm.sh b/scripts/fsadm.sh
index 9ae422f55edf..a7345c503f77 100755
--- a/scripts/fsadm.sh
+++ b/scripts/fsadm.sh
@@ -22,6 +22,7 @@
 # ext2/ext3/ext4: resize2fs, tune2fs
 # reiserfs: resize_reiserfs, reiserfstune
 # xfs: xfs_growfs, xfs_info
+# btrfs: btrfs
 #
 # Return values:
 #   0 success
@@ -59,6 +60,7 @@ XFS_CHECK="xfs_check"
 # XFS_REPAIR -n is used when XFS_CHECK is not found
 XFS_REPAIR="xfs_repair"
 CRYPTSETUP="cryptsetup"
+BTRFS="btrfs"
 
 # user may override lvm location by setting LVM_BINARY
 LVM=${LVM_BINARY:-lvm}
@@ -78,6 +80,9 @@ BLOCKCOUNT=
 MOUNTPOINT=
 MOUNTED=
 REMOUNT=
+FINDMNT=
+UUID=
+BTRFS_DEVID=
 PROCDIR="/proc"
 PROCMOUNTS="$PROCDIR/mounts"
 PROCSELFMOUNTINFO="$PROCDIR/self/mountinfo"
@@ -237,6 +242,33 @@ detect_fs() {
 	verbose "\"$FSTYPE\" filesystem found on \"$VOLUME\"."
 }
 
+check_findmnt() {
+	FINDMNT=$(which findmnt 2>$NULL)
+	test -n "$FINDMNT"
+}
+
+detect_fs_uuid() {
+	UUID=$($BLKID -o value -c $NULL -s UUID "$VOLUME" 2>$NULL)
+	test -n "$UUID"
+}
+
+#find the mountpoint of this device
+detect_mounted_findmnt() {
+	local TMP
+	local STR_IFS=$IFS
+	IFS=" $(echo -n -e '\t')"
+
+	read -r TMP<<EOF
+$($FINDMNT -nuP -o TARGET,UUID 2>$NULL | $GREP "$UUID")
+EOF
+
+	TMP=${TMP##*TARGET=\"}
+	TMP=${TMP%%\"*}
+	MOUNTED=$TMP
+	test -n "$MOUNTED"
+
+	IFS=$STR_IFS
+}
 
 # Check that passed mounted MAJOR:MINOR is not matching $MAJOR:MINOR of resized $VOLUME
 validate_mounted_major_minor() {
@@ -365,7 +397,11 @@ detect_mounted_with_proc_mounts() {
 # check if the given device is already mounted and where
 # FIXME: resolve swap usage and device stacking
 detect_mounted() {
-	if test -e "$PROCSELFMOUNTINFO"; then
+	if test "$FSTYPE" = "btrfs" ; then
+		check_findmnt || error "Need 'findmnt' utility to work with btrfs filesystem"
+		detect_fs_uuid || verbose "Can't get fs UUID from \"$VOLUME\" volume"
+		detect_mounted_findmnt
+	elif test -e "$PROCSELFMOUNTINFO"; then
 		detect_mounted_with_proc_self_mountinfo
 	elif test -e "$PROCMOUNTS"; then
 		detect_mounted_with_proc_mounts
@@ -662,6 +698,47 @@ resize_crypt() {
 	dry "$CRYPTSETUP" resize "$1" --size $CRYPT_RESIZE_BLOCKS || error "$CRYPTSETUP failed to resize device $1"
 }
 
+########################
+# Resize btrfs filesystem
+# - mounted for upsize/downsize
+# - cannot resize when unmounted
+########################
+resize_btrfs() {
+	detect_mounted
+	MOUNTPOINT=$MOUNTED
+	if [ -z "$MOUNTED" ]; then
+		MOUNTPOINT=$TEMPDIR
+		temp_mount || error "Cannot mount Btrfs filesystem"
+	fi
+
+	verbose "Parsing $BTRFS filesystem show \"$MOUNTPOINT\""
+	for i in $(LC_ALL=C "$BTRFS" filesystem show "$MOUNTPOINT"); do
+		case "$i" in
+		  *"$VOLUME") BTRFS_DEVID=${i##*devid};;
+		esac
+	done
+
+	# If dev doesn't locate in "/dev", 'btrfs filesystem show' will mistakely
+	# report path. Below is a work around to get correct lvm dev path.
+	if [ -z "$BTRFS_DEVID" ];then
+		for i in $(LC_ALL=C "$BTRFS" filesystem show "$MOUNTPOINT"); do
+			case "$i" in
+				*" path "*)
+					path_str=${i##*path}
+					path_str=$(echo $path_str|sed 's/^[ \t]*//g'|sed 's/[ \t]*$'//g)
+					result=$(echo $VOLUME | grep -E "${path_str}$")
+					test -n "$result" && BTRFS_DEVID=${i##*devid}
+					;;
+			esac
+		done
+	fi
+	BTRFS_DEVID=${BTRFS_DEVID%%size*}
+	BTRFS_DEVID=$(echo $BTRFS_DEVID|sed 's/^[ \t]*//g'|sed 's/[ \t]*$'//g)
+	decode_size $1 1
+	verbose "Resizing filesystem on device \"$VOLUME\" to $NEWSIZE bytes(btrfs devid: $BTRFS_DEVID) "
+	dry "$BTRFS" filesystem resize "$BTRFS_DEVID":"$NEWSIZE" "$MOUNTPOINT"
+}
+
 ####################
 # Resize filesystem
 ####################
@@ -685,6 +762,7 @@ resize() {
 	  "crypto_LUKS")
 		which "$CRYPTSETUP" >"$NULL" 2>&1 || error "$CRYPTSETUP utility required to resize LUKS volume"
 		CMD=resize_luks ;;
+	  "btrfs") CMD=resize_btrfs ;;
 	  *) error "Filesystem \"$FSTYPE\" on device \"$VOLUME\" is not supported by this tool." ;;
 	esac
 
@@ -762,6 +840,12 @@ check() {
 		which "$CRYPTSETUP" >"$NULL" 2>&1 || error "$CRYPTSETUP utility required."
 		check_luks || error "Crypto luks check failed."
 		;;
+	  "btrfs") #mount the device first and then run scrub
+		 MOUNTPOINT=$TEMPDIR
+		 temp_mount || error "Cannot mount btrfs filesystem"
+		 dry "$BTRFS" scrub start -B "$VOLUME"
+		 test "$MOUNTPOINT" = "$TEMPDIR" && MOUNTPOINT="" temp_umount
+		 ;;
 	  *)
 		error "Filesystem \"$FSTYPE\" on device \"$VOLUME\" is not supported by this tool." ;;
 	esac
@@ -780,7 +864,7 @@ test -n "${FSADM_RUNNING-}" && exit 0
 for i in "$TUNE_EXT" "$RESIZE_EXT" "$TUNE_REISER" "$RESIZE_REISER" \
 	"$TUNE_XFS" "$RESIZE_XFS" "$MOUNT" "$UMOUNT" "$MKDIR" \
 	"$RMDIR" "$BLOCKDEV" "$BLKID" "$GREP" "$READLINK" \
-	"$DATE" "$FSCK" "$XFS_CHECK" "$XFS_REPAIR" "$LVM" ; do
+	"$DATE" "$FSCK" "$XFS_CHECK" "$XFS_REPAIR" "$LVM" "$BTRFS" ; do
 	test -n "$i" || error "Required command definitions in the script are missing!"
 done
 
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/3] man: add support for btrfs
  2021-06-30 14:32 [PATCH 1/3] fsadm: add support to resize & check btrfs filesystem Heming Zhao
@ 2021-06-30 14:32 ` Heming Zhao
  2021-06-30 14:32 ` [PATCH 3/3] tests: new test suite of fsadm " Heming Zhao
  1 sibling, 0 replies; 3+ messages in thread
From: Heming Zhao @ 2021-06-30 14:32 UTC (permalink / raw)
  To: lvm-devel

Signed-off-by: Heming Zhao <heming.zhao@suse.com>
---
 man/fsadm.8_main | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/man/fsadm.8_main b/man/fsadm.8_main
index dfff5bb97021..ad924ac3a304 100644
--- a/man/fsadm.8_main
+++ b/man/fsadm.8_main
@@ -31,6 +31,7 @@ It tries to use the same API for
 .BR ext2 ,
 .BR ext3 ,
 .BR ext4 ,
+.BR btrfs ,
 .BR ReiserFS
 and
 .BR XFS
@@ -119,6 +120,9 @@ Defaults to "\fI/dev\fP" and must be an absolute path.
 .BR tune2fs (8),
 .BR resize2fs (8),
 .P
+.BR btrfs (8),
+.BR btrfs-scrub (8),
+.P
 .BR reiserfstune (8),
 .BR resize_reiserfs (8),
 .P
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 3/3] tests: new test suite of fsadm for btrfs
  2021-06-30 14:32 [PATCH 1/3] fsadm: add support to resize & check btrfs filesystem Heming Zhao
  2021-06-30 14:32 ` [PATCH 2/3] man: add support for btrfs Heming Zhao
@ 2021-06-30 14:32 ` Heming Zhao
  1 sibling, 0 replies; 3+ messages in thread
From: Heming Zhao @ 2021-06-30 14:32 UTC (permalink / raw)
  To: lvm-devel

refer legacy patche:
- Ondrej Kozina <okozina@redhat.com>
  https://listman.redhat.com/archives/lvm-devel/2012-November/msg00055.html

Signed-off-by: Heming Zhao <heming.zhao@suse.com>
---
 test/shell/fsadm-btrfs.sh | 165 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 165 insertions(+)
 create mode 100644 test/shell/fsadm-btrfs.sh

diff --git a/test/shell/fsadm-btrfs.sh b/test/shell/fsadm-btrfs.sh
new file mode 100644
index 000000000000..cd83a95ace41
--- /dev/null
+++ b/test/shell/fsadm-btrfs.sh
@@ -0,0 +1,165 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2012 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
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+test_description='Exercise fsadm btrfs resize'
+
+. lib/inittest
+
+aux prepare_vg 1 1024
+
+# set to "skip" to avoid testing given fs and test warning result
+# i.e. check_btrfs=skip
+check_btrfs=
+
+which mkfs.btrfs || check_btrfs=${check_btrfs:-mkfs.btrfs}
+which btrfs	 || check_btrfs=${check_btrfs:-btrfs}
+
+vg_lv=$vg/$lv1
+vg_lv2=$vg/${lv1}bar
+vg_lv3=$vg/${lv1}bar2
+dev_vg_lv="$DM_DEV_DIR/$vg_lv"
+dev_vg_lv2="$DM_DEV_DIR/$vg_lv2"
+dev_vg_lv3="$DM_DEV_DIR/$vg_lv3"
+mount_dir="mnt"
+mount_space_dir="mnt space dir"
+# for recursive call
+export LVM_BINARY=$(which lvm)
+
+test ! -d "$mount_dir" && mkdir "$mount_dir"
+test ! -d "$mount_space_dir" && mkdir "$mount_space_dir"
+
+cleanup_mounted_and_teardown()
+{
+	umount "$mount_dir" || true
+	umount "$mount_space_dir" || true
+	aux teardown
+}
+
+check_missing_btrfs()
+{
+	eval local t=$check_btrfs
+	test -z "$t" && return 0
+	test "$t" = skip && return 1
+	# trick for warning test
+	echo "WARNING: fsadm test skipped btrfs tests, $t tool is missing"
+	return 1
+}
+
+fscheck_btrfs() {
+	btrfsck "$1"
+}
+scrub_btrfs() {
+	btrfs scrub start -B "$1"
+}
+
+# btrfs minimal size calculation is complex, we use 64M here.
+lvcreate -n $lv1 -L64M $vg
+lvcreate -n ${lv1}bar -L64M $vg
+lvcreate -n ${lv1}bar2 -L64M $vg
+trap 'cleanup_mounted_and_teardown' EXIT
+
+single_device_test() {
+	mkfs.btrfs -m single "$dev_vg_lv"
+	mkfs.btrfs -m single "$dev_vg_lv2"
+
+	# kernel limits 256 MB as minimal btrfs resizable size
+	# you can grow fs from 30MB->256MB
+	# but you can't grow from 30MB->180MB
+	fsadm --lvresize resize $vg_lv 256M
+	fsadm --lvresize resize $vg_lv2 256M
+
+	not fsadm -y --lvresize resize $vg_lv 200M
+	lvresize -L+10M -r $vg_lv
+	lvreduce -L256M -r $vg_lv
+	fscheck_btrfs $dev_vg_lv
+
+	mount "$dev_vg_lv" "$mount_dir"
+	mount "$dev_vg_lv2" "$mount_space_dir"
+
+	not fsadm -y --lvresize resize $vg_lv 200M
+	lvresize -L+10M -r $vg_lv
+	lvreduce -L256M -r $vg_lv
+	scrub_btrfs $dev_vg_lv
+	umount "$mount_dir"
+
+	not fsadm -y --lvresize resize $vg_lv2 200M
+	lvresize -L+10M -r $vg_lv2
+	lvreduce -L256M -r $vg_lv2
+	scrub_btrfs $dev_vg_lv2
+	umount "$mount_space_dir"
+}
+
+multiple_devices_test() {
+	mkfs.btrfs -m single -d single -f "$dev_vg_lv" "$dev_vg_lv2" "$dev_vg_lv3"
+
+	fsadm -y --lvresize resize $vg_lv 256M
+	fsadm -y --lvresize resize $vg_lv2 256M
+	fsadm -y --lvresize resize $vg_lv3 256M
+
+	# check if fsadm is able to get/resize btrfs on
+	# the right device
+	lvresize -L+150M $vg_lv
+	fsadm -y resize $vg_lv 300M
+	# no space to extend, so failed
+	not fsadm -y resize $vg_lv2 300M
+	not fsadm -y resize $vg_lv3 300M
+	lvreduce -y -L256M -r $vg_lv
+
+	lvresize -L+150M $vg_lv2
+	fsadm -y resize $vg_lv2 300M
+	not fsadm -y resize $vg_lv3 300M
+	not fsadm -y resize $vg_lv 300M
+	lvreduce -y -L256M -r $vg_lv2
+
+	lvresize -L+150M $vg_lv3
+	fsadm -y resize $vg_lv3 300M
+	not fsadm -y resize $vg_lv2 300M
+	not fsadm -y resize $vg_lv 300M
+	lvreduce -y -L256M -r $vg_lv3
+	fscheck_btrfs $dev_vg_lv
+
+	# repeat with mounted fs
+	mount "$dev_vg_lv" "$mount_dir"
+	mount "$dev_vg_lv2" "$mount_space_dir"
+
+	lvresize -L300M $vg_lv
+	fsadm -y resize $vg_lv 300M
+	not fsadm -y resize $vg_lv2 300M
+	not fsadm -y resize $vg_lv3 300M
+	lvreduce -y -L256M -r $vg_lv
+
+	lvresize -L300M $vg_lv2
+	fsadm -y resize $vg_lv2 300M
+	not fsadm -y resize $vg_lv3 300M
+	not fsadm -y resize $vg_lv 300M
+	lvreduce -y -L256M -r $vg_lv2
+
+	lvresize -L300M $vg_lv3
+	fsadm -y resize $vg_lv3 300M
+	not fsadm -y resize $vg_lv2 300M
+	not fsadm -y resize $vg_lv 300M
+	lvreduce -y -L256M -r $vg_lv3
+
+	scrub_btrfs $dev_vg_lv
+	umount "$mount_dir"
+	umount "$mount_space_dir"
+
+	lvresize -nf -L300M $vg_lv
+	lvresize -nf -L300M $vg_lv2
+}
+
+if check_missing_btrfs; then
+
+	single_device_test
+	multiple_devices_test
+fi
+
+vgremove -ff $vg
-- 
1.8.3.1




^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-06-30 14:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-30 14:32 [PATCH 1/3] fsadm: add support to resize & check btrfs filesystem Heming Zhao
2021-06-30 14:32 ` [PATCH 2/3] man: add support for btrfs Heming Zhao
2021-06-30 14:32 ` [PATCH 3/3] tests: new test suite of fsadm " Heming Zhao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.