return func;
}
-static int do_disconnect(char *func)
+#define difftime(a, b) \
+ ((double)(a)->tv_sec - (b)->tv_sec + \
+ ((double)((a)->tv_usec - (b)->tv_usec) / 1000000))
+
+static int be_verbose(int verbose, struct timeval *next_time,
+ int num, int *next_num, int num_total)
+{
+ struct timeval now;
+
+ if (!verbose)
+ return 0;
+
+ /* A positive verbosity means to print every X iterations */
+ if (verbose > 0 &&
+ (next_num == NULL || num >= *next_num || num >= num_total)) {
+ *next_num += verbose;
+ return 1;
+ }
+
+ if (verbose < 0 && next_time != NULL) {
+ /* A negative verbosity means to print at most each X seconds */
+ gettimeofday(&now, NULL);
+ if (difftime(&now, next_time) >= 0) {
+ next_time->tv_sec = now.tv_sec - verbose;
+ next_time->tv_usec = now.tv_usec;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int do_disconnect(char *func, int verbose)
{
struct obd_ioctl_data data;
int rc;
fprintf(stderr, "error: %s: %x %s\n", cmdname(func),
OBD_IOC_DISCONNECT, strerror(errno));
} else {
- printf("%s: disconnected connid %d\n", cmdname(func), connid);
+ if (verbose)
+ printf("%s: disconnected connid %d\n", cmdname(func),
+ connid);
connid = -1;
}
struct obd_ioctl_data data;
int rc;
- do_disconnect(argv[0]);
+ do_disconnect(argv[0], 1);
memset(&data, 0, sizeof(data));
if ( argc != 2 ) {
return -1;
}
- data.ioc_dev = atoi(argv[1]);
+ data.ioc_dev = strtoul(argv[1], NULL, 0);
if (obd_ioctl_pack(&data, &buf, max)) {
fprintf(stderr, "error: %s: invalid ioctl\n", cmdname(argv[0]));
IOCINIT(data);
- do_disconnect(argv[0]);
+ do_disconnect(argv[0], 1);
if (argc != 1) {
fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
static int jt_disconnect(int argc, char **argv)
{
- struct obd_ioctl_data data;
- int rc;
-
- IOCINIT(data);
-
if (argc != 1) {
fprintf(stderr, "usage: %s\n", cmdname(argv[0]));
return -1;
}
- rc = ioctl(fd, OBD_IOC_DISCONNECT , &data);
- if (rc < 0)
- fprintf(stderr, "error: %s: %x %s\n", cmdname(argv[0]),
- OBD_IOC_DISCONNECT, strerror(rc = errno));
- else
- connid = -1;
-
- return rc;
+ return do_disconnect(argv[0], 0);
}
static int jt__device(int argc, char **argv)
{
char *arg2[3];
- int rc;
+ int rc, ret;
if (argc < 3) {
fprintf(stderr, "usage: %s devno <command [args ...]>\n",
if (!rc)
rc = Parser_execarg(argc - 2, argv + 2, cmdlist);
- if (!rc) {
- arg2[0] = "disconnect";
- arg2[1] = NULL;
- rc = jt_disconnect(1, arg2);
- }
+ ret = do_disconnect(argv[0], 0);
+ if (!rc)
+ rc = ret;
return rc;
}
static int jt__threads(int argc, char **argv)
{
- int threads;
+ int threads, next_thread;
+ int verbose = 1;
int i, j;
int rc;
- if (argc < 4) {
+ if (argc < 5) {
fprintf(stderr,
- "usage: %s numthreads devno <command [args ...]>\n",
+ "usage: %s numthreads verbose devno <cmd [args ...]>\n",
argv[0]);
return -1;
}
- threads = atoi(argv[1]);
+ threads = strtoul(argv[1], NULL, 0);
+
+ if (argv[2][0] == 's' || argv[2][0] == 'q')
+ verbose = 0;
+ else if (argv[2][0] == 'v')
+ verbose = 1;
+ else
+ verbose = strtoul(argv[2], NULL, 0);
+
printf("%s: starting %d threads on device %s running %s\n",
- argv[0], threads, argv[2], argv[3]);
+ argv[0], threads, argv[3], argv[4]);
- for (i = 1; i <= threads; i++) {
+ for (i = 1, next_thread = verbose; i <= threads; i++) {
rc = fork();
if (rc < 0) {
fprintf(stderr, "error: %s: #%d - %s\n", argv[0], i,
break;
} else if (rc == 0) {
thread = i;
- argv[1] = "--device";
- return jt__device(argc - 1, argv + 1);
- } else {
- printf("%s: thread %d (PID %d) started\n",
+ argv[2] = "--device";
+ return jt__device(argc - 2, argv + 2);
+ } else if (be_verbose(verbose, NULL, i, &next_thread, threads))
+ printf("%s: thread #%d (PID %d) started\n",
argv[0], i, rc);
- rc = 0;
- }
+ rc = 0;
}
- if (!thread) {
- printf("\n");
+ if (!thread) { /* parent process */
+ if (!verbose)
+ printf("%s: started %d threads\n\n", argv[0], i - 1);
+ else
+ printf("\n");
+
for (j = 1; j < i; j++) {
int status;
int ret = wait(&status);
static int jt_create(int argc, char **argv)
{
struct obd_ioctl_data data;
- int num = 1;
- int silent = 0;
+ struct timeval next_time;
+ int count = 1, next_count;
+ int verbose = 1;
int i;
int rc;
IOCINIT(data);
if (argc < 2 || argc > 4) {
- fprintf(stderr, "usage: %s num [mode] [silent]\n",
+ fprintf(stderr, "usage: %s num [mode] [verbose]\n",
cmdname(argv[0]));
return -1;
}
- num = strtoul(argv[1], NULL, 0);
+ count = strtoul(argv[1], NULL, 0);
if (argc > 2)
data.ioc_obdo1.o_mode = strtoul(argv[2], NULL, 0);
data.ioc_obdo1.o_mode = 0100644;
data.ioc_obdo1.o_valid = OBD_MD_FLMODE;
- if (argc > 3)
- silent = strtoul(argv[3], NULL, 0);
+ if (argc > 3) {
+ if (argv[3][0] == 's' || argv[3][0] == 'q')
+ verbose = 0;
+ else if (argv[3][0] == 'v')
+ verbose = 1;
+ else
+ verbose = strtoul(argv[3], NULL, 0);
+ }
- printf("%s: %d obdos\n", cmdname(argv[0]), num);
+ printf("%s: %d obdos\n", cmdname(argv[0]), count);
+ gettimeofday(&next_time, NULL);
+ next_time.tv_sec -= verbose;
- for (i = 0 ; i < num ; i++) {
+ for (i = 1, next_count = verbose; i <= count ; i++) {
rc = ioctl(fd, OBD_IOC_CREATE , &data);
if (rc < 0) {
fprintf(stderr, "error: %s: #%d - %s\n",
cmdname(argv[0]), i, strerror(rc = errno));
break;
}
- if (!silent)
- printf("%s: #%Ld succeeded\n", cmdname(argv[0]),
- data.ioc_obdo1.o_id);
+ if (be_verbose(verbose, &next_time, i, &next_count, count))
+ printf("%s: #%d is object id %Ld\n", cmdname(argv[0]),
+ i, data.ioc_obdo1.o_id);
}
return rc;
}
static int jt_test_getattr(int argc, char **argv)
{
struct obd_ioctl_data data;
- struct timeval start;
- int count, i;
- int silent = 0;
+ struct timeval start, next_time;
+ int i, count, next_count;
+ int verbose = 1;
int rc;
if (argc != 2 && argc != 3) {
- fprintf(stderr, "usage: %s count [silent]\n", cmdname(argv[0]));
+ fprintf(stderr, "usage: %s count [verbose]\n",cmdname(argv[0]));
return -1;
}
if (argc == 3) {
if (argv[2][0] == 's' || argv[2][0] == 'q')
- silent = 1;
+ verbose = 0;
+ else if (argv[2][0] == 'v')
+ verbose = 1;
else
- silent = strtoul(argv[2], NULL, 0);
+ verbose = strtoul(argv[2], NULL, 0);
}
data.ioc_obdo1.o_valid = 0xffffffff;
data.ioc_obdo1.o_id = 2;
gettimeofday(&start, NULL);
- printf("%s: %d attrs (testing only): %s", cmdname(argv[0]), count,
- ctime(&start.tv_sec));
+ next_time.tv_sec = start.tv_sec - verbose;
+ next_time.tv_usec = start.tv_usec;
+ printf("%s: getting %d attrs (testing only): %s", cmdname(argv[0]),
+ count, ctime(&start.tv_sec));
- for (i = 0 ; i < count; i++) {
+ for (i = 1, next_count = verbose; i <= count; i++) {
rc = ioctl(fd, OBD_IOC_GETATTR , &data);
if (rc) {
fprintf(stderr, "error: %s: #%d - %s\n",
cmdname(argv[0]), i, strerror(rc = errno));
break;
- } else if (!silent) {
+ } else if (be_verbose(verbose, &next_time, i,&next_count,count))
printf("%s: got attr #%d\n", cmdname(argv[0]), i);
- }
}
+
if (!rc) {
struct timeval end;
double diff;
gettimeofday(&end, NULL);
- diff = ((double)(end.tv_sec - start.tv_sec) +
- (double)(end.tv_usec - start.tv_usec) / 1000000);
+ diff = difftime(&end, &start);
+ --i;
printf("%s: %d attrs in %.4gs (%.4g attr/s): %s",
cmdname(argv[0]), i, diff, (double)i / diff,
ctime(&end.tv_sec));
static int jt_test_brw(int argc, char **argv)
{
struct obd_ioctl_data data;
- struct timeval start;
+ struct timeval start, next_time;
char *bulk, *b;
- int pages = 1, obdos = 1, count;
- int silent = 0, write = 0, rw;
+ int pages = 1, obdos = 1, count, next_count;
+ int verbose = 1, write = 0, rw;
int i, o, p;
int len;
int rc;
if (argc < 2 || argc > 6) {
fprintf(stderr,
- "usage: %s count [write [silent [pages [obdos]]]]\n",
+ "usage: %s count [write [verbose [pages [obdos]]]]\n",
cmdname(argv[0]));
return -1;
}
count = strtoul(argv[1], NULL, 0);
if (argc >= 3) {
- if (argv[2][0] == 'w')
+ if (argv[2][0] == 'w' || argv[2][0] == '1')
write = 1;
- else if (argv[2][0] == 'r')
+ else if (argv[2][0] == 'r' || argv[2][0] == '0')
write = 0;
- else
- write = strtoul(argv[2], NULL, 0);
}
if (argc >= 4) {
if (argv[3][0] == 's' || argv[3][0] == 'q')
- silent = 1;
+ verbose = 0;
+ else if (argv[3][0] == 'v')
+ verbose = 1;
else
- silent = strtoul(argv[3], NULL, 0);
+ verbose = strtoul(argv[3], NULL, 0);
}
if (argc >= 5)
pages = strtoul(argv[4], NULL, 0);
}
gettimeofday(&start, NULL);
+ next_time.tv_sec = start.tv_sec - verbose;
+ next_time.tv_usec = start.tv_usec;
+
printf("%s: %s %d (%dx%d pages) (testing only): %s",
cmdname(argv[0]), write ? "writing" : "reading",
count, obdos, pages, ctime(&start.tv_sec));
memcpy(b, &start, sizeof(start));
rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
- for (i = 0 ; i < count; i++) {
+ for (i = 1, next_count = verbose; i <= count; i++) {
if (write) {
b = bulk + sizeof(struct timeval);
for (o = 0; o < obdos; o++)
cmdname(argv[0]), i, strerror(rc = errno),
write ? "write" : "read");
break;
- } else if (!silent)
+ } else if (be_verbose(verbose, &next_time, i,&next_count,count))
printf("%s: %s number %d\n", cmdname(argv[0]),
write ? "write" : "read", i);
}
gettimeofday(&end, NULL);
- diff = ((double)(end.tv_sec - start.tv_sec) +
- (double)(end.tv_usec - start.tv_usec) / 1000000);
+ diff = difftime(&end, &start);
+ --i;
printf("%s: %s %dx%dx%d pages in %.4gs (%.4g pg/s): %s",
cmdname(argv[0]), write ? "wrote" : "read", obdos,
pages, i, diff, (double)obdos * i * pages / diff,
}
command_t cmdlist[] = {
+ /* Metacommands */
{"--device", jt__device, 0, "--device <devno> <command [args ...]>"},
{"--threads", jt__threads, 0,
"--threads <threads> <devno> <command [args ...]>"},
+
+ /* Device configuration commands */
{"device", jt_device, 0, "set current device (args device no)"},
{"attach", jt_attach, 0, "name the type of device (args: type data"},
{"setup", jt_setup, 0, "setup device (args: <blkdev> [data]"},
{"detach", jt_detach, 0, "detach the current device (arg: )"},
{"cleanup", jt_cleanup, 0, "cleanup the current device (arg: )"},
- {"create", jt_create, 0, "create [count [mode [silent]]]"},
- {"destroy", jt_destroy, 0, "destroy <id>"},
- {"getattr", jt_getattr, 0, "getattr <id>"},
- {"setattr", jt_setattr, 0, "setattr <id> <mode>"},
+
+ /* Session commands */
{"connect", jt_connect, 0, "connect - get a connection to device"},
{"disconnect", jt_disconnect, 0,
"disconnect - break connection to device"},
- {"test_getattr", jt_test_getattr, 0, "test_getattr <count> [silent]"},
- {"test_brw", jt_test_brw, 0, "test_brw <count> [write [silent]]"},
+
+ /* Session operations */
+ {"create", jt_create, 0, "create [count [mode [verbose]]]"},
+ {"destroy", jt_destroy, 0, "destroy <id>"},
+ {"getattr", jt_getattr, 0, "getattr <id>"},
+ {"setattr", jt_setattr, 0, "setattr <id> <mode>"},
+ {"test_getattr", jt_test_getattr, 0, "test_getattr <count> [verbose]"},
+ {"test_brw", jt_test_brw, 0, "test_brw <count> [write [verbose]]"},
{"test_ldlm", jt_test_ldlm, 0, "test lock manager (no args)"},
+
+ /* User interface commands */
{"help", Parser_help, 0, "help"},
{"exit", Parser_quit, 0, "quit"},
{"quit", Parser_quit, 0, "quit"},
static void signal_server(int sig)
{
if (sig == SIGINT) {
- do_disconnect("sigint");
+ do_disconnect("sigint", 1);
exit(1);
+ } else {
+ fprintf(stderr, "%s: got signal %d\n", cmdname("sigint"), sig);
}
}
Parser_commands();
}
- do_disconnect(argv[0]);
+ do_disconnect(argv[0], 1);
return rc;
}