#!/bin/bash
# reaim installer
P=reaim-install
DEFAULT_VERSION=7.0.1.13
. $SHELLPACK_INCLUDE/common.sh
TIME_CMD=`which time`
if [ "$TIME_CMD" = "" ]; then
        TIMEFORMAT="%2Uuser %2Ssystem %Relapsed %P%%CPU"
        TIME_CMD="time"
fi
WEB_LOCATION=https://10gbps-io.dl.sourceforge.net/project/re-aim-7/re-aim
MIRROR_LOCATION="$WEBROOT/reaim/"

install-depends libaio-devel

# Basic argument parser
TASKSET_SERVER=
TASKSET_CLIENT=
TASKSET_ALL=
SERVERSIDE_COMMAND=none
SERVERSIDE_NAME=`date +%Y%m%d-%H%M-%S`

while [ "$1" != "" ]; do
	case "$1" in
	-v)
		VERSION=$2
		shift 2
		;;
	--serverside-command)
		SERVERSIDE_COMMAND=$2
		shift 2
		;;
	--serverside-name)
		SERVERSIDE_NAME=$2
		shift 2
		;;
	*)
		echo Unrecognised option: $1
		shift
	esac
done
if [ "$TASKSET_SERVER" != "" ]; then
	echo TASKSET_SERVER: $TASKSET_SERVER
	echo TASKSET_CLIENT: $TASKSET_CLIENT
fi
if [ -z "$VERSION" ]; then
	VERSION=$DEFAULT_VERSION
fi

# Unconditionally fetch the tar to find out the real version number
rm -rf $SHELLPACK_SOURCES/reaim-* $SHELLPACK_SOURCES/osdl*.tar.gz
# Unconditionally fetch the tar to find out the real version number
TARFILE=osdl-aim-${VERSION}.tar.gz
sources_fetch $WEB_LOCATION/$VERSION/$TARFILE $MIRROR_LOCATION/$TARFILE $SHELLPACK_SOURCES/$TARFILE $WEB_LOCATION_ALT/$VERSION/$TARFILE
cd $SHELLPACK_SOURCES
tar -xf $TARFILE
if [ $? -ne 0 ]; then
	error "$P: tar xf osdl-aim-${VERSION}.tar.gz failed"
	popd > /dev/null
	exit $SHELLPACK_ERROR
fi

# Rename directory to something we expect.
DST_DIR=`tar tf $TARFILE | head -n 1 | awk -F / '{print $1}'`
mv $DST_DIR reaim-${VERSION}
pushd reaim-${VERSION} > /dev/null || die Failed to rename tar

# Bootstrap
./bootstrap
if [ $? -ne 0 ]; then
        error "$P: bootstrap failed"
        popd > /dev/null
        exit $SHELLPACK_ERROR
fi

export LDFLAGS=-laio
pushd $SHELLPACK_SOURCES/reaim-${VERSION} || die Failed to change to source directory
for FILE in `find -name "*"`; do
	touch $FILE
done

# Patch crazy syncing and off-by-one error
LINESTART=`grep -n "==== BEGIN controlled-sync.patch" $0 | tail -1 | awk -F : '{print $1}'`
LINEEND=`grep -n "==== END controlled-sync.patch" $0 | tail -1 | awk -F : '{print $1}'`
if [ "$LINEEND" = "" ]; then
	LINECOUNT=`wc -l $0 | awk '{print $1}'`
fi
if [ "$LINESTART" = "" ]; then
	die Failed to find start of file controlled-sync.patch
fi
echo Extracting $SHELLPACK_TEMP/controlled-sync.patch
sed -n $((LINESTART+1)),$((LINEEND-1))p $0 > $SHELLPACK_TEMP/controlled-sync.patch
cat $SHELLPACK_TEMP/controlled-sync.patch | patch -p1 || die Failed to apply controlled sync patch
./bootstrap
export CFLAGS="-O2 $CFLAGS_MMTESTS_EXTRA"
eval ./configure --prefix=$SHELLPACK_SOURCES/reaim-${VERSION}-installed 
if [ $? -ne 0 ]; then
	cp /usr/share/automake*/config.guess .
	cp /usr/share/automake*/config.sub .
	eval ./configure --prefix=$SHELLPACK_SOURCES/reaim-${VERSION}-installed 
	if [ $? -ne 0 ]; then
		error "$P: configure failed"
		popd > /dev/null
		exit $SHELLPACK_ERROR
	fi
fi
unset CFLAGS
make -j$NUMCPUS 
if [ $? -ne 0 ]; then
	error "$P: make failed"
	popd > /dev/null
	exit $SHELLPACK_ERROR
fi
popd
mv $SHELLPACK_SOURCES/reaim-${VERSION} $SHELLPACK_SOURCES/reaim-${VERSION}-installed
echo "10 page_test" > $SHELLPACK_SOURCES/reaim-${VERSION}-installed/data/workfile.page_test

echo reaim installed successfully
exit $SHELLPACK_SUCCESS

