[Ocfs2-test-devel] [PATCH 4/4] Ocfs2-test: Enhance reflink_test with aio testing.

Tristan Ye tristan.ye at oracle.com
Mon Jun 28 03:54:20 PDT 2010


Idea here is to make generic write_at(recognized as an atomic write in reflink test,
which is widely used almost in all of the testcases) become aio-aware, that way, the
existing testing semantics and scenarios for basic or odirect tests still are available
for us when we enable aio testing flag, besides, we also do a verfication after each
aio_write by issuing a pread() immediatly to validate the asynchronous writing.

Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 programs/reflink_tests/Makefile                  |   10 +++-
 programs/reflink_tests/multi_reflink_test.c      |    8 ++-
 programs/reflink_tests/multi_reflink_test_run.sh |   19 ++++---
 programs/reflink_tests/reflink_test.c            |    8 ++-
 programs/reflink_tests/reflink_test.h            |    3 +
 programs/reflink_tests/reflink_test_run.sh       |   19 ++++---
 programs/reflink_tests/reflink_test_utils.c      |   68 ++++++++++++++++++++-
 7 files changed, 109 insertions(+), 26 deletions(-)

diff --git a/programs/reflink_tests/Makefile b/programs/reflink_tests/Makefile
index d2f2110..1133504 100755
--- a/programs/reflink_tests/Makefile
+++ b/programs/reflink_tests/Makefile
@@ -8,6 +8,12 @@ CFLAGS = -O2 -Wall -g $(OCFS2_CFLAGS)
 
 CFLAGS += $(EXTRA_CFLAGS)
 
+INCLUDES = -I$(TOPDIR)/programs/libocfs2test
+
+CFLAGS += $(INCLUDES)
+
+LIBO2TEST = $(TOPDIR)/programs/libocfs2test/libocfs2test.a
+
 ifdef NO_REFLINK
 CFLAGS += -DNO_REFLINK
 endif
@@ -49,10 +55,10 @@ BIN_EXTRA = reflink_test_run.sh multi_reflink_test_run.sh reflink_files.sh
 BIN_PROGRAMS = reflink_test multi_reflink_test
 
 reflink_test: $(SINGLE_SOURCES)
-	$(LINK) $(OCFS2_LIBS)
+	$(LINK) $(OCFS2_LIBS) $(LIBO2TEST) -laio
 
 multi_reflink_test: $(MULTI_SOURCES)
-	$(MPI_LINK) $(OCFS2_LIBS)
+	$(MPI_LINK) $(OCFS2_LIBS) $(LIBO2TEST) -laio
 
 include $(TOPDIR)/Postamble.make
 
