[Ocfs2-test-devel] [PATCH 3/4] Ocfs2-test: Enhance fill_verify_holes testcase with aio support.

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


This patch allowes data-filling on a hole being performed in a manner
of aio, besides, each data chunk commited by aio_write will be verified
with a immediately followed pread().

Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 programs/fill_verify_holes/Makefile             |    8 ++-
 programs/fill_verify_holes/burn-in.sh           |    8 ++-
 programs/fill_verify_holes/fill_holes.c         |   64 +++++++++++++++++++++--
 programs/fill_verify_holes/fill_verify_holes.sh |    9 ++-
 programs/fill_verify_holes/old_burn-in.sh       |    8 ++-
 programs/fill_verify_holes/punch_holes.c        |   62 ++++++++++++++++++++--
 6 files changed, 139 insertions(+), 20 deletions(-)

diff --git a/programs/fill_verify_holes/Makefile b/programs/fill_verify_holes/Makefile
index 35929f2..430a8c0 100644
--- a/programs/fill_verify_holes/Makefile
+++ b/programs/fill_verify_holes/Makefile
@@ -6,6 +6,10 @@ TESTS = fill_holes punch_holes verify_holes
 
 CFLAGS = -O2 -Wall -g $(OCFS2_CFLAGS)
 
+INCLUDES = -I$(TOPDIR)/programs/libocfs2test
+
+LIBO2TEST = $(TOPDIR)/programs/libocfs2test/libocfs2test.a
+
 SOURCES = fill_holes.c punch_holes.c verify_holes.c fill_holes.h reservations.h
 
 SUBDIRS = fill_holes_data
@@ -17,10 +21,10 @@ BIN_EXTRA = burn-in.sh old_burn-in.sh fill_verify_holes.sh
 BIN_PROGRAMS = fill_holes punch_holes verify_holes 
 
 fill_holes: fill_holes.o fill_holes.h
-	$(LINK) $(OCFS2_LIBS)
+	$(LINK) $(OCFS2_LIBS) $(LIBO2TEST) -laio
 
 punch_holes: punch_holes.o fill_holes.h
-	$(LINK) $(OCFS2_LIBS)
+	$(LINK) $(OCFS2_LIBS) $(LIBO2TEST) -laio
 
 verify_holes: verify_holes.o fill_holes.h
 	$(LINK) $(OCFS2_LIBS)
diff --git a/programs/fill_verify_holes/burn-in.sh b/programs/fill_verify_holes/burn-in.sh
index e0416ff..b08e58f 100755
--- a/programs/fill_verify_holes/burn-in.sh
+++ b/programs/fill_verify_holes/burn-in.sh
@@ -21,6 +21,7 @@ USERID=`/usr/bin/whoami`
 BINPATH="."
 LOGPATH="."
 MMAPOPT=
+AIOOPT=
 if [ -f `dirname ${0}`/config.sh ]; then
 	. `dirname ${0}`/config.sh
 fi;
@@ -38,7 +39,7 @@ run_fill() {
     logfile="$4"
 
     echo "Creating file..."
-    log_run "${BINPATH}/fill_holes" ${MMAPOPT} ${UNWOPT} -f -o "${logfile}" -i "${iter}" \
+    log_run "${BINPATH}/fill_holes" ${MMAPOPT} ${UNWOPT} ${AIOOPT} -f -o "${logfile}" -i "${iter}" \
 	    "${filename}" "${size}"
     sleep 10
     sudo /sbin/fuser -km ${MOUNTPOINT}
@@ -149,7 +150,7 @@ BLOCKSIZE=`echo 2^${BLOCKSIZE_BITS} |bc`;
 #
 }
 #
-while getopts "c:d:i:b:l:s:muh?" args
+while getopts "c:d:i:b:l:s:muah?" args
 do
   case "$args" in
     c) COUNT="$OPTARG";;
@@ -160,13 +161,14 @@ do
     s) SIZE="$OPTARG";;
     m) MMAPOPT="-m";;
     u) UNWOPT="-u";;
+    a) AIOOPT="-a";;
     h) USAGE="yes";;
     ?) USAGE="yes";;
   esac
 done
 
 if [ -n "${USAGE}" ]; then