==== BEGIN controlled-sync.patch ====
diff -rup a/src/disk1.c b/src/disk1.c
--- a/src/disk1.c	2004-10-21 01:31:33.000000000 +0200
+++ b/src/disk1.c	2018-03-05 14:43:04.126353805 +0100
@@ -175,13 +175,14 @@ static int disk_rr(int argc, char **argv
 			perror("disk_rr()");
 			fprintf(stderr, "disk_rr : cannot write %s\n",
 				myfn2);
+			fsync(fd);
 			close(fd);
 			unlink(myfn2);
 			return (-1);
 		}
 	}
+	fsync(fd);
 	close(fd);
-	system("sync");
 	if ((fd = open(myfn2, O_RDONLY)) < 0) {
 		fprintf(stderr, "disk_rr : cannot open %s\n", myfn2);
 		perror(__FILE__);
@@ -213,13 +214,11 @@ static int disk_rr(int argc, char **argv
 			perror("disk_rr()");
 			fprintf(stderr, "disk_rr : can't read %s\n",
 				myfn2);
-			close(fd);
 			return (-1);
 		}
 	}
 	close(fd);
 	unlink(myfn2);
-	system("sync");
 	res->d = n;
 	return (0);
 }
@@ -265,8 +264,8 @@ static int disk_rw(int argc, char **argv
 			return (-1);
 		}
 	}
+	fsync(fd);
 	close(fd);
-	system("sync");
 	if ((fd = open(myfn2, O_WRONLY)) < 0) {
 		fprintf(stderr, "disk_rw : cannot open %s\n", myfn2);
 		perror(__FILE__);
@@ -305,7 +304,6 @@ static int disk_rw(int argc, char **argv
 	}
 	unlink(myfn2);
 	close(fd);
-	system("sync");
 	res->d = n;
 	return (0);
 }
@@ -415,8 +413,8 @@ static int disk_rd(int argc, char **argv
 			return (-1);
 		}
 	}
+	fsync(fd);
 	close(fd);
-	system("sync");
 	fd = open(myfn1, O_RDONLY);
 	if (fd < 0) {		/*  */
 		fprintf(stderr, "disk_rd : cannot open %s\n", myfn1);
@@ -442,7 +440,6 @@ static int disk_rd(int argc, char **argv
 		}
 	}
 	close(fd);
-	system("sync");
 	res->d = i;
 	unlink(myfn1);
 	return (0);
@@ -464,7 +461,6 @@ static int disk_cp(int argc, char **argv
 		sprintf(fn1, "%s", TMPFILE1);	/* source file name */
 		sprintf(fn2, "%s", TMPFILE2);	/* desination file nam */
 	}
