[Ocfs2-test-devel] [PATCH 5/6] Discontig-bg-test: Add a tool to activate discontig block group.

Tristan Ye tristan.ye at oracle.com
Mon May 31 02:01:35 PDT 2010


This tool as a prerequisite, is a critical utility to perform the entire discontig-bg
testing, since we're required to do all testing stuff after discontig block group has
already been activated, the activator reaches its goal by following steps:

1. Consume the majority portion of volume by allocating a range of unwriten region.

2. Fill up the rest of free space by 4M small files.

3. Remove even numbered files to make fs fragmented in 4M size.

4. Fill up the inodes/extents contiguous block group in a exact way.

Now we're ready to perform further discontig-bg things.

Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 programs/discontig_bg_test/Makefile                |    2 +
 .../discontig_bg_test/activate_discontig_bg.sh     |  457 ++++++++++++++++++++
 2 files changed, 459 insertions(+), 0 deletions(-)
 create mode 100755 programs/discontig_bg_test/activate_discontig_bg.sh

diff --git a/programs/discontig_bg_test/Makefile b/programs/discontig_bg_test/Makefile
index 2d48bb1..4baf66b 100644
--- a/programs/discontig_bg_test/Makefile
+++ b/programs/discontig_bg_test/Makefile
@@ -12,6 +12,8 @@ SOURCES = spawn_inodes.c gen_extents.c resv.h resv_unwritten.c punch_hole.c
 
 DIST_FILES = $(SOURCES)
 
+BIN_EXTRA = activate_discontig_bg.sh
+
 BIN_PROGRAMS = spawn_inodes gen_extents resv_unwritten punch_hole
 
 spawn_inode: spawn_inodes.c
