#include <pthread.h>
#include <sys/file.h>
#include <sys/wait.h>
+#include <sys/time.h>
#include <stdarg.h>
+#include <ctype.h>
#define MAX_PATH_LENGTH 4096
+
+
+static double now(void)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
+}
+
/**
* helper functions
*/
}
+#define T6BUF_SIZE 200
+
+int set_lock(struct flock *lock, char *buf)
+{
+ int i, v;
+ struct tag_node {
+ char tag;
+ int mode;
+ } tags[] = {
+ { 'W', F_WRLCK },
+ { 'R', F_RDLCK },
+ { 'U', F_UNLCK },
+ { 0, 0 }
+ };
+
+ for (i = 0; isspace(buf[i]) && i < T6BUF_SIZE;)
+ i++;
+ for (v = 0; tags[v].tag && i < T6BUF_SIZE; v++) {
+ if (buf[i] == tags[v].tag) {
+ char *head;
+
+ head = buf + i + 1;
+ for (; buf[i] != ','; i++)
+ if (i >= T6BUF_SIZE)
+ break;
+ buf[i] = '\0';
+ lock->l_start = atol(head);
+ if (lock->l_start < 0)
+ break;
+ for (; !isdigit(buf[i]); i++)
+ if (i >= T6BUF_SIZE)
+ break;
+ lock->l_len = atol(buf + i);
+ if (lock->l_len <= 0)
+ break;
+ lock->l_type = tags[v].mode;
+ return 1;
+ }
+ }
+ fprintf(stderr, "Invalid line: %s\n", buf);
+ return 0;
+}
+
+/*
+ * Read command from stdin then enqueue a lock
+ *
+ * [W|R|U]sss,lll
+ * W: write R: read U: unlock
+ * sss: start of range
+ * lll: length of range
+ *
+ * for example:
+ * W1,100 # add a write lock from 1 to 100
+ * R100,100 # add a read lock from 100 to 199
+ */
+static int t6(int argc, char *argv[])
+{
+ struct flock lock = {
+ .l_whence = SEEK_SET,
+ };
+
+ int fd, rc = 0;
+ char buf[T6BUF_SIZE+1];
+ double stime;
+
+ if (argc < 3) {
+ fprintf(stderr, "usage: flocks_test 6 file\n");
+ return EXIT_FAILURE;
+ }
+
+ fd = open(argv[2], O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "Couldn't open file: %s\n", argv[2]);
+ return EXIT_FAILURE;
+ }
+
+ memset(buf, '\0', T6BUF_SIZE + 1);
+ stime = now();
+ while (fgets(buf, T6BUF_SIZE, stdin)) {
+ if (set_lock(&lock, buf)) {
+ rc = t_fcntl(fd, F_SETLKW, &lock);
+ if (rc != 0) {
+ fprintf(stderr, "%d: cannot set lock: %s\n",
+ getpid(), strerror(errno));
+ rc = EXIT_FAILURE;
+ break;
+ }
+ }
+ }
+ close(fd);
+ printf("Time for processing %.03lfs\n", now() - stime);
+ return rc;
+}
+
/** ==============================================================
* program entry
*/
case 5:
rc = t5(argc, argv);
break;
+ case 6:
+ rc = t6(argc, argv);
+ break;
default:
fprintf(stderr, "unknown test number '%s'\n", argv[1]);
break;
ALWAYS_EXCEPT="$PERFORMANCE_SANITY_EXCEPT "
build_test_filter
-[[ -x "$MPIRUN" ]] || skip_env "no mpirun program found"
-[[ -x "$MDTEST" ]] || skip_env "no mdtest program found"
-
check_and_setup_lustre
-get_mpiuser_id $MPI_USER
-MPI_RUNAS=${MPI_RUNAS:-"runas -u $MPI_USER_UID -g $MPI_USER_GID"}
-$GSS_KRB5 && refresh_krb5_tgt $MPI_USER_UID $MPI_USER_GID $MPI_RUNAS
+env_verify()
+{
+ [[ -x "$MPIRUN" ]] || skip_env "no mpirun program found"
+ [[ -x "$MDTEST" ]] || skip_env "no mdtest program found"
+ get_mpiuser_id $MPI_USER
+ MPI_RUNAS=${MPI_RUNAS:-"runas -u $MPI_USER_UID -g $MPI_USER_GID"}
+ $GSS_KRB5 && refresh_krb5_tgt $MPI_USER_UID $MPI_USER_GID $MPI_RUNAS
+}
test_1() {
+ env_verify
echo "Small files creation performance test"
# LU-2600/LU-4108 - Decrease load on zfs
if [[ "$SLOW" == no && "$mds1_FSTYPE" == zfs ]]; then
run_test 1 "small files create/open/delete"
test_2() {
+ env_verify
echo "Large files creation performance test"
run_mdtest create-large
}
run_test 2 "large files create/open/delete"
test_3() {
+ env_verify
NUM_DIRS=1
NUM_FILES=200000
echo "Single directory lookup rate for $NUM_FILES files"
run_test 3 "lookup rate 200k files in single directory"
test_4() {
+ env_verify
NUM_DIRS=100
NUM_FILES=200000
echo "Directory lookup rate $NUM_DIRS directories, $((NUM_FILES/NUM_DIRS)) files each"
}
run_test 4 "lookup rate 200k files in 100 directories"
+test_5() {
+ touch $DIR/$tfile
+ for((i=0; i < 20000; i++)) {
+ echo "W$((i * 10)), 5"
+ } | flocks_test 6 $DIR/$tfile
+ rm -r $DIR/$tfile
+}
+run_test 5 "enqueue 20k no overlap flocks on same file"
+
+test_6() {
+ touch $DIR/$tfile
+ for((i=0; i < 20000; i++)) {
+ [ $i -eq 0 ] && echo "W0,99999999" && continue
+ echo "R$((i * 10)), 5"
+ } | flocks_test 6 $DIR/$tfile
+ rm -r $DIR/$tfile
+}
+run_test 6 "split a flock 20k times"
+
+test_7() {
+ touch $DIR/$tfile
+ for((i=0; i < 20001; i++)) {
+ echo "R$((i * 10)), 5"
+ [ $i -eq 20000 ] && echo "W0,99999999" && continue
+ } | flocks_test 6 $DIR/$tfile
+ rm -r $DIR/$tfile
+}
+run_test 7 "merge 20k flocks"
+
complete_test $SECONDS
check_and_cleanup_lustre
exit_status