diff --git a/programs/reflink_tests/multi_reflink_test.c b/programs/reflink_tests/multi_reflink_test.c
index 6c951af..494279d 100755
--- a/programs/reflink_tests/multi_reflink_test.c
+++ b/programs/reflink_tests/multi_reflink_test.c
@@ -117,7 +117,7 @@ static void usage(void)
 {
        root_printf("Usage: multi_reflink_test [-i iteration] [-l file_size] "
 	       "[-p refcount_tree_pairs] [-n reflink_nums] <-w work_place> "
-	       "[-f] [-x] [-r] [-m] [-y] [-s] [-c] [-O]\n"
+	       "[-f] [-x] [-r] [-m] [-y] [-s] [-c] [-O] [-A]\n"
 	       "iteration specify the running times.\n"
 	       "file_size specify the size of original file.\n"
 	       "reflink_nums specify the number of reflinks.\n"
@@ -130,6 +130,7 @@ static void usage(void)
 	       "-s specify the stress test.\n"
 	       "-c specify the comprehensive test.here need 6 ranks at least.\n"
 	       "-O specify O_DIRECT test.\n"
+	       "-A specify asynchronous io test.\n"
 	       "-m specify the mmap test.\n");
 
 	MPI_Finalize();
@@ -142,7 +143,7 @@ int parse_opts(int argc, char **argv)
 	int c;
 
 	while (1) {
-		c = getopt(argc, argv, "I:i:w:OfFrRmMyYcCsSW:n:N:l:L:p:P:x:X:");
+		c = getopt(argc, argv, "I:i:w:OAfFrRmMyYcCsSW:n:N:l:L:p:P:x:X:");
 		if (c == -1)
 			break;
 
@@ -179,6 +180,9 @@ int parse_opts(int argc, char **argv)
 		case 'O':
 			test_flags |= ODCT_TEST;
 			break;
+		case 'A':
+			test_flags |= ASIO_TEST;
+			break;
 		case 'r':
 		case 'R':
 			test_flags |= RAND_TEST;
diff --git a/programs/reflink_tests/multi_reflink_test_run.sh b/programs/reflink_tests/multi_reflink_test_run.sh
index b89e934..dae3143 100755
--- a/programs/reflink_tests/multi_reflink_test_run.sh
+++ b/programs/reflink_tests/multi_reflink_test_run.sh
@@ -69,6 +69,7 @@ RUN_LOG_FILE=
 LOG_FILE=
 
 MOUNT_OPTS=
+AIO_OPT=
 
 DEFAULT_RANKS=4
 MPI_RANKS=
@@ -89,7 +90,7 @@ set -o pipefail
 function f_usage()
 {
     echo "usage: `basename ${0}` [-r MPI_Ranks] <-f MPI_Hosts> \
-[-a access method] [-o logdir] <-d <device>> [-W] <mountpoint path>"
+[-a access method] [-o logdir] <-d <device>> [-W] [-A] <mountpoint path>"
     echo "       -r size of MPI rank"
     echo "       -a access method for mpi execution,should be ssh or rsh"
     echo "       -f MPI hosts list,separated by comma"
@@ -97,6 +98,7 @@ function f_usage()
     echo "       -d specify the device"
     echo "       -i Network Interface name to be used for MPI messaging."
     echo "       -W enable data=writeback mode"
+    echo "       -A enable asynchronous io testing mode"
     echo "       <mountpoint path> specify the mounting point."
     exit 1;
 
@@ -108,7 +110,7 @@ function f_getoptions()
                 exit 1
          fi
 
-	 while getopts "o:d:i:r:f:Wha:" options; do
+	 while getopts "o:d:i:r:f:WAha:" options; do
                 case $options in
 		r ) MPI_RANKS="$OPTARG";;
                 f ) MPI_HOSTS="$OPTARG";;
@@ -117,6 +119,7 @@ function f_getoptions()
 		a ) MPI_ACCESS_METHOD="$OPTARG";;
 		i ) INTERFACE="$OPTARG";;
 		W ) MOUNT_OPTS="data=writeback";;
+		A ) AIO_OPT=" -A ";;
                 h ) f_usage
                     exit 1;;
                 * ) f_usage
@@ -208,10 +211,10 @@ ${DEVICE} "refcount,xattr" ${JOURNALSIZE} ${BLOCKS}
 	f_LogMsg ${LOG_FILE} "[${TEST_NO}] Basic Functional Test, CMD:\
 ${MPIRUN} ${MPI_PLS_AGENT_ARG} ${MPI_BTL_ARG} ${MPI_BTL_IF_ARG} -np \
 ${MPI_RANKS} --host ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 104857600 \
--n 100 -w ${WORK_PLACE} -f "
+-n 100 -w ${WORK_PLACE} -f ${AIO_OPT}"
 	${MPIRUN} ${MPI_PLS_AGENT_ARG} ${MPI_BTL_ARG} ${MPI_BTL_IF_ARG} -np \
 ${MPI_RANKS} --host ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 104857600 \
--n 100 -w ${WORK_PLACE} -f >>${LOG_FILE} 2>&1
+-n 100 -w ${WORK_PLACE} -f ${AIO_OPT} >>${LOG_FILE} 2>&1
 	RET=$?
 	f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
 	f_exit_or_not ${RET}
@@ -226,10 +229,10 @@ ${MPI_RANKS} --host ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 104857600 \
 	f_LogMsg ${LOG_FILE} "[${TEST_NO}] Random Test, CMD:${MPIRUN} \
 ${MPI_PLS_AGENT_ARG} ${MPI_BTL_ARG} ${MPI_BTL_IF_ARG} -np ${MPI_RANKS} --host \
 ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 104857600 -n 100 -w \
-${WORK_PLACE} -r "
+${WORK_PLACE} -r ${AIO_OPT}"
 	${MPIRUN} ${MPI_PLS_AGENT_ARG} ${MPI_BTL_ARG} ${MPI_BTL_IF_ARG} -np \
 ${MPI_RANKS} --host ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 104857600 -n \
