2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
42 #include <sys/types.h>
46 #include <xtypes/xhash.h>
47 #include <xtypes/xobj.h>
48 #include <xseg/xseg.h>
49 #include <xseg/protocol.h>
52 printf("xseg <spec> [[[<src_port>]:[<dst_port>]] [<command> <arg>*] ]*\n"
54 " <type:name:nr_ports:nr_requests:request_size:extra_size:page_shift>\n"
61 " bridge <portno1> <portno2> <logfile> {full|summary|stats}\n"
64 " alloc_requests (to source) <nr>\n"
65 " free_requests (from source) <nr>\n"
66 " put_requests (all from dest)\n"
67 " put_replies (all from dest)\n"
68 " wait <nr_replies>\n"
69 " complete <nr_requests>\n"
70 " fail <nr_requests>\n"
71 " rndwrite <nr_loops> <seed> <targetlen> <datalen> <objectsize>\n"
72 " rndread <nr_loops> <seed> <targetlen> <datalen> <objectsize>\n"
73 " submit_reqs <nr_loops> <concurrent_reqs>\n"
75 " read <target> <offset> <size>\n"
76 " write <target> <offset> < data\n"
77 " truncate <target> <size>\n"
82 " clone <src> <dst>\n"
102 struct xseg_config cfg;
104 uint32_t srcport, dstport;
106 #define mkname mkname_heavy
107 /* heavy distributes duplicates much more widely than light
108 * ./xseg-tool random 100000 | cut -d' ' -f2- | sort | uniq -d -c |wc -l
111 xport sport = NoPort;
114 static void init_local_signal()
116 struct xseg_port *port;
117 if (xseg && sport != srcport){
118 xseg_init_local_signal(xseg, srcport);
120 port = xseg_get_port(xseg, srcport);
121 sd = xseg_get_signal_desc(xseg, port);
125 void mkname_heavy(char *name, uint32_t namelen, uint32_t seed)
129 for (i = 0; i < namelen; i += 1) {
130 c = seed + (seed >> 8) + (seed >> 16) + (seed >> 24);
131 c = '0' + ((c + (c >> 4)) & 0xf);
135 seed *= ((seed % 137911) | 1) * 137911;
139 void mkname_light(char *name, uint32_t namelen, uint32_t seed)
143 for (i = 0; i < namelen; i += 1) {
145 name[i] = 'A' + (c & 0xf);
150 uint64_t pick(uint64_t size)
152 return (uint64_t)((double)(RAND_MAX) / random());
155 void mkchunk( char *chunk, uint32_t datalen,
156 char *target, uint32_t targetlen, uint64_t offset)
158 long i, r, bufsize = targetlen + 16;
160 r = datalen % bufsize;
161 snprintf(buf, bufsize, "%016llx%s", (unsigned long long)offset, target);
163 for (i = 0; i <= (long)datalen - bufsize; i += bufsize)
164 memcpy(chunk + i, buf, bufsize);
166 memcpy(chunk + datalen - r, buf, r);
169 int chkchunk( char *chunk, uint32_t datalen,
170 char *target, uint32_t targetlen, uint64_t offset)
173 int bufsize = targetlen + 16;
175 r = datalen % targetlen;
176 snprintf(buf, bufsize, "%016llx%s", (unsigned long long)offset, target);
178 for (i = 0; i <= (long)datalen - bufsize; i += bufsize)
179 if (memcmp(chunk + i, buf, bufsize)) {
180 /*printf("mismatch: '%*s'* vs '%*s'\n",
181 bufsize, buf, datalen, chunk);
186 if (memcmp(chunk + datalen - r, buf, r))
193 #define ALLOC_MIN 4096
194 #define ALLOC_MAX 1048576
196 void inputbuf(FILE *fp, char **retbuf, uint64_t *retsize)
198 static uint64_t alloc_size;
204 if (alloc_size < ALLOC_MIN)
205 alloc_size = ALLOC_MIN;
207 if (alloc_size > ALLOC_MAX)
208 alloc_size = ALLOC_MAX;
210 p = realloc(buf, alloc_size);
221 r = fread(buf + size, 1, alloc_size - size, fp);
225 if (size >= alloc_size) {
226 p = realloc(buf, alloc_size * 2);
244 void report_request(struct xseg_request *req)
246 char target[64], data[64];
247 char *req_target, *req_data;
248 unsigned int end = (req->targetlen> 63) ? 63 : req->targetlen;
249 req_target = xseg_get_target(xseg, req);
250 req_data = xseg_get_data(xseg, req);
252 strncpy(target, req_target, end);
254 strncpy(data, req_data, 63);
257 "Request %lx: target[%u](xptr: %llu): %s, data[%llu](xptr: %llu): %s \n\t"
258 "offset: %llu, size: %llu, serviced; %llu, op: %u, state: %u, flags: %u \n\t"
259 "src: %u, transit: %u, dst: %u, effective dst: %u\n",
260 (unsigned long) req, req->targetlen, (unsigned long long)req->target,
262 (unsigned long long) req->datalen, (unsigned long long) req->data,
264 (unsigned long long) req->offset, (unsigned long long) req->size,
265 (unsigned long long) req->serviced, req->op, req->state, req->flags,
266 (unsigned int) req->src_portno, (unsigned int) req->transit_portno,
267 (unsigned int) req->dst_portno, (unsigned int) req->effective_dst_portno);
272 int cmd_info(char *target)
274 uint32_t targetlen = strlen(target);
275 size_t size = sizeof(uint64_t);
278 struct xseg_request *req;
281 req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
283 fprintf(stderr, "No request!\n");
287 r = xseg_prep_request(xseg, req, targetlen, size);
289 fprintf(stderr, "Cannot prepare request! (%lu, %lu)\n",
290 (unsigned long) targetlen, (unsigned long) size);
291 xseg_put_request(xseg, req, srcport);
295 req_target = xseg_get_target(xseg, req);
296 strncpy(req_target, target, targetlen);
301 p = xseg_submit(xseg, req, srcport, X_ALLOC);
305 xseg_signal(xseg, p);
310 int cmd_read(char *target, uint64_t offset, uint64_t size)
312 uint32_t targetlen = strlen(target);
316 struct xseg_request *req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
318 fprintf(stderr, "No request\n");
322 r = xseg_prep_request(xseg, req, targetlen, size);
324 fprintf(stderr, "Cannot prepare request! (%lu, %llu)\n",
325 (unsigned long)targetlen, (unsigned long long)size);
326 xseg_put_request(xseg, req, srcport);
330 req_target = xseg_get_target(xseg, req);
331 strncpy(req_target, target, targetlen);
332 req->offset = offset;
336 p = xseg_submit(xseg, req, srcport, X_ALLOC);
340 xseg_signal(xseg, p);
344 int cmd_write(char *target, uint64_t offset)
350 char *req_target, *req_data;
351 uint32_t targetlen = strlen(target);
352 struct xseg_request *req;
354 inputbuf(stdin, &buf, &size);
356 fprintf(stderr, "No input\n");
360 req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
362 fprintf(stderr, "No request\n");
366 r = xseg_prep_request(xseg, req, targetlen, size);
368 fprintf(stderr, "Cannot prepare request! (%lu, %llu)\n",
369 (unsigned long)targetlen, (unsigned long long)size);
370 xseg_put_request(xseg, req, srcport);
374 req_target = xseg_get_target(xseg, req);
375 strncpy(req_target, target, targetlen);
377 req_data = xseg_get_data(xseg, req);
378 memcpy(req_data, buf, size);
379 req->offset = offset;
383 p = xseg_submit(xseg, req, srcport, X_ALLOC);
385 fprintf(stderr, "Cannot submit\n");
388 xseg_signal(xseg, p);
393 int cmd_truncate(char *target, uint64_t offset)
398 int cmd_delete(char *target)
400 uint32_t targetlen = strlen(target);
402 struct xseg_request *req;
404 xseg_bind_port(xseg, srcport, NULL);
406 req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
408 fprintf(stderr, "No request!\n");
412 r = xseg_prep_request(xseg, req, targetlen, 0);
414 fprintf(stderr, "Cannot prepare request! (%lu, %lu)\n",
415 (unsigned long) targetlen, (unsigned long) req->bufferlen - targetlen);
416 xseg_put_request(xseg, req, srcport);
420 char *reqtarget = xseg_get_target(xseg, req);
421 strncpy(reqtarget, target, targetlen);
424 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
426 fprintf(stderr, "Couldn't submit request\n");
427 xseg_put_request(xseg, req, srcport);
431 xseg_signal(xseg, p);
436 int cmd_acquire(char *target)
438 uint32_t targetlen = strlen(target);
442 struct xseg_request *req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
444 fprintf(stderr, "No request\n");
448 r = xseg_prep_request(xseg, req, targetlen, 0);
450 fprintf(stderr, "Cannot prepare request! (%lu, 0)\n",
451 (unsigned long)targetlen);
452 xseg_put_request(xseg, req, srcport);
456 req_target = xseg_get_target(xseg, req);
457 strncpy(req_target, target, targetlen);
461 req->flags = XF_NOSYNC;
462 p = xseg_submit(xseg, req, srcport, X_ALLOC);
466 xseg_signal(xseg, p);
470 int cmd_release(char *target)
472 uint32_t targetlen = strlen(target);
476 struct xseg_request *req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
478 fprintf(stderr, "No request\n");
482 r = xseg_prep_request(xseg, req, targetlen, 0);
484 fprintf(stderr, "Cannot prepare request! (%lu, 0)\n",
485 (unsigned long)targetlen);
486 xseg_put_request(xseg, req, srcport);
490 req_target = xseg_get_target(xseg, req);
491 strncpy(req_target, target, targetlen);
495 //req->flags = XF_FORCE;
497 p = xseg_submit(xseg, req, srcport, X_ALLOC);
501 xseg_signal(xseg, p);
506 int cmd_open(char *target)
508 uint32_t targetlen = strlen(target);
512 struct xseg_request *req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
514 fprintf(stderr, "No request\n");
518 r = xseg_prep_request(xseg, req, targetlen, 0);
520 fprintf(stderr, "Cannot prepare request! (%lu, 0)\n",
521 (unsigned long)targetlen);
522 xseg_put_request(xseg, req, srcport);
526 req_target = xseg_get_target(xseg, req);
527 strncpy(req_target, target, targetlen);
531 p = xseg_submit(xseg, req, srcport, X_ALLOC);
535 xseg_signal(xseg, p);
539 int cmd_close(char *target)
541 uint32_t targetlen = strlen(target);
545 struct xseg_request *req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
547 fprintf(stderr, "No request\n");
551 r = xseg_prep_request(xseg, req, targetlen, 0);
553 fprintf(stderr, "Cannot prepare request! (%lu, 0)\n",
554 (unsigned long)targetlen);
555 xseg_put_request(xseg, req, srcport);
559 req_target = xseg_get_target(xseg, req);
560 strncpy(req_target, target, targetlen);
564 req->flags = XF_FORCE;
565 p = xseg_submit(xseg, req, srcport, X_ALLOC);
569 xseg_signal(xseg, p);
574 int cmd_copy(char *src, char *dst)
576 uint32_t targetlen = strlen(dst);
577 uint32_t parentlen = strlen(src);
578 struct xseg_request *req;
579 struct xseg_request_copy *xcopy;
580 req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
582 fprintf(stderr, "No request\n");
586 int r = xseg_prep_request(xseg, req, targetlen,
587 sizeof(struct xseg_request_copy));
589 fprintf(stderr, "Cannot prepare request!\n");
590 xseg_put_request(xseg, req, srcport);
594 char *target = xseg_get_target(xseg, req);
595 char *data = xseg_get_data(xseg, req);
597 strncpy(target, dst, targetlen);
598 xcopy = (struct xseg_request_copy *) data;
599 strncpy(xcopy->target, src, parentlen);
600 xcopy->targetlen = parentlen;
602 req->size = sizeof(struct xseg_request_copy);
605 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
607 fprintf(stderr, "Cannot submit request\n");
610 xseg_signal(xseg, p);
616 int cmd_clone(char *src, char *dst, long size)
619 uint32_t targetlen = strlen(dst);
620 uint32_t parentlen = strlen(src);
621 struct xseg_request *req;
622 struct xseg_request_clone *xclone;
623 xseg_bind_port(xseg, srcport, NULL);
624 req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
626 fprintf(stderr, "No request\n");
630 int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_clone));
632 fprintf(stderr, "Cannot prepare request!\n");
633 xseg_put_request(xseg, req, srcport);
637 char *target = xseg_get_target(xseg, req);
638 char *data = xseg_get_data(xseg, req);
640 strncpy(target, dst, targetlen);
641 xclone = (struct xseg_request_clone *) data;
642 strncpy(xclone->target, src, parentlen);
643 xclone->targetlen = parentlen;
645 xclone->size = (uint64_t)size;
646 xclone->size *= 1024*1024;
651 req->size = sizeof(struct xseg_request_clone);
654 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
656 fprintf(stderr, "Cannot submit request\n");
659 xseg_signal(xseg, p);
664 int cmd_snapshot(char *src, char *dst, long block_size)
667 uint32_t targetlen = strlen(src);
668 uint32_t parentlen = strlen(dst);
669 struct xseg_request *req;
670 struct xseg_request_snapshot *xsnapshot;
671 xseg_bind_port(xseg, srcport, NULL);
672 req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
674 fprintf(stderr, "No request\n");
678 int r = xseg_prep_request(xseg, req, targetlen, sizeof(struct xseg_request_snapshot));
680 fprintf(stderr, "Cannot prepare request!\n");
681 xseg_put_request(xseg, req, srcport);
685 char *target = xseg_get_target(xseg, req);
686 char *data = xseg_get_data(xseg, req);
688 fprintf(stdout, "Snapshotting %s(%u) to %s(%u)\n", src, targetlen, dst, parentlen);
689 strncpy(target, src, targetlen);
690 xsnapshot = (struct xseg_request_snapshot *) data;
691 strncpy(xsnapshot->target, dst, parentlen);
692 xsnapshot->targetlen = parentlen;
694 req->size = (uint64_t) block_size;
695 req->op = X_SNAPSHOT;
697 xport p = xseg_submit(xseg, req, srcport, X_ALLOC);
699 fprintf(stderr, "Cannot submit request\n");
702 xseg_signal(xseg, p);
707 void log_req(int logfd, uint32_t portno2, uint32_t portno1, int op, int method,
708 struct xseg_request *req)
711 char target[64], data[64];
712 char *req_target, *req_data;
713 /* null terminate name in case of req->target is less than 63 characters,
714 * and next character after name (aka first byte of next buffer) is not
717 unsigned int end = (req->targetlen > 63) ? 63 : req->targetlen;
719 req_target = xseg_get_target(xseg, req);
720 req_data = xseg_get_data(xseg, req);
722 logfp = fdopen(logfd, "a");
728 strncpy(target, req_target, end);
730 strncpy(data, req_data, 63);
734 "src port: %u, dst port: %u, op:%u offset: %llu size: %lu, reqstate: %u\n"
735 "target[%u]: '%s', data[%llu]:\n%s------------------\n\n",
736 (unsigned int)portno1,
737 (unsigned int)portno2,
738 (unsigned int)req->op,
739 (unsigned long long)req->offset,
740 (unsigned long)req->size,
741 (unsigned int)req->state,
742 (unsigned int)req->targetlen, target,
743 (unsigned long long)req->datalen, data);
747 "src port: %u, dst port: %u, op: %u\n",
748 (unsigned int)portno1,
749 (unsigned int)portno2,
750 (unsigned int)req->op);
753 fprintf(logfp, "src port: %u, dst port: %u, reqs: %llu\n",
754 (unsigned int)portno1,
755 (unsigned int)portno2,
756 (unsigned long long)++reqs);
764 #define LOG_RECEIVE 1
765 int cmd_bridge(uint32_t portno1, uint32_t portno2, char *logfile, char *how)
768 struct xseg_request *req;
770 if (!strcmp(logfile, "-"))
773 logfd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0600);
780 if (!strcmp(how, "full"))
782 else if (!strcmp(how, "summary"))
788 int reloop = 0, active;
789 xseg_prepare_wait(xseg, portno1);
790 xseg_prepare_wait(xseg, portno2);
797 req = xseg_accept(xseg, portno1, 0);
799 xseg_submit(xseg, req, portno2, X_ALLOC);
800 log_req(logfd, portno1, portno2, LOG_ACCEPT, method, req);
804 req = xseg_accept(xseg, portno2, 0);
806 xseg_submit(xseg, req, portno1, X_ALLOC);
807 log_req(logfd, portno2, portno1, LOG_ACCEPT, method, req);
811 req = xseg_receive(xseg, portno1, 0);
813 xseg_respond(xseg, req, portno2, X_ALLOC);
814 log_req(logfd, portno1, portno2, LOG_RECEIVE, method, req);
818 req = xseg_receive(xseg, portno2, 0);
820 xseg_respond(xseg, req, portno1, X_ALLOC);
821 log_req(logfd, portno2, portno1, LOG_RECEIVE, method, req);
828 /* wait on multiple queues? */
829 xseg_wait_signal(xseg, 100000);
832 xseg_cancel_wait(xseg, portno1);
833 xseg_cancel_wait(xseg, portno2);
844 int cmd_rndwrite(long loops, int32_t seed, uint32_t targetlen, uint32_t chunksize, uint64_t size)
849 if (targetlen >= chunksize) {
850 fprintf(stderr, "targetlen >= chunksize\n");
854 char *p = realloc(namebuf, targetlen+1);
856 fprintf(stderr, "Cannot allocate memory\n");
861 p = realloc(chunk, chunksize);
863 fprintf(stderr, "Cannot allocate memory\n");
867 memset(chunk, 0, chunksize);
871 struct xseg_request *submitted = NULL, *received;
872 long nr_submitted = 0, nr_received = 0, nr_failed = 0;
876 char *req_data, *req_target;
881 xseg_prepare_wait(xseg, srcport);
882 if (nr_submitted < loops &&
883 (submitted = xseg_get_request(xseg, srcport, dstport, X_ALLOC))) {
884 xseg_cancel_wait(xseg, srcport);
885 r = xseg_prep_request(xseg, submitted, targetlen, chunksize);
887 fprintf(stderr, "Cannot prepare request! (%u, %u)\n",
888 targetlen, chunksize);
889 xseg_put_request(xseg, submitted, srcport);
893 req_target = xseg_get_target(xseg, submitted);
894 req_data = xseg_get_data(xseg, submitted);
897 mkname(namebuf, targetlen, seed);
898 namebuf[targetlen] = 0;
899 //printf("%ld: %s\n", nr_submitted, namebuf);
900 strncpy(req_target, namebuf, targetlen);
901 offset = 0;// pick(size);
902 mkchunk(req_data, chunksize, namebuf, targetlen, offset);
904 submitted->offset = offset;
905 submitted->size = chunksize;
906 submitted->op = X_WRITE;
907 submitted->flags |= XF_NOSYNC;
909 port = xseg_submit(xseg, submitted, srcport, X_ALLOC);
910 if (port == NoPort) {
911 xseg_put_request(xseg, submitted, srcport);
915 xseg_signal(xseg, port);
919 received = xseg_receive(xseg, srcport, 0);
921 xseg_cancel_wait(xseg, srcport);
923 if (!(received->state & XS_SERVED)) {
925 report_request(received);
927 if (xseg_put_request(xseg, received, srcport))
928 fprintf(stderr, "Cannot put request at port %u\n", received->src_portno);
931 if (!submitted && !received)
932 xseg_wait_signal(xseg, sd, 1000000);
934 if (nr_submitted % 1000 == 0 && !reported) {
936 fprintf(stderr, "submitted %ld, received %ld, failed %ld\n",
937 nr_submitted, nr_received, nr_failed);
940 if (nr_received >= loops)
944 fprintf(stderr, "submitted %ld, received %ld, failed %ld\n",
945 nr_submitted, nr_received, nr_failed);
949 int cmd_rnddelete(long loops, int32_t seed, uint32_t targetlen)
953 char *p = realloc(namebuf, targetlen+1);
955 fprintf(stderr, "Cannot allocate memory\n");
962 struct xseg_request *submitted = NULL, *received;
963 long nr_submitted = 0, nr_received = 0, nr_failed = 0;
971 xseg_prepare_wait(xseg, srcport);
972 if (nr_submitted < loops &&
973 (submitted = xseg_get_request(xseg, srcport, dstport, X_ALLOC))) {
974 xseg_cancel_wait(xseg, srcport);
975 r = xseg_prep_request(xseg, submitted, targetlen, 0);
977 fprintf(stderr, "Cannot prepare request! (%u, %u)\n",
979 xseg_put_request(xseg, submitted, srcport);
983 req_target = xseg_get_target(xseg, submitted);
986 mkname(namebuf, targetlen, seed);
987 namebuf[targetlen] = 0;
988 //printf("%ld: %s\n", nr_submitted, namebuf);
989 strncpy(req_target, namebuf, targetlen);
990 submitted->offset = 0;
992 submitted->op = X_DELETE;
993 submitted->flags = 0;
995 port = xseg_submit(xseg, submitted, srcport, X_ALLOC);
996 if (port == NoPort) {
997 xseg_put_request(xseg, submitted, srcport);
1001 xseg_signal(xseg, port);
1005 received = xseg_receive(xseg, srcport, 0);
1007 xseg_cancel_wait(xseg, srcport);
1009 if (!(received->state & XS_SERVED)) {
1011 report_request(received);
1013 if (xseg_put_request(xseg, received, srcport))
1014 fprintf(stderr, "Cannot put request at port %u\n", received->src_portno);
1017 if (!submitted && !received)
1018 xseg_wait_signal(xseg, sd, 1000000);
1020 if (nr_submitted % 1000 == 0 && !reported) {
1022 fprintf(stderr, "submitted %ld, received %ld, failed %ld\n",
1023 nr_submitted, nr_received, nr_failed);
1026 if (nr_received >= loops)
1030 fprintf(stderr, "submitted %ld, received %ld, failed %ld\n",
1031 nr_submitted, nr_received, nr_failed);
1035 * prepare/wait rhythm,
1036 * files are converted to independent chunk access patterns,
1039 int cmd_rndread(long loops, int32_t seed, uint32_t targetlen, uint32_t chunksize, uint64_t size)
1044 if (targetlen >= chunksize) {
1045 fprintf(stderr, "targetlen >= chunksize\n");
1049 char *p = realloc(namebuf, targetlen+1);
1051 fprintf(stderr, "Cannot allocate memory\n");
1056 p = realloc(chunk, chunksize);
1058 fprintf(stderr, "Cannot allocate memory\n");
1062 memset(chunk, 0, chunksize);
1066 struct xseg_request *submitted = NULL, *received;
1067 long nr_submitted = 0, nr_received = 0, nr_failed = 0, nr_mismatch = 0;
1068 int reported = 0, r;
1071 char *req_data, *req_target;
1072 init_local_signal();
1077 xseg_prepare_wait(xseg, srcport);
1078 if (nr_submitted < loops &&
1079 (submitted = xseg_get_request(xseg, srcport, dstport, X_ALLOC))) {
1080 xseg_cancel_wait(xseg, srcport);
1081 r = xseg_prep_request(xseg, submitted, targetlen, chunksize);
1083 fprintf(stderr, "Cannot prepare request! (%u, %u)\n",
1084 targetlen, chunksize);
1085 xseg_put_request(xseg, submitted, srcport);
1089 req_target = xseg_get_target(xseg, submitted);
1091 mkname(namebuf, targetlen, seed);
1092 namebuf[targetlen] = 0;
1093 //printf("%ld: %s\n", nr_submitted, namebuf);
1094 offset = 0;//pick(size);
1096 strncpy(req_target, namebuf, targetlen);
1097 submitted->offset = offset;
1098 submitted->size = chunksize;
1099 submitted->op = X_READ;
1100 port = xseg_submit(xseg, submitted, srcport, X_ALLOC);
1101 if (port == NoPort) {
1102 xseg_put_request(xseg, submitted, srcport);
1106 xseg_signal(xseg, port);
1110 received = xseg_receive(xseg, srcport, 0);
1112 xseg_cancel_wait(xseg, srcport);
1114 req_target = xseg_get_target(xseg, received);
1115 req_data = xseg_get_data(xseg, received);
1116 if (!(received->state & XS_SERVED)) {
1118 report_request(received);
1119 } else if (!chkchunk(req_data, received->datalen,
1120 req_target, received->targetlen, received->offset)) {
1121 // report_request(received);
1125 if (xseg_put_request(xseg, received, srcport))
1126 fprintf(stderr, "Cannot put request at port %u\n", received->src_portno);
1129 if (!submitted && !received)
1130 xseg_wait_signal(xseg, sd, 1000000);
1132 if (nr_submitted % 1000 == 0 && !reported) {
1134 fprintf(stderr, "submitted %ld, received %ld, failed %ld, mismatched %ld\n",
1135 nr_submitted, nr_received, nr_failed, nr_mismatch);
1138 if (nr_received >= loops)
1142 fprintf(stderr, "submitted %ld, received %ld, failed %ld, mismatched %ld\n",
1143 nr_submitted, nr_received, nr_failed, nr_mismatch);
1147 int cmd_submit_reqs(long loops, long concurrent_reqs, int op)
1152 struct xseg_request *submitted = NULL, *received;
1153 long nr_submitted = 0, nr_received = 0, nr_failed = 0, nr_mismatch = 0, nr_flying = 0;
1156 uint32_t targetlen = 10, chunksize = 4096;
1157 struct timeval tv1, tv2;
1159 char *req_data, *req_target;
1161 xseg_bind_port(xseg, srcport, NULL);
1163 gettimeofday(&tv1, NULL);
1166 xseg_prepare_wait(xseg, srcport);
1167 if (nr_submitted < loops && nr_flying < concurrent_reqs &&
1168 (submitted = xseg_get_request(xseg, srcport, dstport, X_ALLOC))) {
1169 xseg_cancel_wait(xseg, srcport);
1170 r = xseg_prep_request(xseg, submitted, targetlen, chunksize);
1172 fprintf(stderr, "Cannot prepare request! (%u, %u)\n",
1173 targetlen, chunksize);
1174 xseg_put_request(xseg, submitted, srcport);
1181 offset = 0;//pick(size);
1183 submitted->offset = offset;
1184 submitted->size = chunksize;
1185 req_target = xseg_get_target(xseg, submitted);
1186 req_data = xseg_get_data(xseg, submitted);
1189 submitted->op = X_INFO;
1191 submitted->op = X_READ;
1193 submitted->op = X_WRITE;
1194 mkchunk(req_data, submitted->datalen, req_target, submitted->targetlen, submitted->offset);
1197 p = xseg_submit(xseg, submitted, srcport, X_ALLOC);
1199 if (xseg_signal(xseg, p) < 0)
1200 perror("Cannot signal peer");
1203 received = xseg_receive(xseg, srcport, 0);
1205 xseg_cancel_wait(xseg, srcport);
1207 if (nr_received == 0)
1208 fprintf(stderr, "latency (time for the first req to complete): %llu usecs\n",
1209 (unsigned long long)received->elapsed);
1211 if (!(received->state & XS_SERVED)) {
1213 //report_request(received);
1216 if (xseg_put_request(xseg, received, srcport))
1217 fprintf(stderr, "Cannot put request at port %u\n", received->src_portno);
1220 if (!submitted && !received)
1221 xseg_wait_signal(xseg, sd, 10000000L);
1223 if (nr_received >= loops)
1226 gettimeofday(&tv2, NULL);
1228 fprintf(stderr, "submitted %ld, received %ld, failed %ld, mismatched %ld\n",
1229 nr_submitted, nr_received, nr_failed, nr_mismatch);
1230 long t = (tv2.tv_sec - tv1.tv_sec)*1000000 + (tv2.tv_usec - tv1.tv_usec);
1231 fprintf(stderr, "elpased time: %lf secs, throughput: %lf reqs/sec\n", (double) t / 1000000.0, (double) nr_submitted / (t / 1000000.0));
1236 static void lock_status(struct xlock *lock, char *buf, int len)
1239 if (lock->owner == Noone)
1240 r = snprintf(buf, len, "Locked: No");
1242 r = snprintf(buf, len, "Locked: Yes (Owner: %lu)", lock->owner);
1247 int cmd_report(uint32_t portno)
1249 char fls[64], rls[64], pls[64]; // buffer to store lock status
1250 struct xseg_port *port = xseg_get_port(xseg, portno);
1252 printf("port %u is not assigned\n", portno);
1255 struct xq *fq, *rq, *pq;
1256 fq = xseg_get_queue(xseg, port, free_queue);
1257 rq = xseg_get_queue(xseg, port, request_queue);
1258 pq = xseg_get_queue(xseg, port, reply_queue);
1259 lock_status(&port->fq_lock, fls, 64);
1260 lock_status(&port->rq_lock, rls, 64);
1261 lock_status(&port->pq_lock, pls, 64);
1262 fprintf(stderr, "port %u:\n"
1263 " requests: %llu/%llu next: %u dst gw: %u\n"
1264 " free_queue [%p] count : %4llu | %s\n"
1265 " request_queue [%p] count : %4llu | %s\n"
1266 " reply_queue [%p] count : %4llu | %s\n",
1267 portno, (unsigned long long)port->alloc_reqs,
1268 (unsigned long long)port->max_alloc_reqs,
1269 xseg->path_next[portno],
1270 xseg->dst_gw[portno],
1271 (void *)fq, (unsigned long long)xq_count(fq), fls,
1272 (void *)rq, (unsigned long long)xq_count(rq), rls,
1273 (void *)pq, (unsigned long long)xq_count(pq), pls);
1282 xseg = xseg_join(cfg.type, cfg.name, "posix", NULL);
1284 fprintf(stderr, "cannot join segment!\n");
1289 static void print_hanlder(char *name, struct xobject_h *obj_h)
1292 lock_status(&obj_h->lock, ls, 64);
1293 fprintf(stderr, "%20s: free: %4llu, allocated: %4llu, allocated space: %7llu (object size: %llu), Lock %s\n",
1295 (unsigned long long) obj_h->nr_free,
1296 (unsigned long long) obj_h->nr_allocated,
1297 (unsigned long long) obj_h->allocated_space,
1298 (unsigned long long) obj_h->obj_size, ls);
1302 static void print_heap(struct xseg *xseg)
1312 MULT[2] = 1024*1024;
1313 MULT[3] = 1024*1024*1024;
1317 fprintf(stderr, "Heap usage: ");
1319 t = xseg->heap->cur;
1326 t = xseg->heap->cur / MULT[u];
1328 float tf = ((float)(xseg->heap->cur))/((float)MULT[u]);
1329 fprintf(stderr, "%2.1f %s/", tf, UNIT[u]);
1332 unsigned int tu = xseg->heap->cur / MULT[u];
1333 fprintf(stderr, "%3u %s/", tu, UNIT[u]);
1337 t = xseg->config.heap_size;
1344 t = xseg->config.heap_size/MULT[u];
1346 float tf = ((float)(xseg->config.heap_size))/(float)MULT[u];
1347 fprintf(stderr, "%2.1f %s ", tf, UNIT[u]);
1350 unsigned int tu = xseg->config.heap_size / MULT[u];
1351 fprintf(stderr, "%3u %s ", tu, UNIT[u]);
1354 lock_status(&xseg->heap->lock, ls, 64);
1355 fprintf(stderr, "(%llu / %llu), %s\n",
1356 (unsigned long long)xseg->heap->cur,
1357 (unsigned long long)xseg->config.heap_size,
1361 int cmd_reportall(void)
1368 fprintf(stderr, "Segment lock: %s\n",
1369 (xseg->shared->flags & XSEG_F_LOCK) ? "Locked" : "Unlocked");
1371 /* fprintf(stderr, "Heap usage: %llu / %llu\n", */
1372 /* (unsigned long long)xseg->heap->cur, */
1373 /* (unsigned long long)xseg->config.heap_size); */
1374 fprintf(stderr, "Handlers: \n");
1375 print_hanlder("Requests handler", xseg->request_h);
1376 print_hanlder("Ports handler", xseg->port_h);
1377 print_hanlder("Objects handler", xseg->object_handlers);
1378 fprintf(stderr, "\n");
1380 for (t = 0; t < xseg->config.nr_ports; t++)
1387 int finish_req(struct xseg_request *req, enum req_action action)
1389 if (action == COMPLETE){
1390 req->state &= ~XS_FAILED;
1391 req->state |= XS_SERVED;
1393 req->state |= XS_FAILED;
1394 req->state &= ~XS_SERVED;
1397 xport p = xseg_respond(xseg, req, srcport, X_ALLOC);
1399 xseg_put_request(xseg, req, srcport);
1401 xseg_signal(xseg, p);
1405 //FIXME this should be in xseg lib?
1406 static int isDangling(struct xseg_request *req)
1409 struct xseg_port *port;
1410 for (i = 0; i < xseg->config.nr_ports; i++) {
1411 if (xseg->ports[i]){
1412 port = xseg_get_port(xseg, i);
1414 fprintf(stderr, "Inconsisten port <-> portno mapping %u", i);
1417 struct xq *fq, *rq, *pq;
1418 fq = xseg_get_queue(xseg, port, free_queue);
1419 rq = xseg_get_queue(xseg, port, request_queue);
1420 pq = xseg_get_queue(xseg, port, reply_queue);
1421 xlock_acquire(&port->fq_lock, srcport);
1422 if (__xq_check(fq, XPTR_MAKE(req, xseg->segment))){
1423 xlock_release(&port->fq_lock);
1426 xlock_release(&port->fq_lock);
1427 xlock_acquire(&port->rq_lock, srcport);
1428 if (__xq_check(rq, XPTR_MAKE(req, xseg->segment))){
1429 xlock_release(&port->rq_lock);
1432 xlock_release(&port->rq_lock);
1433 xlock_acquire(&port->pq_lock, srcport);
1434 if (__xq_check(pq, XPTR_MAKE(req, xseg->segment))){
1435 xlock_release(&port->pq_lock);
1438 xlock_release(&port->pq_lock);
1444 int prompt_user(char *msg)
1447 printf("%s [y/n]: ", msg);
1450 if (c == 'y' || c == 'Y')
1452 else if (c == 'n' || c == 'N')
1454 else if (c == '\n'){
1456 printf("%s [y/n]: ", msg);
1464 //FIXME this should be in xseg lib?
1465 int cmd_verify(int fix)
1470 if (xseg->shared->flags & XSEG_F_LOCK){
1471 fprintf(stderr, "Segment lock: Locked\n");
1472 if (fix && prompt_user("Unlock it ?"))
1473 xseg->shared->flags &= ~XSEG_F_LOCK;
1476 if (xseg->heap->lock.owner != Noone){
1477 fprintf(stderr, "Heap lock: Locked (Owner: %llu)\n",
1478 (unsigned long long)xseg->heap->lock.owner);
1479 if (fix && prompt_user("Unlock it ?"))
1480 xlock_release(&xseg->heap->lock);
1483 if (xseg->request_h->lock.owner != Noone){
1484 fprintf(stderr, "Requests handler lock: Locked (Owner: %llu)\n",
1485 (unsigned long long)xseg->request_h->lock.owner);
1486 if (fix && prompt_user("Unlock it ?"))
1487 xlock_release(&xseg->request_h->lock);
1489 if (xseg->port_h->lock.owner != Noone){
1490 fprintf(stderr, "Ports handler lock: Locked (Owner: %llu)\n",
1491 (unsigned long long)xseg->port_h->lock.owner);
1492 if (fix && prompt_user("Unlock it ?"))
1493 xlock_release(&xseg->port_h->lock);
1495 if (xseg->object_handlers->lock.owner != Noone){
1496 fprintf(stderr, "Objects handler lock: Locked (Owner: %llu)\n",
1497 (unsigned long long)xseg->object_handlers->lock.owner);
1498 if (fix && prompt_user("Unlock it ?"))
1499 xlock_release(&xseg->object_handlers->lock);
1501 //take segment lock?
1503 struct xseg_port *port;
1504 for (i = 0; i < xseg->config.nr_ports; i++) {
1505 if (xseg->ports[i]){
1506 port = xseg_get_port(xseg, i);
1508 fprintf(stderr, "Inconsisten port <-> portno mapping %u", i);
1511 if (port->fq_lock.owner != Noone) {
1512 fprintf(stderr, "Free queue lock of port %u locked (Owner %llu)\n",
1513 i, (unsigned long long)port->fq_lock.owner);
1514 if (fix && prompt_user("Unlock it ?"))
1515 xlock_release(&port->fq_lock);
1517 if (port->rq_lock.owner != Noone) {
1518 fprintf(stderr, "Request queue lock of port %u locked (Owner %llu)\n",
1519 i, (unsigned long long)port->rq_lock.owner);
1520 if (fix && prompt_user("Unlock it ?"))
1521 xlock_release(&port->rq_lock);
1523 if (port->pq_lock.owner != Noone) {
1524 fprintf(stderr, "Reply queue lock of port %u locked (Owner %llu)\n",
1525 i, (unsigned long long)port->pq_lock.owner);
1526 if (fix && prompt_user("Unlock it ?"))
1527 xlock_release(&port->pq_lock);
1532 struct xobject_h *obj_h = xseg->request_h;
1533 struct xobject_iter it;
1535 struct xseg_request *req;
1536 xlock_acquire(&obj_h->lock, srcport);
1537 xobj_iter_init(obj_h, &it);
1538 while (xobj_iterate(obj_h, &it, (void **)&req)){
1539 //FIXME this will not work cause obj->magic - req->serial is not
1540 //touched when a request is get
1541 /* if (obj->magic != MAGIC_REQ && t->src_portno == portno){ */
1542 if (isDangling(req) && !__xobj_isFree(obj_h, req)){
1543 report_request(req);
1544 if (fix && prompt_user("Fail it ?")){
1545 printf("Finishing ...\n");
1546 finish_req(req, FAIL);
1550 xlock_release(&obj_h->lock);
1554 int cmd_inspectq(xport portno, enum queue qt)
1561 struct xseg_port *port = xseg_get_port(xseg, portno);
1564 if (qt == FREE_QUEUE){
1565 q = xseg_get_queue(xseg, port, free_queue);
1568 else if (qt == REQUEST_QUEUE){
1569 q = xseg_get_queue(xseg, port, request_queue);
1572 else if (qt == REPLY_QUEUE) {
1573 q = xseg_get_queue(xseg, port, reply_queue);
1578 xlock_acquire(l, srcport);
1579 xqindex i,c = xq_count(q);
1581 struct xseg_request *req;
1583 for (i = 0; i < c; i++) {
1584 xqi = __xq_pop_head(q);
1585 req = XPTR_TAKE(xqi, xseg->segment);
1586 report_request(req);
1587 __xq_append_tail(q, xqi);
1591 fprintf(stderr, "Queue is empty\n\n");
1598 int cmd_request(struct xseg_request *req, enum req_action action)
1603 struct xobject_h *obj_h = xseg->request_h;
1604 if (!xobj_check(obj_h, req))
1607 if (action == REPORT)
1608 report_request(req);
1609 else if (action == FAIL){
1610 report_request(req);
1611 if (prompt_user("fail it ?")){
1612 printf("Finishing ...\n");
1613 finish_req(req, FAIL);
1616 else if (action == COMPLETE){
1617 report_request(req);
1618 if (prompt_user("Complete it ?")){
1619 printf("Finishing ...\n");
1620 finish_req(req, COMPLETE);
1626 int cmd_create(void)
1628 int r = xseg_create(&cfg);
1630 fprintf(stderr, "cannot create segment!\n");
1634 fprintf(stderr, "Segment initialized.\n");
1638 int cmd_destroy(void)
1640 if (!xseg && cmd_join())
1645 fprintf(stderr, "Segment destroyed.\n");
1649 int cmd_alloc_requests(unsigned long nr)
1651 return xseg_alloc_requests(xseg, srcport, nr);
1654 int cmd_free_requests(unsigned long nr)
1656 return xseg_free_requests(xseg, srcport, nr);
1659 int cmd_put_requests(void)
1661 struct xseg_request *req;
1664 req = xseg_accept(xseg, dstport, 0);
1667 if (xseg_put_request(xseg, req, srcport))
1668 fprintf(stderr, "Cannot put request at port %u\n", req->src_portno);
1674 int cmd_finish(unsigned long nr, int fail)
1676 struct xseg_request *req;
1677 char *buf = malloc(sizeof(char) * 8128);
1678 char *req_target, *req_data;
1679 xseg_bind_port(xseg, srcport, NULL);
1680 init_local_signal();
1684 xseg_prepare_wait(xseg, srcport);
1685 req = xseg_accept(xseg, srcport, 0);
1687 req_target = xseg_get_target(xseg, req);
1688 req_data = xseg_get_data(xseg, req);
1689 xseg_cancel_wait(xseg, srcport);
1691 req->state &= ~XS_SERVED;
1693 if (req->op == X_READ)
1694 mkchunk(req_data, req->datalen, req_target, req->targetlen, req->offset);
1695 else if (req->op == X_WRITE)
1696 memcpy(buf, req_data, (sizeof(*buf) > req->datalen) ? req->datalen : sizeof(*buf));
1697 else if (req->op == X_INFO)
1698 *((uint64_t *) req->data) = 4294967296;
1700 req->state |= XS_SERVED;
1701 req->serviced = req->size;
1704 p = xseg_respond(xseg, req, srcport, X_ALLOC);
1705 xseg_signal(xseg, p);
1709 xseg_wait_signal(xseg, sd, 10000000L);
1717 void handle_reply(struct xseg_request *req)
1719 char *req_data = xseg_get_data(xseg, req);
1720 char *req_target = xseg_get_target(xseg, req);
1721 if (!(req->state & XS_SERVED)) {
1722 report_request(req);
1728 fwrite(req_data, 1, req->datalen, stdout);
1732 fprintf(stdout, "wrote: ");
1733 fwrite(req_data, 1, req->datalen, stdout);
1737 fprintf(stderr, "deleted %s\n", req_target);
1742 fprintf(stderr, "cloned %s\n", ((struct xseg_request_clone *)req_data)->target);
1745 fprintf(stderr, "size: %llu\n", (unsigned long long)*((uint64_t *)req_data));
1748 fprintf(stderr, "copied %s\n", ((struct xseg_request_copy *)req_data)->target);
1751 fprintf(stderr, "Closed %s\n", req_target);
1754 fprintf(stderr, "Opened %s\n", req_target);
1757 fprintf(stderr, "Snapshotted %s\n", req_target);
1764 if (xseg_put_request(xseg, req, srcport))
1765 fprintf(stderr, "Cannot put reply at port %u\n", req->src_portno);
1768 int cmd_wait(uint32_t nr)
1770 struct xseg_request *req;
1772 init_local_signal();
1775 req = xseg_receive(xseg, srcport, 0);
1784 ret = xseg_prepare_wait(xseg, srcport);
1788 ret = xseg_wait_signal(xseg, sd, 1000000);
1789 ret = xseg_cancel_wait(xseg, srcport);
1797 int cmd_put_replies(void)
1799 struct xseg_request *req;
1802 req = xseg_receive(xseg, dstport, 0);
1805 fprintf(stderr, "request: %08llx%08llx\n"
1808 0LL, (unsigned long long)req->serial,
1811 report_request(req);
1813 //fwrite(req->buffer, 1, req->bufferlen, stdout);
1815 if (xseg_put_request(xseg, req, srcport))
1816 fprintf(stderr, "Cannot put reply\n");
1822 int cmd_bind(long portno)
1824 struct xseg_port *port = xseg_bind_port(xseg, portno, NULL);
1826 fprintf(stderr, "failed to bind port %ld\n", portno);
1830 fprintf(stderr, "bound port %u\n", xseg_portno(xseg, port));
1834 int cmd_signal(uint32_t portno)
1836 return xseg_signal(xseg, portno);
1839 int cmd_set_next(xport portno, xport next)
1841 xseg->path_next[portno] = next;
1845 int parse_ports(char *str)
1856 if ((s > str) && isdigit(str[0])) {
1857 srcport = atol(str);
1870 if ((s > str) && isdigit(str[0])) {
1871 dstport = atol(str);
1882 int main(int argc, char **argv)
1894 if (xseg_parse_spec(spec, &cfg)) {
1895 fprintf(stderr, "Cannot parse spec\n");
1899 if (xseg_initialize()) {
1900 fprintf(stderr, "cannot initialize!\n");
1904 for (i = 2; i < argc; i++) {
1906 if (!strcmp(argv[i], "create")) {
1911 if (!strcmp(argv[i], "join")) {
1914 fprintf(stderr, "Segment joined.\n");
1918 if (!strcmp(argv[i], "destroy")) {
1919 ret = cmd_destroy();
1926 if (!strcmp(argv[i], "reportall")) {
1927 ret = cmd_reportall();
1931 if (!strcmp(argv[i], "bind") && (i + 1 < argc)) {
1932 ret = cmd_bind(atol(argv[i+1]));
1937 if (!strcmp(argv[i], "set-next") && (i + 2 < argc)) {
1938 ret = cmd_set_next(atol(argv[i+1]), atol(argv[i+2]));
1943 if (!strcmp(argv[i], "signal") && (i + 1 < argc)) {
1944 ret = cmd_signal(atol(argv[i+1]));
1949 if (!strcmp(argv[i], "bridge") && (i + 4 < argc)) {
1950 ret = cmd_bridge(atol(argv[i+1]),
1958 if (srcport == -1) {
1959 if (!parse_ports(argv[i]))
1960 fprintf(stderr, "source port undefined: %s\n", argv[i]);
1964 if (dstport == -1) {
1965 if (!parse_ports(argv[i]))
1966 fprintf(stderr, "destination port undefined: %s\n", argv[i]);
1970 if (!strcmp(argv[i], "verify")) {
1971 ret = cmd_verify(0);
1975 if (!strcmp(argv[i], "verify-fix")) {
1976 ret = cmd_verify(1);
1980 if (!strcmp(argv[i], "failreq") && (i + 1 < argc)) {
1981 struct xseg_request *req;
1982 sscanf(argv[i+1], "%lx", (unsigned long *)&req);
1983 ret = cmd_request(req, FAIL);
1988 if (!strcmp(argv[i], "inspect-freeq") && (i + 1 < argc)) {
1989 ret = cmd_inspectq(atol(argv[i+1]), FREE_QUEUE);
1994 if (!strcmp(argv[i], "inspect-requestq") && (i + 1 < argc)) {
1995 ret = cmd_inspectq(atol(argv[i+1]), REQUEST_QUEUE);
2000 if (!strcmp(argv[i], "inspect-replyq") && (i + 1 < argc)) {
2001 ret = cmd_inspectq(atol(argv[i+1]), REPLY_QUEUE);
2006 if (!strcmp(argv[i], "report")) {
2007 ret = cmd_report(dstport);
2011 if (!strcmp(argv[i], "alloc_requests") && (i + 1 < argc)) {
2012 ret = cmd_alloc_requests(atol(argv[i+1]));
2017 if (!strcmp(argv[i], "free_requests") && (i + 1 < argc)) {
2018 ret = cmd_free_requests(atol(argv[i+1]));
2023 if (!strcmp(argv[i], "put_requests")) {
2024 ret = cmd_put_requests();
2028 if (!strcmp(argv[i], "put_replies")) {
2029 ret = cmd_put_replies();
2033 if (!strcmp(argv[i], "complete") && (i + 1 < argc)) {
2034 ret = cmd_finish(atol(argv[i+1]), 0);
2039 if (!strcmp(argv[i], "fail") && (i + 1 < argc)) {
2040 ret = cmd_finish(atol(argv[i+1]), 1);
2045 if (!strcmp(argv[i], "wait") && (i + 1 < argc)) {
2046 ret = cmd_wait(atol(argv[i+1]));
2051 if (!strcmp(argv[i], "rndwrite") && (i + 5 < argc)) {
2052 long nr_loops = atol(argv[i+1]);
2053 unsigned int seed = atoi(argv[i+2]);
2054 unsigned int targetlen = atoi(argv[i+3]);
2055 unsigned int chunksize = atoi(argv[i+4]);
2056 unsigned long objectsize = atol(argv[i+5]);
2057 ret = cmd_rndwrite(nr_loops, seed, targetlen, chunksize, objectsize);
2062 if (!strcmp(argv[i], "rnddelete") && (i + 3 < argc)) {
2063 long nr_loops = atol(argv[i+1]);
2064 unsigned int seed = atoi(argv[i+2]);
2065 unsigned int targetlen = atoi(argv[i+3]);
2066 ret = cmd_rnddelete(nr_loops, seed, targetlen);
2071 if (!strcmp(argv[i], "rndread") && (i + 5 < argc)) {
2072 long nr_loops = atol(argv[i+1]);
2073 unsigned int seed = atoi(argv[i+2]);
2074 unsigned int targetlen = atoi(argv[i+3]);
2075 unsigned int chunksize = atoi(argv[i+4]);
2076 unsigned long objectsize = atol(argv[i+5]);
2077 ret = cmd_rndread(nr_loops, seed, targetlen, chunksize, objectsize);
2082 if (!strcmp(argv[i], "submit_reqs") && (i + 3 < argc)) {
2083 long nr_loops = atol(argv[i+1]);
2084 long concurrent_reqs = atol(argv[i+2]);
2085 int op = atoi(argv[i+3]);
2086 ret = cmd_submit_reqs(nr_loops, concurrent_reqs, op);
2091 if (!strcmp(argv[i], "read") && (i + 3 < argc)) {
2092 char *target = argv[i+1];
2093 uint64_t offset = atol(argv[i+2]);
2094 uint64_t size = atol(argv[i+3]);
2095 ret = cmd_read(target, offset, size);
2100 if (!strcmp(argv[i], "write") && (i + 2 < argc)) {
2101 char *target = argv[i+1];
2102 uint64_t offset = atol(argv[i+2]);
2103 ret = cmd_write(target, offset);
2108 if (!strcmp(argv[i], "truncate") && (i + 2 < argc)) {
2109 char *target = argv[i+1];
2110 uint64_t offset = atol(argv[i+2]);
2111 ret = cmd_truncate(target, offset);
2116 if (!strcmp(argv[i], "delete") && (i + 1 < argc)) {
2117 char *target = argv[i+1];
2118 ret = cmd_delete(target);
2123 if (!strcmp(argv[i], "acquire") && (i + 1 < argc)) {
2124 char *target = argv[i+1];
2125 ret = cmd_acquire(target);
2130 if (!strcmp(argv[i], "release") && (i + 1 < argc)) {
2131 char *target = argv[i+1];
2132 ret = cmd_release(target);
2137 if (!strcmp(argv[i], "copy") && (i + 2) < argc) {
2138 char *src = argv[i+1];
2139 char *dst = argv[i+2];
2140 ret = cmd_copy(src, dst);
2145 if (!strcmp(argv[i], "clone") && (i + 3 < argc)) {
2146 char *src = argv[i+1];
2147 char *dst = argv[i+2];
2148 long size = atol(argv[i+3]);
2149 ret = cmd_clone(src, dst, size);
2153 if (!strcmp(argv[i], "snapshot") && (i + 2 < argc)) {
2154 char *src = argv[i+1];
2155 char *dst = argv[i+2];
2156 ret = cmd_snapshot(src, dst, 4096*1024*1024UL);
2161 if (!strcmp(argv[i], "info") && (i + 1 < argc)) {
2162 char *target = argv[i+1];
2163 ret = cmd_info(target);
2169 if (!parse_ports(argv[i]))
2170 fprintf(stderr, "invalid argument: %s\n", argv[i]);