-	system("sync");
 	aim_mktemp(fn2);	/* convert into unique temporary name */
 	fd = open(fn1, O_RDONLY);	/* open the file */
 	if (fd < 0) {		/* open source file */
@@ -479,7 +475,6 @@ static int disk_cp(int argc, char **argv
 		close(fd);	/* close source file */
 		return (-1);	/* return error */
 	}
-	system("sync");
 	status = lseek(fd, 0L, SEEK_SET);	/* move pointer to offset 0 (rewind) */
 	if (status < 0) {	/* handle error case */
 		fprintf(stderr, "disk_cp (3): cannot lseek %s\n", fn1);	/* talk to human */
@@ -513,10 +508,10 @@ static int disk_cp(int argc, char **argv
 	/*
 	 * make it anonymous (and work NFS harder) 
 	 */
+	fsync(fd);
 	close(fd);		/* close input file */
 	close(fd2);		/* close (and delete) output file */
 	unlink(fn2);
-	system("sync");
 	res->d = disk_iteration_count;	/* return number */
 	return (0);		/* show success */
 }
@@ -612,8 +607,6 @@ static int disk_wrt(int argc, char **arg
 		return (-1);
 	}
 
-	system("sync");
-
 	while (n--) {
 		if ((i = write(fd, nbuf, sizeof nbuf)) != sizeof nbuf) {
 			fprintf(stderr, "disk_wrt : cannot write %s\n",
@@ -628,8 +621,8 @@ static int disk_wrt(int argc, char **arg
 	unlink(fn2);		/*
 				 * unlink moved after write 10/17/95  
 				 */
+	fsync(fd);
 	close(fd);
-	system("sync");
 
 	res->d = disk_iteration_count;
 	return (0);
@@ -859,9 +852,9 @@ static int disk_dio_rr(int argc, char **
 				return (-1);
 			}
 		}
+		fsync(fd);
 		close(fd);
 	}
-	system("sync");
 	if ((n = posix_memalign(&align_buf, 4096, sizeof nbuf))) {
 		fprintf(stderr,
 			"disk_dio_rr : can't allocated aligned memory %s\n",
@@ -905,8 +898,8 @@ static int disk_dio_rr(int argc, char **
 	}
 	if (do_unlink)
 		unlink(mfn2);
+	fsync(fd);
 	close(fd);
-	system("sync");
 	res->d = n;
 	free(align_buf);
 	return (0);
@@ -967,9 +960,9 @@ static int disk_dio_rw(int argc, char **
 				return (-1);
 			}
 		}
+		fsync(fd);
 		close(fd);
 	}
-	system("sync");
 	if ((n = posix_memalign(&align_buf, 4096, sizeof nbuf))) {
 		fprintf(stderr,
 			"disk_dio_rw : can't allocated aligned memory %s\n",
@@ -1023,8 +1016,8 @@ static int disk_dio_rw(int argc, char **
 	}
 	if (do_unlink)
 		unlink(fn2);
+	fsync(fd);
 	close(fd);
-	system("sync");
 	res->d = n;
 	free(align_buf);
 	return (0);
@@ -1089,8 +1082,8 @@ static int disk_dio_rd(int argc, char **
 			return (-1);
 		}
 	}
+	fsync(fd);
 	close(fd);
-	system("sync");
 	res->d = i;
 	free(align_buf);
 	return (0);
@@ -1127,7 +1120,6 @@ static int disk_dio_cp(int argc, char **
 		close(fd);	/* close source file */
 		return (-1);	/* return error */
 	}
-	system("sync");
 	status = lseek(fd, 0L, SEEK_SET);	/* move pointer to offset 0 (rewind) */
 	if (status < 0) {	/* handle error case */
 		fprintf(stderr, "disk_dio_cp (3): cannot lseek %s\n", fn1);	/* talk to human */
@@ -1170,9 +1162,9 @@ static int disk_dio_cp(int argc, char **
 	/*
 	 * make it anonymous (and work NFS harder) 
 	 */
+	fsync(fd);
 	close(fd);		/* close input file */
 	close(fd2);		/* close (and delete) output file */
-	system("sync");
 	res->d = disk_iteration_count;	/* return number */
 	free(align_buf);
 	return (0);		/* show success */
@@ -1216,7 +1208,6 @@ static int disk_dio_wrt(int argc, char *
 		return (-1);
 	}
 
-	system("sync");
 	if ((n = posix_memalign(&align_buf, 4096, sizeof nbuf))) {
 		fprintf(stderr,
 			"disk_dio_wrt : can't allocated aligned memory %s\n",
@@ -1236,11 +1227,11 @@ static int disk_dio_wrt(int argc, char *
 		}
 	}
 
+	fsync(fd);
 	close(fd);
 	res->d = disk_iteration_count;
 	if (do_unlink)
 		unlink(fn2);
-	system("sync");
 	free(align_buf);
 
 	return (0);
@@ -1711,7 +1702,6 @@ static int disk_aio_read_write(int argc,
 		}
 		close(fd);
 	}
-	system("sync");
 	if ((fd = open(myfn2, open_flag)) < 0) {
 		fprintf(stderr, "%s : cannot open %s\n", name, myfn2);
 		perror(__FILE__);
@@ -1797,10 +1787,10 @@ static int disk_aio_read_write(int argc,
 		(void)aio_wait_for_ios(myctx, 0, name);
 	}
 	io_queue_release(myctx);
+	fsync(fd);
 	close(fd);
 	if (do_unlink)
 		unlink(myfn2);
-	system("sync");
 	res->d = n;
 	return (0);
 }
diff -rup a/src/disk_funcs.c b/src/disk_funcs.c
--- a/src/disk_funcs.c	2004-10-21 01:31:33.000000000 +0200
+++ b/src/disk_funcs.c	2018-03-05 14:40:06.526350957 +0100
@@ -150,6 +150,7 @@ int disk_create_all_files()
 
 			/* Save the generated file name for destruction */
 			strcpy(my_disk->fn1arr[j], fn1);
+			fsync(fd1);
 			close(fd1);
 		}
 	} else {
@@ -158,7 +159,6 @@ int disk_create_all_files()
 			"No directories in config file, exitiing. \n");
 		return 1;
 	}
-	system("sync");
 	return (0);
 }
 
diff -rup a/src/driver.c b/src/driver.c
--- a/src/driver.c	2004-10-21 01:31:33.000000000 +0200
+++ b/src/driver.c	2018-03-05 14:40:06.526350957 +0100
@@ -632,7 +632,7 @@ int multiuser(struct input_params *invar
 		   (void) printf("%5d", rl_vars->runnum);
 		 */
 		fflush(stdout);
-		system("sync;sync;sync");	/* clean out the cache, boosts performance */
+		system("sync");	/* clean out the cache, avoids interference */
 		loop_result = runloop(global_list, rl_vars);
 		time(&my_time);
 
diff -rup a/src/drv_funcs.c b/src/drv_funcs.c
--- a/src/drv_funcs.c	2004-10-21 01:31:33.000000000 +0200
+++ b/src/drv_funcs.c	2018-03-05 14:40:06.526350957 +0100
@@ -171,7 +171,7 @@ int write_debug_file(char *debug_msg)
 
 char *ext_strcat(char *s1, char *s2)
 {
-	char *stmp = (char*)malloc(strlen(s1)+strlen(s2));
+	char *stmp = (char*)malloc(strlen(s1)+strlen(s2) + 1);
 	stmp[0] = '\0';
 	strcat(stmp,s1);
 	strcat(stmp,s2);
==== END controlled-sync.patch ====
#### Description reaim
#### Details reaim 61