-100 -w ${WORK_PLACE} -r >>${LOG_FILE} 2>&1
+100 -w ${WORK_PLACE} -r ${AIO_OPT} >>${LOG_FILE} 2>&1
 	RET=$?
 	f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
 	f_exit_or_not ${RET}
@@ -262,10 +265,10 @@ ${MPI_RANKS} --host ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 104857600 -n
         f_LogMsg ${LOG_FILE} "[${TEST_NO}] O_DIRECT Test, CMD:${MPIRUN} \
 ${MPI_PLS_AGENT_ARG} ${MPI_BTL_ARG} ${MPI_BTL_IF_ARG} -np ${MPI_RANKS} --host \
 ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 41943040 -n 100 -w \
-${WORK_PLACE} -O "
+${WORK_PLACE} -O ${AIO_OPT}"
         ${MPIRUN} ${MPI_PLS_AGENT_ARG} ${MPI_BTL_ARG} ${MPI_BTL_IF_ARG} -np \
 ${MPI_RANKS} --host ${MPI_HOSTS} ${MULTI_REFLINK_TEST_BIN} -i 1 -l 41943040 -n \
-100 -w ${WORK_PLACE} -O >>${LOG_FILE} 2>&1
+100 -w ${WORK_PLACE} -O ${AIO_OPT} >>${LOG_FILE} 2>&1
         RET=$?
         f_echo_status ${RET}| tee -a ${RUN_LOG_FILE}
         f_exit_or_not ${RET}
diff --git a/programs/reflink_tests/reflink_test.c b/programs/reflink_tests/reflink_test.c
index c0221ec..121f768 100755
--- a/programs/reflink_tests/reflink_test.c
+++ b/programs/reflink_tests/reflink_test.c
@@ -108,7 +108,7 @@ static void usage(void)
 	printf("Usage: reflink_tests [-i iteration] <-n ref_counts> "
 	       "<-p refcount_tree_pairs> <-l file_size> <-d disk> "
 	       "<-w workplace> -f -b [-c conc_procs] -m -s -r [-x xattr_nums]"
-	       " [-h holes_num] [-o holes_filling_log] -O -D <child_nums> -I -H -T\n\n"
+	       " [-h holes_num] [-o holes_filling_log] -O -A -D <child_nums> -I -H -T\n\n"
 	       "-f enable basic feature test.\n"
 	       "-b enable boundary test.\n"
 	       "-c enable concurrent tests with conc_procs processes.\n"
@@ -116,6 +116,7 @@ static void usage(void)
 	       "-r enable random test.\n"
 	       "-s enable stress test.\n"
 	       "-O enable O_DIRECT test.\n"
+	       "-A enable asynchronous io test.\n"
 	       "-D enable destructive test.\n"
 	       "-v enable verification for destructive test.\n"
 	       "-H enable CoW verification test for punching holes.\n"
@@ -143,7 +144,7 @@ static int parse_opts(int argc, char **argv)
 
 	while (1) {
 		c = getopt(argc, argv,
-			   "i:d:w:IOfFbBsSrRHTmMW:n:N:"
+			   "i:d:w:IOAfFbBsSrRHTmMW:n:N:"
 			   "l:L:c:C:p:x:X:h:o:v:a:P:D:");
 		if (c == -1)
 			break;
@@ -169,6 +170,9 @@ static int parse_opts(int argc, char **argv)
 		case 'O':
 			test_flags |= ODCT_TEST;
 			break;
+		case 'A':
+			test_flags |= ASIO_TEST;
+			break;
 		case 'D':
 			test_flags |= DSCV_TEST;
 			child_nums = atol(optarg);
diff --git a/programs/reflink_tests/reflink_test.h b/programs/reflink_tests/reflink_test.h
index 5f864f2..10006d0 100755
--- a/programs/reflink_tests/reflink_test.h
+++ b/programs/reflink_tests/reflink_test.h
@@ -51,6 +51,8 @@
 #include <ocfs2/byteorder.h>
 #include "crc32table.h"
 
+#include "aio.h"
+
 #define OCFS2_MAX_FILENAME_LEN	255
 #define FILE_RW_FLAGS		(O_CREAT|O_RDWR)
 #define FILE_RO_FLAGS		(O_RDONLY)
@@ -79,6 +81,7 @@
 #define VERI_TEST		0x00002000
 #define PUNH_TEST		0x00004000
 #define TRUC_TEST		0x00008000
+#define ASIO_TEST		0x00010000
 
 #define MPI_RET_SUCCESS		0
 #define MPI_RET_FAILED		1
diff --git a/programs/reflink_tests/reflink_test_run.sh b/programs/reflink_tests/reflink_test_run.sh
index d161e95..54aa63d 100755
--- a/programs/reflink_tests/reflink_test_run.sh
+++ b/programs/reflink_tests/reflink_test_run.sh
@@ -69,6 +69,7 @@ WORK_PLACE_DIRENT=ocfs2-refcount-tests
 WORK_PLACE=
 
 MOUNT_OPTS=
+AIO_OPT=
 
 DSCV_TEST=
 LISTENER_ADDR=
@@ -97,10 +98,11 @@ set -o pipefail
 function f_usage()
 {
         echo "usage: `basename ${0}` [-D <-a remote_listener_addr> <-p port>] \
-[-v verify_log] [-W] [-o logdir] <-d device> <mountpoint path>"
+[-v verify_log] [-W] [-A] [-o logdir] <-d device> <mountpoint path>"
         echo "       -o output directory for the logs"
         echo "       -d block device name used for ocfs2 volume"
         echo "       -W enable data=writeback mode"
+        echo "       -A enable asynchronous io testing mode"
 	echo "       -D enable destructive test,it will crash the testing node,\
 be cautious, you need to specify listener addr and port then"
         echo "       <mountpoint path> specify the testing mounting point."
@@ -115,11 +117,12 @@ function f_getoptions()
                 exit 1
          fi
 
-         while getopts "o:WDhd:a:p:v:" options; do
+         while getopts "o:WDAhd:a:p:v:" options; do
                 case $options in
                 o ) LOG_DIR="$OPTARG";;
                 d ) DEVICE="$OPTARG";;
 		W ) MOUNT_OPTS="data=writeback";;
