Thread (8 messages) 8 messages, 4 authors, 2022-01-05

Script to test allocation_hint - [Was Re: [PATCH 0/2][V9] btrfs-progs: allocation_hint disk property]

From: Goffredo Baroncelli <hidden>
Date: 2021-12-17 18:53:16

On 12/17/21 19:47, Goffredo Baroncelli wrote:
From: Goffredo Baroncelli <redacted>

This patches set is the userspace portion of the serie
"[PATCH V9] btrfs: allocation_hint mode".

Look this patches set for further information.

G.Baroncelli

Goffredo Baroncelli (2):
   btrfs-progs: new "allocation_hint" property.
   Update man page for allocator_hint property.

  Documentation/btrfs-property.asciidoc |  17 +++
  cmds/property.c                       | 204 ++++++++++++++++++++++++++
  kernel-shared/ctree.h                 |  13 ++
  3 files changed, 234 insertions(+)

Below the script that I used to stress this patch. As is is not integrable in xfstest, but for now is better than nothing :-)

-----------
#!/bin/bash

#size of disk, smaller -> faster
MAXSIZE=$((1*1024*1024*1024))
MNT=mnt
BTRFS=./btrfs-hint
UUID=292afefb-6e8c-4fb3-9d12-8c4ecb1f237c

cleanup_all() {
	umount $MNT
	losetup -D
}

raise() {
	echo 1>&2 "$@"
	exit 100
}

xmount() {
	#mount -o allocation_hint=1 "$1" "$2"
	mount  "$1" "$2"
}

create_loops() {
	[ -n "$1" ] || {
		cleanup_all
		raise "Create_loops, missing an argument"
	}
	ret=""
	for i in $(seq "$1"); do
		disk=disk-$i.img
		rm -rf $disk
		truncate -s ${MAXSIZE} $disk
		losetup /dev/loop$i $disk
		ret="$ret /dev/loop$i"
	done

	echo "$ret"
}


fill_1_file() {
	fn=$MNT/giant-file-$1
	if [ -n "$2" ]; then
		size=count=$(($2 / 16 / 1024 / 1024 ))
	else
		size=
	fi
	dd if=/dev/zero of=$fn bs=16M oflag=direct $size
	ls -l $fn | awk '{ print $5 }'
}

dump_bg_data() {
	$BTRFS fi us -b $MNT | awk '
		/^$/    { flag=0 }
		        { if(flag) print $0 }
		/^Data/ { flag=1 }
	'
}

dump_bg_metadata() {
	$BTRFS fi us -b $MNT | awk '
		/^$/        { flag=0 }
		            { if(flag) print $0 }
		/^Metadata/ { flag=1 }
	'
}

test_default_raid1() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT
	
	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	res=$(dump_bg_data)
	echo $res | egrep $loop0 || raise "Data BG should contains $loop0"
	echo $res | egrep $loop1 || raise "Data BG should contains $loop1"
	echo $res | egrep $loop2 || raise "Data BG should contains $loop2"
	echo $res | egrep $loop3 || raise "Data BG should contains $loop3"

	size1=$(fill_1_file y )

	size=$(($size + $size1))

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] || raise "File too small: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 * 3 / 2 )) ] || raise "File too big: check mnt/"

	cleanup_all
}

test_default_single() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT
	
	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	res=$(dump_bg_data)
	echo $res | egrep $loop0 || raise "Data BG should contains $loop0"
	echo $res | egrep $loop1 || raise "Data BG should contains $loop1"

	size1=$(fill_1_file y )

	size=$(($size + $size1))

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] || raise "File too small: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 * 3 / 2 )) ] || raise "File too big: check mnt/"

	cleanup_all
}

test_single_preferred_data() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint PREFERRED_METADATA
	$BTRFS prop set $loop1 allocation_hint PREFERRED_DATA
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	res=$(dump_bg_data)
	echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}

test_single_preferred_metadata() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint PREFERRED_METADATA
	$BTRFS prop set $loop1 allocation_hint PREFERRED_DATA
	
	$BTRFS balance start --full-balance $MNT

	fnsize=2048
	for i in $(seq $(( $MAXSIZE / $fnsize * 700 / 1000))); do
		dd if=/dev/zero of=$MNT/fn-$i bs=$fnsize count=1
	done

	#BTRFS fi us $MNT

	res=$(dump_bg_metadata)
	echo $res | egrep $loop0 &>/dev/null || raise "Metadata BG should contains $loop0"
	echo $res | egrep $loop1 &>/dev/null && raise "Metadata BG should contains $loop3"

	cleanup_all
}



test_raid1_preferred_data() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint PREFERRED_METADATA
	$BTRFS prop set $loop1 allocation_hint PREFERRED_METADATA
	$BTRFS prop set $loop2 allocation_hint PREFERRED_DATA
	$BTRFS prop set $loop3 allocation_hint PREFERRED_DATA
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x $(($MAXSIZE / 2)) )

	res=$(dump_bg_data)
	echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	echo $res | egrep $loop1 &>/dev/null && raise "Data BG should not contains $loop1"
	echo $res | egrep $loop2 &>/dev/null || raise "Data BG should contains $loop2"
	echo $res | egrep $loop3 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}

