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

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

From: Paul Jones <hidden>
Date: 2021-12-21 05:36:11

-----Original Message-----
From: Goffredo Baroncelli <redacted>
Sent: Saturday, 18 December 2021 5:53 AM
To: linux-btrfs@vger.kernel.org
Cc: Zygo Blaxell <redacted>; Josef Bacik
[off-list ref]; David Sterba [off-list ref]; Sinnamohideen
Shafeeq [off-list ref]
Subject: Script to test allocation_hint - [Was Re: [PATCH 0/2][V9] btrfs-progs:
allocation_hint disk property]

On 12/17/21 19:47, Goffredo Baroncelli wrote:
quoted
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 :-)

FYI something has broken in 5.15 - Only the first device in a raid set gets allocation_hint set

server /media/storage/peejay/linux/btrfs-progs # cat .err.log
dd: error writing 'mnt/giant-file-x': No space left on device
110+0 records in
109+0 records out
1828716544 bytes (1.8 GB, 1.7 GiB) copied, 4.4846 s, 408 MB/s
File too big: check mnt/
server /media/storage/peejay/linux/btrfs-progs # ./btrfs-hint prop get /dev/loop1
label=
devid=1, path=/dev/loop1: allocation_hint=METADATA_ONLY
server /media/storage/peejay/linux/btrfs-progs # ./btrfs-hint prop get /dev/loop2
label=
server /media/storage/peejay/linux/btrfs-progs # ./btrfs-hint prop get /dev/loop3
label=
server /media/storage/peejay/linux/btrfs-progs # ./btrfs-hint prop get /dev/loop4
label=


-----------
#!/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