diff --git a/programs/discontig_bg_test/activate_discontig_bg.sh b/programs/discontig_bg_test/activate_discontig_bg.sh
new file mode 100755
index 0000000..7c2f529
--- /dev/null
+++ b/programs/discontig_bg_test/activate_discontig_bg.sh
@@ -0,0 +1,457 @@
+#!/bin/bash
+#
+# vim: noexpandtab sw=8 ts=8 sts=0:
+#
+# activate_discontig_bg.sh
+#
+# Description:  It's a simple script to activate first discontiguous block group.
+#
+# Copyright (C) 2009 Oracle.  All rights reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License, version 2,  as published by the Free Software Foundation.
+
+################################################################################
+# Global Variables
+################################################################################
+if [ -f `dirname ${0}`/o2tf.sh ]; then
+	. `dirname ${0}`/o2tf.sh
+fi
+
+BINDIR=`dirname ${0}`
+
+DEVICE=
+MOUNT_POINT=
+WORK_PLACE=
+WORK_PLACE_DIRENT=ocfs2-activate-discontig-bg-dir
+TUNEFS_BIN="`which sudo` -u root `which tunefs.ocfs2`"
+RESV_UNWRITTEN_BIN="${BINDIR}/resv_unwritten"
+GEN_EXTENTS_BIN="${BINDIR}/gen_extents"
+SETXATTR="`which sudo` -u root `which setfattr`"
+
+DEFAULT_LOG_DIR=${O2TDIR}/log
+LOG_DIR=
+RUN_LOG_FILE=
+LOG_FILE=
+
+BLOCKSIZE=4096
+CLUSTERSIZE=4096
+TYPE=inode
+SLOTS=0
+JOURNALSIZE=0
+LABELNAME="ocfs2-discontig-bg-tests"
+MOUNT_OPTS="localalloc=0"
+DEVICE=
+WORK_PLACE=
+
+ORIG_VOLUME_SIZE=$((3*1024*1024*1024))
+ORIG_VOLUME_SIZE_BK=
+DISK_FREE_M=
+FILE_MAJOR_SIZE_M=
+RESV_SIZE_M=500
+FILL_CONTIG_EBG_M=
+FILL_CONTIG_IBG_NUM=
+CONTIG_REG_M=
+
+OCFS2_LINK_MAX=65000
+################################################################################
+# Utility Functions
+################################################################################
+function f_usage()
+{
+    echo "usage: `basename ${0}` [-t type] [-r resv_size] [-b blocksize] [-c clustersize] <-d device> [-o logdir] <mount point> "
+    exit 1;
+
+}
+
+function f_getoptions()
+{
+	if [ $# -eq 0 ]; then
+		f_usage;
+		exit 1
+	fi
+	
+	while getopts "hd:o:b:c:t:r:" options; do
+		case $options in
+		d ) DEVICE="$OPTARG";;
+		o ) LOG_DIR="$OPTARG";;
+		b ) BLOCKSIZE="$OPTARG";;
+		c ) CLUSTERSIZE="$OPTARG";;
+		r ) RESV_SIZE_M="$OPTARG";;
+		t ) TYPE="$OPTARG";;
+		h ) f_usage
+			exit 1;;
+		* ) f_usage
+			exit 1;;
+		esac
+	done
+
+	shift $(($OPTIND -1))
+	MOUNT_POINT=${1}
+}
+
+function f_setup()
+{
+	f_getoptions $*
+	
+	if [ -z "${DEVICE}" ];then
+		f_usage
+	fi	
+	
+	if [ -z "${MOUNT_POINT}" ];then
+		f_usage
+	fi
+	
+	if [ ! -d "${MOUNT_POINT}" ];then
+		echo "${MOUNT_POINT} you specified was not a dir."
+		f_usage
+	fi
+
+	if [ -n "${TYPE}" ];then
+		if [ "${TYPE}" != "inode" ] && [ "${TYPE}" != "extent" ];then
+			echo "type should be 'inode' or 'extent'"
+			f_usage
+		fi
+	fi
+	
+	LOG_DIR=${LOG_DIR:-$DEFAULT_LOG}
+	${MKDIR_BIN} -p ${LOG_DIR} || exit 1
+	
+	RUN_LOG_FILE="`dirname ${LOG_DIR}`/`basename ${LOG_DIR}`/`date +%F-%H-\
+%M-%S`-activate-discontig-bg-run.log"
+	LOG_FILE="`dirname ${LOG_DIR}`/`basename ${LOG_DIR}`/`date +%F-%H-\
+%M-%S`-activate-discontig-bg.log"
+
+}
+
+function f_get_contig_region()
+{
+	case $BLOCKSIZE in
+		512 )  CONTIG_REG_M=1;;
+		1024 ) CONTIG_REG_M=2;;
+		2048 ) CONTIG_REG_M=4;;
+		4096 ) CONTIG_REG_M=4;;
+	esac
+}
+
+function f_get_disk_usage()
+{
+	f_LogMsg ${LOG_FILE} "Calculate the disk total and free size"
+
+	DISK_FREE=`df |grep ${MOUNT_POINT}|awk '{print $4}'`
+
+	if [ -z "${DISK_FREE}" ]; then
+		DISK_FREE=`df |grep ${DEVICE}|awk '{print $4}'`
+	fi
+
+	DISK_FREE_M=`echo ${DISK_FREE}/1024|bc`
+}
+
+function f_get_extents_num_of_contig_bg()
+{
+	local -i num_extents
+
+	num_extents=$(($((4*1024*1024))/${BLOCKSIZE}))
+
+	echo $num_extents
+}
+
+function f_get_inodes_num_of_contig_bg()
+{
+	local -i num_inodes
+
+	if [ "${BLOCKSIZE}" == "512" ]; then
+		num_inodes=$(($((1024*1024))/${BLOCKSIZE}))
+	elif [ "${BLOCKSIZE}" == "1024" ];then
+		num_inodes=$(($((2*1024*1024))/${BLOCKSIZE}))
+	elif [ "${BLOCKSIZE}" == "2048" -o "${BLOCKSIZE}" == "4096" ];then
+		num_inodes=$(($((4*1024*1024))/${BLOCKSIZE}))
+	fi
+
+	echo $num_inodes
+}
+
+function f_get_recs_in_eb()
+{
+	local num_recs
+
+	num_recs=$(($((${BLOCKSIZE}-48-16))/16))
+
+	echo $num_recs
+}
+
+function f_fillup_ibg()
+{
+	local -i i=
+	local filename_prefix=
+	local filename=
+
+	f_LogMsg ${LOG_FILE} "Fill inode block groups by touching ${FILL_CONTIG_IBG_NUM} files."
+	filename_prefix=fill_contig_igb_testfile
+	for i in `seq ${FILL_CONTIG_IBG_NUM}`;do
+		filename=${filename_prefix}${i}
+		${TOUCH_BIN} ${WORK_PLACE}/$filename >/dev/null  2>&1|| {
+			f_LogMsg ${LOG_FILE} "No discontig block group created until volume gets full"
+			RET=1
+			return $RET
+		}
+	done
+
+	sync
+
+	${DEBUGFS_BIN} -R "stat //inode_alloc:0000" ${DEVICE} |grep -q "Tree Depth" && {
+		f_LogMsg ${LOG_FILE} "Oh, boy, now we have activated discontiguous inode block group."
+		return 0
+	}
+
+	i=1
+	filename_prefix=fill_contig_igb_testfile_addup_inode
+	while :;do
+		filename=${filename_prefix}${i}
+		if [ "${i}" -gt "$OCFS2_LINK_MAX" ];then
+			mkdir -p ${WORK_PLACE}/${filename}
+			i=1
+			filename_prefix=${filename}/
+			continue
+		else
+			dd if=/dev/zero of=${WORK_PLACE}/$filename bs=4k count=1 >/dev/null  2>&1|| {
+				f_LogMsg ${LOG_FILE} "No discontig block group created until volume gets full."
+				RET=1
+				break
+			}
+		fi
+
+		sync
+
+		${DEBUGFS_BIN} -R "stat ${WORK_PLACE_DIRENT}/${filename}" ${DEVICE} |grep -q "Sub Alloc Group" && {
+			f_LogMsg ${LOG_FILE} "Oh, boy, now we have activated one discontiguous inode block group."
+			break;
+		}
+
+		((i++))
+	done
+	RET=$?
+
+	return $RET
+}
+
+function f_is_xattr_in_block()
+{
+	#${1} is test file
+	#${2} is target volume
+
+	${DEBUGFS_BIN} -R "xattr ${1}" ${2}|grep -qi "block" && {
+		return 0
+	}
+
+	return 1
+}
+
+function f_fillup_ebg()
+{
+	local filename=${WORK_PLACE}/fill_contig_egb_testfile
+
+	filesize=$((${FILL_CONTIG_EBG_M}*1024*1024/2))
+
+	f_LogMsg ${LOG_FILE} "Fill contiguous extent block groups by gen_extents"
+	f_LogMsg ${LOG_FILE} "CMD: ${GEN_EXTENTS_BIN} -f ${filename} -l ${filesize} -c ${CLUSTERSIZE} -k 1"
+	${GEN_EXTENTS_BIN} -f ${filename} -l ${filesize} -c ${CLUSTERSIZE} -k 1 >>${LOG_FILE} 2>&1
+        if [ "$?" -ne "0" ];then
+                return 1
+        fi
+
+	sync
+
+	${DEBUGFS_BIN} -R "stat //extent_alloc:0000" ${DEVICE} |grep -q "Tree Depth" && {
+		f_LogMsg ${LOG_FILE} "Oh, boy, now we have activated one discontiguous extent block group."
+		return 0
+	}
+
+	# if above operation didn't consume up the contig extent block
+	# exactly, we need to slowly force the filling-up by populating
+	# xattr blocks from exteng bg.
+	local -i i=1
+	local filename_prefix=fill_contig_egb_testfile_addup_xattr
+	f_LogMsg ${LOG_FILE} "Use additional xattr extents to activate the discontig."
+	while :;do
+		filename=${filename_prefix}${i}
+		if [ "${i}" -gt "$OCFS2_LINK_MAX" ];then
+			mkdir -p ${WORK_PLACE}/${filename}
+			i=1
+			filename_prefix=${filename}/
+			continue
+		else
+			${TOUCH_BIN} ${WORK_PLACE}/$filename >>${LOG_FILE} 2>&1|| {
+				f_LogMsg ${LOG_FILE} "touch ${filename} failed."
+				RET=1
+				break
+			}
+
+			sync
+
+			for j in $(seq 100);do
+				${SETXATTR} -n user.name${j} -v value${j} ${WORK_PLACE}/${filename} >>${LOG_FILE} 2>&1 || {
+					f_LogMsg ${LOG_FILE} "setxattr failed."
+					break
+				}
+
+				f_is_xattr_in_block ${WORK_PLACE_DIRENT}/${filename} ${DEVICE} && {
+					break
+				}
+			done
+
+		fi
+
+		sync
+
+		${DEBUGFS_BIN} -R "stat //extent_alloc:0000" ${DEVICE} |grep -q "Tree Depth" && {
+			f_LogMsg ${LOG_FILE} "Oh, boy, now we have activated one discontiguous extent block group."
+			break;
+		}
+
+		((i++))
+	done
+	RET=$?
+
+	return $RET
+}
+
+# fill up volume with a huge reserved unwritten region
+# and fragmented small files.
+function f_fillup_volume_almost()
+{
+	WORK_PLACE=${MOUNT_POINT}/${WORK_PLACE_DIRENT}
+	${MKDIR_BIN} -p ${WORK_PLACE}
+
+	f_get_disk_usage
+
+	# RESV_SIZE_M is reserved for further testing operations.
+	if [ "${DISK_FREE_M}" -le "${RESV_SIZE_M}" ];then
+		RESV_SIZE_M=$((${DISK_FREE_M}/4))
+	fi
+
+	local -i extents=`f_get_extents_num_of_contig_bg`
+	local -i recs=`f_get_recs_in_eb`
+
+	FILL_CONTIG_IBG_NUM=`f_get_inodes_num_of_contig_bg`
+	FILL_CONTIG_EBG_M=$((${extents}*${recs}*${CLUSTERSIZE}/1024/1024))
+
+
+	if [ "${TYPE}" == "extent" ];then
+		if [ "${DISK_FREE_M}" -le "$((2*${RESV_SIZE_M}+2*${FILL_CONTIG_EBG_M}))" ]; then
+			RESV_SIZE_M=$((${DISK_FREE_M}/2-${FILL_CONTIG_EBG_M}))
+		fi
+		FILE_MAJOR_SIZE_M=$((${DISK_FREE_M}-2*${RESV_SIZE_M}-2*${FILL_CONTIG_EBG_M}))
+	else
+		if [ "${DISK_FREE_M}" -le "$((2*${RESV_SIZE_M}))" ]; then
+			RESV_SIZE_M=$((${DISK_FREE_M}/4))
+		fi
+		FILE_MAJOR_SIZE_M=$((${DISK_FREE_M}-2*${RESV_SIZE_M}))
+	fi
+
+	f_LogMsg ${LOG_FILE} "[*] Reserve ${FILE_MAJOR_SIZE_M}M space for a LARGE file"
+	${RESV_UNWRITTEN_BIN} -f ${WORK_PLACE}/large_testfile -s 0 -l $((${FILE_MAJOR_SIZE_M}*1024*1024)) >>${LOG_FILE} 2>&1
+	RET=$?
+	f_exit_or_not ${RET}
+
+	f_get_contig_region
+
+	local blocksz=
+	if [ ${CONTIG_REG_M} -eq "1" ];then
+		blocksz=512K
+	else
+		blocksz=$((${CONTIG_REG_M}/2))M
+	fi
+
+	f_LogMsg ${LOG_FILE} "[*] Fill up left $((${DISK_FREE_M}-${FILE_MAJOR_SIZE_M})) space with ${blocksz} small files"
+	local -i i=1
+	while :;do
+		filename=testfile-small-${i}
+		dd if=/dev/zero of=${WORK_PLACE}/${filename} bs=${blocksz} count=1 >/dev/null 2>&1 || {
+			f_LogMsg ${LOG_FILE} "Volume gets full being filled with files in ${blocksz} size"
+			break
+		}
+		((i++))
+	done
+	RET=$?
+	f_exit_or_not ${RET}
+
+	sync
+
+	f_LogMsg ${LOG_FILE} "[*] Remove even numbered files to make fs fragmented in ${blocksz} size"
+	local -i j=
+	for j in `seq ${i}`;do
+		if [ "$((${j}%2))" -eq "0" ]; then
+			filename=testfile-small-${j}
+			${RM_BIN} -rf ${WORK_PLACE}/${filename}
+		fi
+	done
+	RET=$?
+	f_exit_or_not ${RET}
+
+	sync
+}
+
+function f_activate_discontig()
+{
+	ORIG_VOLUME_SIZE_BK=$((ORIG_VOLUME_SIZE/${BLOCKSIZE}))
+	
+	f_LogRunMsg ${RUN_LOG_FILE} "[*] Mkfs device ${DEVICE}:"
+        f_mkfs ${LOG_FILE} ${BLOCKSIZE} ${CLUSTERSIZE} ${LABELNAME} ${SLOTS} \
+${DEVICE} "refcount,xattr,metaecc,discontig-bg,local" ${JOURNALSIZE} ${ORIG_VOLUME_SIZE_BK}
+        RET=$?
+        f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
+        f_exit_or_not ${RET}
+
+	f_LogRunMsg ${RUN_LOG_FILE} "[*] Change Volume Size"
+	${TUNEFS_BIN} -S ${DEVICE} 0
+	RET=$?
+	f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
+	f_exit_or_not ${RET}
+
+	f_LogRunMsg ${RUN_LOG_FILE} "[*] Mount ${DEVICE} to ${MOUNT_POINT}:"
+	f_mount ${LOG_FILE} ${DEVICE} ${MOUNT_POINT} ocfs2 ${MOUNT_OPTS}
+        RET=$?
+        f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
+        f_exit_or_not ${RET}
+
+	f_LogRunMsg ${RUN_LOG_FILE} "[*] Fillup volume with huge unwritten region and small files:"
+	f_fillup_volume_almost
+	RET=$?
+	f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
+        f_exit_or_not ${RET}
+
+	f_LogRunMsg ${RUN_LOG_FILE} "[*] Activate discontiguous ${TYPE} block group by filling up all contiguous ones:"
+	if [ "${TYPE}" == "inode" ];then
+		f_fillup_ibg
+	else
+		f_fillup_ebg
+	fi
+	RET=$?
+	f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
+	f_exit_or_not ${RET}
+
+	f_LogRunMsg ${RUN_LOG_FILE} "[*] Umount device ${DEVICE} from ${MOUNT_POINT}:"
+	f_umount ${LOG_FILE} ${MOUNT_POINT}
+	RET=$?
+	f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
+	f_exit_or_not ${RET}
+}
+
+function f_cleanup()
+{
+	:
+}
+
+################################################################################
+# Main Entry
+################################################################################
+
+#redfine the int signal hander
+trap 'echo -ne "\n\n">>${RUN_LOG_FILE};echo  "Interrupted by Ctrl+C,Cleanuping\
+... "|tee -a ${RUN_LOG_FILE}; f_cleanup;exit 1' SIGINT
+
+f_setup $*
+
+f_activate_discontig 
-- 
1.5.5




More information about the Ocfs2-test-devel mailing list