+		A ) AIO_OPT=" -A ";;
 		D ) DSCV_TEST="1";;
 		a ) LISTENER_ADDR="$OPTARG";;
 		p ) LISTENER_PORT="$OPTARG";;
@@ -442,9 +445,9 @@ ${WORK_PLACE} -D 10 -a ${LISTENER_ADDR} -p ${LISTENER_ADDR} >>${LOG_FILE} 2>&1
 	((TEST_NO++))
 	f_LogRunMsg ${RUN_LOG_FILE} "[${TEST_NO}] Basic Fucntional Test:"
 	f_LogMsg ${LOG_FILE} "[${TEST_NO}] Basic Fucntional Test, CMD:${SUDO} \
-${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w ${WORK_PLACE} -f "
+${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w ${WORK_PLACE} -f ${AIO_OPT}"
 	${SUDO} ${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w \
-${WORK_PLACE} -f >>${LOG_FILE} 2>&1
+${WORK_PLACE} -f ${AIO_OPT} >>${LOG_FILE} 2>&1
         RET=$?
         f_echo_status ${RET} | tee -a ${RUN_LOG_FILE}
         f_exit_or_not ${RET}
@@ -458,9 +461,9 @@ ${WORK_PLACE} -f >>${LOG_FILE} 2>&1
 	((TEST_NO++))
 	f_LogRunMsg ${RUN_LOG_FILE} "[${TEST_NO}] Random Refcount Test:"
 	f_LogMsg ${LOG_FILE} "[${TEST_NO}] Random Refcount Test, CMD:${SUDO} \
-${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w ${WORK_PLACE} -f -r "
+${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w ${WORK_PLACE} -f -r ${AIO_OPT}"
 	${SUDO} ${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w \
-${WORK_PLACE} -r >>${LOG_FILE} 2>&1
+${WORK_PLACE} -r ${AIO_OPT} >>${LOG_FILE} 2>&1
         RET=$?
         f_echo_status ${RET} | tee -a ${RUN_LOG_FILE}
         f_exit_or_not ${RET}
@@ -523,9 +526,9 @@ ${WORK_PLACE} -c 100 >>${LOG_FILE} 2>&1
 	((TEST_NO++))
         f_LogRunMsg ${RUN_LOG_FILE} "[${TEST_NO}] O_DIRECT Refcount Test:"
         f_LogMsg ${LOG_FILE} "[${TEST_NO}] O_DIRECT Refcount Test, CMD:${SUDO} \
-${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w ${WORK_PLACE} -O "
+${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w ${WORK_PLACE} -O ${AIO_OPT}"
         ${SUDO} ${REFLINK_TEST_BIN} -i 1 -n 100 -l 104857600 -d ${DEVICE} -w \
-${WORK_PLACE} -O >>${LOG_FILE} 2>&1
+${WORK_PLACE} -O ${AIO_OPT} >>${LOG_FILE} 2>&1
         RET=$?
         f_echo_status ${RET} | tee -a ${RUN_LOG_FILE}
         f_exit_or_not ${RET}
diff --git a/programs/reflink_tests/reflink_test_utils.c b/programs/reflink_tests/reflink_test_utils.c
index a55d6da..083e749 100755
--- a/programs/reflink_tests/reflink_test_utils.c
+++ b/programs/reflink_tests/reflink_test_utils.c
@@ -205,15 +205,69 @@ int mmap_read_at_file(char *pathname, void *buf, size_t count,
 
 int write_at(int fd, const void *buf, size_t count, off_t offset)
 {
-	int ret;
+	int ret, i;
 	size_t bytes_write;
+	struct o2test_aio o2a;
+	void *buf_cmp = NULL;
+	unsigned long long *ubuf = (unsigned long long *)buf;
+        unsigned long long *ubuf_cmp = NULL;
+
+	if (test_flags & ASIO_TEST) {
+
+		if (test_flags & ODCT_TEST) {
+			ret = posix_memalign(&buf_cmp, DIRECTIO_SLICE,
+					     count);
+			if (ret) {
+				ret = errno;
+				fprintf(stderr, "error %s during %s\n",
+					strerror(ret), "posix_memalign");
+				ret = -1;
+				goto bail;
+			}
+		} else
+			buf_cmp = (char *)malloc(count);
+
+		ret = o2test_aio_setup(&o2a, 1);
+		if (ret < 0)
+			goto bail;
+
+		ret = o2test_aio_pwrite(&o2a, fd, (void *)buf, count, offset);
+		if (ret < 0)
+			goto bail;
+
+		ret = o2test_aio_query(&o2a, 1, 1);
+		if(ret < 0)
+			goto bail;
+
+		ret = pread(fd, buf_cmp, count, offset);
+		if (ret < 0) {
+			ret = errno;
+			fprintf(stderr, "pread error %d: \"%s\"\n", ret,
+				strerror(ret));
+			ret = -1;
+			goto bail;
+		}
+
+		if (memcmp(buf, buf_cmp, count)) {
+
+			ubuf_cmp = (unsigned long long *)buf_cmp;
+			for (i = 0; i < count / sizeof(unsigned long long); i++)
+				printf("%d: 0x%llx[aio_write]  0x%llx[pread]\n",
+				       i, ubuf[i], ubuf_cmp[i]);
+		}
+
+		ret = o2test_aio_destroy(&o2a);
+
+		goto bail;
+	}
 
 	ret = pwrite(fd, buf, count, offset);
 
 	if (ret < 0) {
 		ret = errno;
 		fprintf(stderr, "write error %d: \"%s\"\n", ret, strerror(ret));
-		return -1;
+		ret = -1;
+		goto bail;
 	}
 
 	bytes_write = ret;
@@ -226,13 +280,19 @@ int write_at(int fd, const void *buf, size_t count, off_t offset)
 			ret = errno;
 			fprintf(stderr, "write error %d: \"%s\"\n", ret,
 				strerror(ret));
-			return -1;
+			ret = -1;
+			goto bail;
 		}
 
 		bytes_write += ret;
 	}
 
-	return 0;
+	ret = 0;
+bail:
+	if (buf_cmp)
+		free(buf_cmp);
+
+	return ret;
 }
 
 int write_at_file(char *pathname, const void *buf, size_t count,
-- 
1.5.5




More information about the Ocfs2-test-devel mailing list