-    echo "usage: burn-in.sh [ -m ] [ -u ] [ -b path-to-binaries ]  \
+    echo "usage: burn-in.sh [ -m ] [ -u ] [ -a ] [ -b path-to-binaries ]  \
     	[ -l path-for-logfiles ] [ -c count ] [ -d  directory ]  \
 	[ -i iteractions ] [ -s size ]";
     exit 0;
diff --git a/programs/fill_verify_holes/fill_holes.c b/programs/fill_verify_holes/fill_holes.c
index 14ac980..d128475 100644
--- a/programs/fill_verify_holes/fill_holes.c
+++ b/programs/fill_verify_holes/fill_holes.c
@@ -15,6 +15,7 @@
 
 #include "fill_holes.h"
 #include "reservations.h"
+#include "aio.h"
 
 
 /*
@@ -34,7 +35,7 @@ size, verifying it's contents.
 
 static void usage(void)
 {
-	printf("fill_holes [-f] [-m] [-u] [-i ITER] [-o LOGFILE] [-r REPLAYLOG] FILE SIZE\n"
+	printf("fill_holes [-f] [-m] [-u] [-a] [-i ITER] [-o LOGFILE] [-r REPLAYLOG] FILE SIZE\n"
 	       "FILE is a path to a file\n"
 	       "SIZE is in bytes and must always be specified, even with a REPLAYLOG\n"
 	       "ITER defaults to 1000, unless REPLAYLOG is specified.\n"
@@ -42,6 +43,7 @@ static void usage(void)
 	       "-f will result in logfile being flushed after every write\n"
 	       "-m instructs the test to use mmap to write to FILE\n"
 	       "-u will create an unwritten region instead of ftruncate\n"
+	       "-a will enable aio io mode\n"
 	       "REPLAYLOG is an optional file to generate values from\n\n"
 	       "FILE will be truncated to zero, then truncated out to SIZE\n"
 	       "For each iteration, a character, offset and length will be\n"
@@ -61,6 +63,7 @@ static char buf[MAX_WRITE_SIZE];
 static unsigned int max_iter = 1000;
 static unsigned int flush_output = 0;
 static unsigned int create_unwritten = 0;
+static unsigned int enable_aio = 0;
 static char *fname = NULL;
 static char *logname = NULL;
 static char *replaylogname = NULL;
@@ -75,7 +78,7 @@ static int parse_opts(int argc, char **argv)
 	int c, iter_specified = 0;
 
 	while (1) {
-		c = getopt(argc, argv, "umfi:o:r:");
+		c = getopt(argc, argv, "aumfi:o:r:");
 		if (c == -1)
 			break;
 
@@ -83,6 +86,9 @@ static int parse_opts(int argc, char **argv)
 		case 'u':
 			create_unwritten = 1;
 			break;
+		case 'a':
+			enable_aio = 1;
+			break;
 		case 'm':
 			use_mmap = 1;
 			break;
@@ -278,7 +284,11 @@ static int prep_write_unit(struct write_unit *wu)
 
 int do_write(int fd, struct write_unit *wu)
 {
-	int ret;
+	int ret, i;
+	struct o2test_aio o2a;
+	char *buf_cmp = NULL;
+	unsigned long long *ubuf = (unsigned long long *)buf;
+	unsigned long long *ubuf_cmp = NULL;
 
 	if (use_mmap) {
 		memset(mapped + wu->w_offset, wu->w_char, wu->w_len);
@@ -286,14 +296,58 @@ int do_write(int fd, struct write_unit *wu)
 	}
 
 	memset(buf, wu->w_char, wu->w_len);
+
+	if (enable_aio) {
+
+		buf_cmp = (char *)malloc(MAX_WRITE_SIZE);
+
+		ret = o2test_aio_setup(&o2a, 1);
+		if (ret < 0)
+			goto bail;
+
+		ret = o2test_aio_pwrite(&o2a, fd, buf, wu->w_len, wu->w_offset);
+		if (ret < 0)
+			goto bail;
+
+		ret = o2test_aio_query(&o2a, 1, 1);
+		if(ret < 0)
+			goto bail;
+
+		ret = pread(fd, buf_cmp, wu->w_len, wu->w_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, wu->w_len)) {
+
+			ubuf_cmp = (unsigned long long *)buf_cmp;
+			for (i = 0; i < wu->w_len / 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, wu->w_len, wu->w_offset);
 	if (ret == -1) {
 		fprintf(stderr, "write error %d: \"%s\"\n", errno,
 			strerror(errno));
-		return -1;
+		goto bail;
 	}
 
-	return 0;
+	ret = 0;
+bail:
+	if (buf_cmp)
+		free(buf_cmp);
+
+	return ret;
 }
 
 int main(int argc, char **argv)
diff --git a/programs/fill_verify_holes/fill_verify_holes.sh b/programs/fill_verify_holes/fill_verify_holes.sh
index 67d5d06..80a00c3 100755
--- a/programs/fill_verify_holes/fill_verify_holes.sh
+++ b/programs/fill_verify_holes/fill_verify_holes.sh
@@ -26,6 +26,8 @@ USERID=`${WHOAMI}`
 FILL_HOLES=`which fill_holes 2>/dev/null`
 VERIFY_HOLES=`which verify_holes 2>/dev/null`
 
+AIOOPT=
+
 log_run() {
 	${ECHO} "Run: $@"
 	"$@"
@@ -68,7 +70,7 @@ do_umount() {
 
 usage()
 {
-	${ECHO} "${APP} [ -M ] [ -U ] [ -i iteractions ] [ -s size ] [-o mountopts] -c count -m mountpoint -l logdir -d device"
+	${ECHO} "${APP} [ -M ] [ -U ] [ -A ] [ -i iteractions ] [ -s size ] [-o mountopts] -c count -m mountpoint -l logdir -d device"
 	exit 1
 }
 
@@ -80,7 +82,7 @@ SIZE=10000000
 MMAPOPT=
 UNWOPT=
 
-while getopts "c:d:i:l:s:m:o:MUh?" args
+while getopts "c:d:i:l:s:m:o:MUAh?" args
 do
 	case "$args" in
 		c) COUNT="$OPTARG";;
@@ -92,6 +94,7 @@ do
 		o) MOUNTOPTS="$OPTARG";;
 		M) MMAPOPT="-m";;
 		U) UNWOPT="-u";;
+		A) AIOOPT="-a";;
 		h) USAGE="yes";;
 		?) USAGE="yes";;
 	esac
@@ -136,7 +139,7 @@ do
       	outlog="${LOGPATH}/${fnamebase}.${i}.log"
 
     	${ECHO} "Creating file..."
-   	log_run "${FILL_HOLES}" ${MMAPOPT} ${UNWOPT} -f -o "${outlog}" -i "${ITER}" "${outtxt}" "${SIZE}"
+   	log_run "${FILL_HOLES}" ${MMAPOPT} ${UNWOPT} ${AIOOPT} -f -o "${outlog}" -i "${ITER}" "${outtxt}" "${SIZE}"
 	if [ $? -ne 0 ]; then
 		do_umount ${MOUNTPOINT}
 		exit 1
diff --git a/programs/fill_verify_holes/old_burn-in.sh b/programs/fill_verify_holes/old_burn-in.sh
index fe02fb3..251beea 100755
--- a/programs/fill_verify_holes/old_burn-in.sh
+++ b/programs/fill_verify_holes/old_burn-in.sh
@@ -3,6 +3,7 @@
 BINPATH="."
 LOGPATH="."
 MMAPOPT=
+AIOOPT=
 
 log_run() {
     echo "Run: $@"
@@ -15,7 +16,7 @@ run_fill() {
     size="$3";
     logfile="$4"
 
-    log_run "$BINPATH/fill_holes" $MMAPOPT -f -o "$logfile" -i "$iter" "$filename" "$size"
+    log_run "$BINPATH/fill_holes" $MMAPOPT $AIOOPT -f -o "$logfile" -i "$iter" "$filename" "$size"
     log_run "$BINPATH/verify_holes" "$logfile" "$filename"
 
     RET=$?
@@ -40,10 +41,11 @@ run100() {
 
 USAGE=""
 OPTIND=1
-while getopts "mb:l:h?" args
+while getopts "mab:l:h?" args
 do
   case "$args" in
     m) MMAPOPT="-m";;
+    a) AIOOPT="-a";;
     b) BINPATH="$OPTARG";;
     l) LOGPATH="$OPTARG";;
     h) USAGE="yes";;
@@ -52,7 +54,7 @@ do
 done
 
 if [ -n "$USAGE" ]; then
-    echo "usage: burn-in.sh [ -b path-to-binaries ] [ -l path-for-logfiles ]";
+    echo "usage: burn-in.sh [ -b path-to-binaries ] [ -l path-for-logfiles ] [ -a ]";
     exit 0;
 fi
 
diff --git a/programs/fill_verify_holes/punch_holes.c b/programs/fill_verify_holes/punch_holes.c
index 642be54..6923a75 100644
--- a/programs/fill_verify_holes/punch_holes.c
+++ b/programs/fill_verify_holes/punch_holes.c
@@ -15,16 +15,18 @@
 
 #include "fill_holes.h"
 #include "reservations.h"
+#include "aio.h"
 
 static void usage(void)
 {
-	printf("punch_holes [-f] [-u] [-i ITER] [-o LOGFILE] [-r REPLAYLOG] FILE SIZE\n"
+	printf("punch_holes [-f] [-u] [-a] [-i ITER] [-o LOGFILE] [-r REPLAYLOG] FILE SIZE\n"
 	       "FILE is a path to a file\n"
 	       "SIZE is in bytes and must always be specified, even with a REPLAYLOG\n"
 	       "ITER defaults to 1000, unless REPLAYLOG is specified.\n"
 	       "LOGFILE defaults to stdout\n"
 	       "-f will result in logfile being flushed after every write\n"
 	       "-u will create an unwritten region instead of ftruncate\n"
+	       "-a will enable aio mode during writes\n"
 	       "REPLAYLOG is an optional file to generate values from\n\n"
 	       "FILE will be truncated to zero, then truncated out to SIZE\n"
 	       "A random series of characters will be written into the\n"
@@ -45,6 +47,7 @@ static char buf[MAX_WRITE_SIZE];
 static unsigned int max_iter = 1000;
 static unsigned int flush_output = 0;
 static unsigned int create_unwritten = 0;
+static unsigned int enable_aio = 0;
 static char *fname = NULL;
 static char *logname = NULL;
 static char *replaylogname = NULL;
@@ -57,7 +60,7 @@ static int parse_opts(int argc, char **argv)
 	int c, iter_specified = 0;
 
 	while (1) {
-		c = getopt(argc, argv, "ufi:o:r:");
+		c = getopt(argc, argv, "aufi:o:r:");
 		if (c == -1)
 			break;
 
@@ -68,6 +71,9 @@ static int parse_opts(int argc, char **argv)
 		case 'u':
 			create_unwritten = 1;
 			break;
+		case 'a':
+			enable_aio = 1;
+			break;
 		case 'i':
 			max_iter = atoi(optarg);
 			iter_specified = 1;
@@ -182,16 +188,64 @@ static int prep_write_unit(struct write_unit *wu)
 
 static int do_write(int fd, struct write_unit *wu)
 {
-	int ret;
+	int ret, i;
+	struct o2test_aio o2a;
+	char *buf_cmp = NULL;
+	unsigned long long *ubuf = (unsigned long long *)buf;
+	unsigned long long *ubuf_cmp = NULL;
 
 	memset(buf, wu->w_char, wu->w_len);
+
+	if (enable_aio) {
+
+		buf_cmp = (char *)malloc(MAX_WRITE_SIZE);
+
+		ret = o2test_aio_setup(&o2a, 1);
+		if (ret < 0)
+			goto bail;
+
+		ret = o2test_aio_pwrite(&o2a, fd, buf, wu->w_len, wu->w_offset);
+		if (ret < 0)
+			goto bail;
+
+		ret = o2test_aio_query(&o2a, 1, 1);
+		if(ret < 0)
+			goto bail;
+
+		ret = pread(fd, buf_cmp, wu->w_len, wu->w_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, wu->w_len)) {
+
+			ubuf_cmp = (unsigned long long *)buf_cmp;
+			for (i = 0; i < wu->w_len / 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, wu->w_len, wu->w_offset);
 	if (ret == -1) {
 		fprintf(stderr, "write error %d: \"%s\"\n", errno,
 			strerror(errno));
-		return -1;
+		goto bail;
 	}
 
+	ret = 0;
+bail:
+	if (buf_cmp)
+		free(buf_cmp);
+
 	return 0;
 }
 
-- 
1.5.5




More information about the Ocfs2-test-devel mailing list