test_raid1_preferred_metadata() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint PREFERRED_METADATA
	$BTRFS prop set $loop1 allocation_hint PREFERRED_METADATA
	$BTRFS prop set $loop2 allocation_hint PREFERRED_DATA
	$BTRFS prop set $loop3 allocation_hint PREFERRED_DATA
	
	$BTRFS balance start --full-balance $MNT

	fnsize=2048
	for i in $(seq $(( $MAXSIZE / $fnsize * 700 / 1000))); do
		dd if=/dev/zero of=$MNT/fn-$i bs=$fnsize count=1
	done

	#BTRFS fi us $MNT

	res=$(dump_bg_metadata)
	echo $res | egrep $loop0 &>/dev/null || raise "Metadata BG should contains $loop0"
	echo $res | egrep $loop1 &>/dev/null || raise "Metadata BG should contains $loop1"
	echo $res | egrep $loop2 &>/dev/null && raise "Metadata BG should contains $loop2"
	echo $res | egrep $loop3 &>/dev/null && raise "Metadata BG should contains $loop3"

	cleanup_all
}

test_raid1_data_only() {
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	loop2=$(echo $loops | awk '{ print $3 }')
	loop3=$(echo $loops | awk '{ print $4 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop2 allocation_hint DATA_ONLY
	$BTRFS prop set $loop3 allocation_hint DATA_ONLY
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x  )

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] && raise "File too big: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 / 3 )) ] && raise "File too small: check mnt/"

	res=$(dump_bg_data)
	echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	echo $res | egrep $loop1 &>/dev/null && raise "Data BG should not contains $loop1"
	echo $res | egrep $loop2 &>/dev/null || raise "Data BG should contains $loop2"
	echo $res | egrep $loop3 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}

test_single_data_only() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint DATA_ONLY
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x  )

	[ $size -gt $(($MAXSIZE * 2 * 2 / 3 )) ] && raise "File too big: check mnt/"
	[ $size -lt $(($MAXSIZE * 2 / 3 )) ] && raise "File too small: check mnt/"

	res=$(dump_bg_data)
	echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop3"

	cleanup_all
}


test_single_data_bouncing() {
	loops=$(create_loops 2)
	loop0=$(echo $loops | awk '{ print $1 }')
	loop1=$(echo $loops | awk '{ print $2 }')
	$BTRFS dev scan -u
	mkfs.btrfs -U $UUID -dsingle -msingle $loops
	xmount $loop0 $MNT

	$BTRFS prop set $loop0 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop1 allocation_hint DATA_ONLY
	
	$BTRFS balance start --full-balance $MNT

	size=$(fill_1_file x  $(($MAXSIZE * 2 / 4 )))

	[ $size -gt $(($MAXSIZE * 2 / 3 )) ] && raise "File too big: check mnt/"
	[ $size -lt $(($MAXSIZE * 1 / 3 )) ] && raise "File too small: check mnt/"

	res=$(dump_bg_data)

	echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop1"

	$BTRFS balance start --full-balance $MNT

	res=$(dump_bg_data)

	echo $res | egrep $loop0 &>/dev/null && raise "Data BG should not contains $loop0"
	echo $res | egrep $loop1 &>/dev/null || raise "Data BG should contains $loop1"


	$BTRFS prop set $loop1 allocation_hint METADATA_ONLY
	$BTRFS prop set $loop0 allocation_hint DATA_ONLY

	$BTRFS balance start --full-balance $MNT

	res=$(dump_bg_data)

	echo $res | egrep $loop1 &>/dev/null && raise "Data BG should not contains $loop1"
	echo $res | egrep $loop0 &>/dev/null || raise "Data BG should contains $loop0"
	cleanup_all
}








if [ "$1" = "cleanup" ]; then
	cleanup_all

	exit
elif [ "$1" = "makeraid1" ]; then
	loops=$(create_loops 4)
	loop0=$(echo $loops | awk '{ print $1 }')
	mkfs.btrfs -U $UUID -draid1 -mraid1 $loops
	xmount $loop0 $MNT

	exit
fi


cleanup_all &>/dev/null
cleanup_all &>/dev/null

SETV=""
SETX=""

while true; do
	if [ "$1" = "-x" ]; then
		SETX="set -x"
		shift
	elif [ "$1" = "-v" ]; then
		SETV="-v"
		shift
	elif [ "$1" = "--list" ]; then
		declare -F | awk '{ print $3 }' | egrep ^test_ | sort
		exit
	else
		break
	fi
done

ARG="$1"

$SETX


[ -z "$ARG" ] && ARG="."
declare -F | awk '{ print $3 }' | egrep ^test_ | sort |
	egrep $SETV "$ARG" | while read func; do

	echo -n "TEST '$func' "
	(
		$SETX
		$func >.out.log 2>.err.log
	)|| raise "Error !!!; read .out.log, .err.log"
	echo "OK"
done

-----------



-- 
gpg @keyserver.linux.it: Goffredo Baroncelli <kreijackATinwind.it>
Key fingerprint BBF5 1610 0B64 DAC6 5F7D  17B2 0EDA 9B37 8B82 E0B5
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help