diff --git a/lustre/tests/multiop.c b/lustre/tests/multiop.c
index 70b61d8..479c757 100644
--- a/lustre/tests/multiop.c
+++ b/lustre/tests/multiop.c
@@ -110,7 +110,9 @@ char usage[] =
 "	 Y  fdatasync\n"
 "	 z[num] lseek(SEEK_SET) [optional offset, default 0]\n"
 "	 Z[num] lseek(SEEK_CUR) [optional offset, default 0]\n"
-"	 _  wait for signal\n";
+"	 @  wait for signal absolute time\n"
+"	 _  wait for signal relative time\n"
+"	 i  duration of operation(s)\n";
 
 void usr1_handler(int unused)
 {
@@ -234,6 +236,27 @@ out_closedir:
 	return rc;
 }
 
+static int str2timestamp(const char *str, struct timespec *const time)
+{
+	char strnano[10] = "000000000";
+	int match;
+
+	time->tv_sec = 0;
+	time->tv_nsec = 0;
+	match = sscanf(str, "%ld.%9[0-9]",
+		       &time->tv_sec, &strnano[0]);
+
+	if (match == 2)
+	{
+		int len = strlen(strnano);
+		if ( len < 9 )
+			strnano[len] = '0';
+		time->tv_nsec = atol(strnano);
+	}
+
+	return (match > 0)? 0: -1;
+}
+
 #define POP_ARG() (pop_arg(argc, argv))
 
 int main(int argc, char **argv)
@@ -251,7 +274,9 @@ int main(int argc, char **argv)
 	int verbose = 0;
 	int gid = 0;
 	struct lu_fid fid;
-	struct timespec ts;
+	struct timespec ts, tc;
+	struct timespec ti = {0};
+	struct timespec dt = {0};
 	struct lov_user_md_v3 lum;
 	char *xattr_buf = NULL;
 	size_t xattr_buf_size = 0;
@@ -280,19 +305,46 @@ int main(int argc, char **argv)
 		rc = 0;
 
 		switch (*commands) {
+		case '@':
+			if (verbose) {
+				printf("PAUSING\n");
+				fflush(stdout);
+			}
+			str2timestamp(commands + 1, &ts);
+
+			while (sem_timedwait(&sem, &ts) < 0 && errno == EINTR)
+				;
+			break;
 		case '_':
 			if (verbose) {
 				printf("PAUSING\n");
 				fflush(stdout);
 			}
-			len = atoi(commands + 1);
-			if (len <= 0)
-				len = 3600; /* 1 hour */
-			ts.tv_sec = time(NULL) + len;
-			ts.tv_nsec = 0;
+			if (str2timestamp(commands + 1, &ts) == -1)
+				ts.tv_sec = 3600; /* 1 hour */
+
+			if (clock_gettime(CLOCK_REALTIME, &tc)) {
+				perror("Unable to get time:");
+				exit(1);
+			}
+
+			ts.tv_sec += tc.tv_sec;
+			if ((ts.tv_nsec + tc.tv_nsec) >= 1000000000) {
+				ts.tv_nsec += tc.tv_nsec - 1000000000;
+				ts.tv_sec++;
+			} else {
+				ts.tv_nsec += tc.tv_nsec;
+			}
+
 			while (sem_timedwait(&sem, &ts) < 0 && errno == EINTR)
 				;
 			break;
+		case 'i':
+			if (clock_gettime(CLOCK_MONOTONIC_RAW, &ti)) {
+				perror("Unable to mesure time:");
+				exit(1);
+			}
+			break;
 		case 'A':
 			if (fsetxattr(fd, XATTR, "multiop", 8, 0)) {
 				save_errno = errno;
@@ -792,6 +844,7 @@ int main(int argc, char **argv)
 			break;
 		}
 		case '-':
+		case '.':
 		case '0':
 		case '1':
 		case '2':
@@ -810,6 +863,21 @@ int main(int argc, char **argv)
 		}
 	}
 
+	if (ti.tv_sec > 0) {
+		if (clock_gettime(CLOCK_MONOTONIC_RAW, &dt)) {
+			perror("Unable to mesure time:");
+			exit(1);
+		}
+		dt.tv_sec -= ti.tv_sec;
+		if (dt.tv_nsec < ti.tv_nsec) {
+			dt.tv_nsec = 1000000000 - ti.tv_nsec + dt.tv_nsec;
+			dt.tv_sec--;
+		} else {
+			dt.tv_nsec -=  ti.tv_nsec;
+		}
+		printf("OpTime(s):\t%ld.%09ld\n", dt.tv_sec, dt.tv_nsec);
+	}
+
 	if (buf)
 		free(buf);
 
