[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