2 * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution
16 * at such time that OpenAFS documentation is written.
18 * 3. Neither the name of the Institute nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <afsconfig.h>
38 nn * We are using getopt since we want it to be possible to link to
43 #include <sys/types.h>
45 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
67 #include <err.h> /* not stricly right, but if we have a errx() there
68 * is hopefully a err.h */
72 #include "rx_globals.h"
75 #define u_int32_t u_int32
77 #define u_int32_t afs_uint32
80 static const char *__progname;
84 warnx(const char *fmt, ...)
89 fprintf(stderr, "%s: ", __progname);
90 vfprintf(stderr, fmt, args);
91 fprintf(stderr, "\n");
94 #endif /* !HAVE_WARNX */
98 errx(int eval, const char *fmt, ...)
103 fprintf(stderr, "%s: ", __progname);
104 vfprintf(stderr, fmt, args);
105 fprintf(stderr, "\n");
110 #endif /* !HAVE_ERRX */
114 warn(const char *fmt, ...)
120 fprintf(stderr, "%s: ", __progname);
121 vfprintf(stderr, fmt, args);
123 errstr = strerror(errno);
125 fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
128 #endif /* !HAVE_WARN */
132 err(int eval, const char *fmt, ...)
138 fprintf(stderr, "%s: ", __progname);
139 vfprintf(stderr, fmt, args);
141 errstr = strerror(errno);
143 fprintf(stderr, ": %s\n", errstr ? errstr : "unknown error");
148 #endif /* !HAVE_ERR */
150 #define DEFAULT_PORT 7009 /* To match tcpdump */
151 #define DEFAULT_HOST "127.0.0.1"
152 #define DEFAULT_BYTES 1000000
153 #define RXPERF_BUFSIZE 10000
155 enum { RX_PERF_VERSION = 3 };
156 enum { RX_SERVER_ID = 147 };
157 enum { RX_PERF_UNKNOWN = -1, RX_PERF_SEND = 0, RX_PERF_RECV = 1,
158 RX_PERF_RPC = 3, RX_PERF_FILE = 4
161 enum { RXPERF_MAGIC_COOKIE = 0x4711 };
168 #define DBFPRINT(x) do { printf x ; } while(0)
176 exit(2); /* XXX profiler */
183 exit(2); /* XXX profiler */
190 static struct timeval timer_start;
191 static struct timeval timer_stop;
192 static int timer_check = 0;
198 gettimeofday(&timer_start, NULL);
206 end_and_print_timer(char *str)
208 long long start_l, stop_l;
211 assert(timer_check == 0);
212 gettimeofday(&timer_stop, NULL);
213 start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
214 stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
215 printf("%s:\t%8llu msec\n", str, (stop_l - start_l) / 1000);
223 str2addr(const char *s)
225 struct in_addr server;
229 #define INADDR_NONE 0xffffffff
231 if (inet_addr(s) != INADDR_NONE)
233 h = gethostbyname(s);
235 memcpy(&server, h->h_addr_list[0], sizeof(server));
236 return server.s_addr;
247 get_sec(int serverp, struct rx_securityClass **sec, int *secureindex)
250 *sec = rxnull_NewServerSecurityObject();
253 *sec = rxnull_NewClientSecurityObject();
259 * process the "RPC" and return the results
262 char somebuf[RXPERF_BUFSIZE];
264 int32_t rxwrite_size = sizeof(somebuf);
265 int32_t rxread_size = sizeof(somebuf);
268 readbytes(struct rx_call *call, int32_t bytes)
276 if (rx_Read(call, somebuf, size) != size)
284 sendbytes(struct rx_call *call, int32_t bytes)
292 if (rx_Write(call, somebuf, size) != size)
301 rxperf_ExecuteRequest(struct rx_call *call)
310 u_int32_t *readwrite;
314 DBFPRINT(("got a request\n"));
316 if (rx_Read32(call, &version) != 4) {
317 warn("rx_Read failed to read version");
321 if (htonl(RX_PERF_VERSION) != version) {
322 warnx("client has wrong version");
326 if (rx_Read32(call, &command) != 4) {
327 warnx("rx_Read failed to read command");
330 command = ntohl(command);
332 if (rx_Read32(call, &data) != 4) {
333 warnx("rx_Read failed to read size");
336 rxread_size = ntohl(data);
337 if (rxread_size > sizeof(somebuf)) {
338 warnx("rxread_size too large %d", rxread_size);
342 if (rx_Read32(call, &data) != 4) {
343 warnx("rx_Read failed to write size");
346 rxwrite_size = ntohl(data);
347 if (rxwrite_size > sizeof(somebuf)) {
348 warnx("rxwrite_size too large %d", rxwrite_size);
354 DBFPRINT(("got a send request\n"));
356 if (rx_Read32(call, &bytes) != 4) {
357 warnx("rx_Read failed to read bytes");
360 bytes = ntohl(bytes);
362 DBFPRINT(("reading(%d) ", bytes));
363 readbytes(call, bytes);
365 data = htonl(RXPERF_MAGIC_COOKIE);
366 if (rx_Write32(call, &data) != 4) {
367 warnx("rx_Write failed when sending back result");
370 DBFPRINT(("done\n"));
374 DBFPRINT(("got a rpc request, reading commands\n"));
376 if (rx_Read32(call, &recvb) != 4) {
377 warnx("rx_Read failed to read recvbytes");
380 recvb = ntohl(recvb);
381 if (rx_Read32(call, &sendb) != 4) {
382 warnx("rx_Read failed to read sendbytes");
385 sendb = ntohl(sendb);
387 DBFPRINT(("read(%d) ", recvb));
388 if (readbytes(call, recvb)) {
389 warnx("readbytes failed");
392 DBFPRINT(("send(%d) ", sendb));
393 if (sendbytes(call, sendb)) {
394 warnx("sendbytes failed");
398 DBFPRINT(("done\n"));
400 data = htonl(RXPERF_MAGIC_COOKIE);
401 if (rx_Write32(call, &data) != 4) {
402 warnx("rx_Write failed when sending back magic cookie");
408 if (rx_Read32(call, &data) != 4)
409 errx(1, "failed to read num from client");
412 readwrite = malloc(num * sizeof(u_int32_t));
413 if (readwrite == NULL)
416 if (rx_Read(call, readwrite, num * sizeof(u_int32_t)) !=
417 num * sizeof(u_int32_t))
418 errx(1, "failed to read recvlist from client");
420 for (i = 0; i < num; i++) {
421 if (readwrite[i] == 0) {
422 DBFPRINT(("readp %d", readwrite[i]));
426 bytes = ntohl(readwrite[i]) * sizeof(u_int32_t);
429 DBFPRINT(("read\n"));
430 readbytes(call, bytes);
432 sendbytes(call, bytes);
433 DBFPRINT(("send\n"));
439 DBFPRINT(("got a recv request\n"));
441 if (rx_Read32(call, &bytes) != 4) {
442 warnx("rx_Read failed to read bytes");
445 bytes = ntohl(bytes);
447 DBFPRINT(("sending(%d) ", bytes));
448 sendbytes(call, bytes);
450 data = htonl(RXPERF_MAGIC_COOKIE);
451 if (rx_Write32(call, &data) != 4) {
452 warnx("rx_Write failed when sending back result");
455 DBFPRINT(("done\n"));
459 warnx("client sent a unsupported command");
462 DBFPRINT(("done with command\n"));
472 do_server(int port, int nojumbo, int maxmtu)
474 struct rx_service *service;
475 struct rx_securityClass *secureobj;
481 errx(1, "rx_Init failed");
486 rx_SetMaxMTU(maxmtu);
487 get_sec(1, &secureobj, &secureindex);
490 rx_NewService(0, RX_SERVER_ID, "rxperf", &secureobj, secureindex,
491 rxperf_ExecuteRequest);
493 errx(1, "Cant create server");
504 readfile(const char *filename, u_int32_t ** readwrite, u_int32_t * size)
511 char buf[RXPERF_BUFSIZE];
513 *readwrite = malloc(sizeof(u_int32_t) * len);
515 if (*readwrite == NULL)
518 f = fopen(filename, "r");
522 while (fgets(buf, sizeof(buf), f) != NULL) {
525 *readwrite = realloc(*readwrite, len * sizeof(u_int32_t));
526 if (*readwrite == NULL)
531 data = htonl(strtol(buf, &ptr, 0));
532 if (ptr && ptr == buf)
533 errx(1, "can't resolve number of bytes to transfer");
538 (*readwrite)[num] = data;
555 do_client(const char *server, int port, char *filename, int32_t command,
556 int32_t times, int32_t bytes, int32_t sendtimes, int32_t recvtimes,
557 int dumpstats, int nojumbo, int maxmtu)
559 struct rx_connection *conn;
560 struct rx_call *call;
561 u_int32_t addr = str2addr(server);
562 struct rx_securityClass *secureobj;
572 u_int32_t *readwrite;
576 errx(1, "rx_Init failed");
581 rx_SetMaxMTU(maxmtu);
582 get_sec(0, &secureobj, &secureindex);
584 conn = rx_NewConnection(addr, port, RX_SERVER_ID, secureobj, secureindex);
586 errx(1, "failed to contact server");
588 sprintf(stamp, "send\t%d times\t%d writes\t%d reads", times, sendtimes,
592 for (i = 0; i < times; i++) {
594 DBFPRINT(("starting command "));
596 call = rx_NewCall(conn);
598 errx(1, "rx_NewCall failed");
600 data = htonl(RX_PERF_VERSION);
601 if (rx_Write32(call, &data) != 4)
602 errx(1, "rx_Write failed to send version (err %d)", rx_Error(call));
604 data = htonl(command);
605 if (rx_Write32(call, &data) != 4)
606 errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
608 data = htonl(rxread_size);
609 if (rx_Write32(call, &data) != 4)
610 errx(1, "rx_Write failed to send read size (err %d)", rx_Error(call));
611 data = htonl(rxwrite_size);
612 if (rx_Write32(call, &data) != 4)
613 errx(1, "rx_Write failed to send write read (err %d)", rx_Error(call));
618 DBFPRINT(("command "));
621 if (rx_Write32(call, &data) != 4)
622 errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
624 DBFPRINT(("sending(%d) ", bytes));
625 if (readbytes(call, bytes))
626 errx(1, "sendbytes (err %d)", rx_Error(call));
628 if (rx_Read32(call, &data) != 4)
629 errx(1, "failed to read result from server (err %d)", rx_Error(call));
631 if (data != htonl(RXPERF_MAGIC_COOKIE))
632 warn("server send wrong magic cookie in responce");
634 DBFPRINT(("done\n"));
638 DBFPRINT(("command "));
641 if (rx_Write32(call, &data) != 4)
642 errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
644 DBFPRINT(("sending(%d) ", bytes));
645 if (sendbytes(call, bytes))
646 errx(1, "sendbytes (err %d)", rx_Error(call));
648 if (rx_Read32(call, &data) != 4)
649 errx(1, "failed to read result from server (err %d)", rx_Error(call));
651 if (data != htonl(RXPERF_MAGIC_COOKIE))
652 warn("server send wrong magic cookie in responce");
654 DBFPRINT(("done\n"));
658 DBFPRINT(("commands "));
660 data = htonl(sendtimes);
661 if (rx_Write32(call, &data) != 4)
662 errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
664 data = htonl(recvtimes);
665 if (rx_Write32(call, &data) != 4)
666 errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
668 DBFPRINT(("send(%d) ", sendtimes));
669 if (sendbytes(call, sendtimes))
670 errx(1, "sendbytes (err %d)", rx_Error(call));
672 DBFPRINT(("recv(%d) ", recvtimes));
673 if (readbytes(call, recvtimes))
674 errx(1, "sendbytes (err %d)", rx_Error(call));
676 if (rx_Read32(call, &bytes) != 4)
677 errx(1, "failed to read result from server (err %d)", rx_Error(call));
679 if (bytes != htonl(RXPERF_MAGIC_COOKIE))
680 warn("server send wrong magic cookie in responce");
682 DBFPRINT(("done\n"));
686 readfile(filename, &readwrite, &num);
689 if (rx_Write32(call, &data) != 4)
690 errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
692 if (rx_Write(call, readwrite, num * sizeof(u_int32_t))
693 != num * sizeof(u_int32_t))
694 errx(1, "rx_Write failed to send list (err %d)", rx_Error(call));
696 for (i = 0; i < num; i++) {
697 if (readwrite[i] == 0)
700 size = ntohl(readwrite[i]) * sizeof(u_int32_t);
703 if (readbytes(call, size))
704 errx(1, "sendbytes (err %d)", rx_Error(call));
705 DBFPRINT(("read\n"));
707 if (sendbytes(call, size))
708 errx(1, "sendbytes (err %d)", rx_Error(call));
709 DBFPRINT(("send\n"));
720 end_and_print_timer(stamp);
721 DBFPRINT(("done for good\n"));
724 rx_PrintStats(stdout);
725 rx_PrintPeerStats(stdout, conn->peer);
735 fprintf(stderr, "usage: %s client -c send -b <bytes>\n", __progname);
736 fprintf(stderr, "usage: %s client -c recv -b <bytes>\n", __progname);
738 "usage: %s client -c rpc -S <sendbytes> -R <recvbytes>\n",
740 fprintf(stderr, "usage: %s client -c file -f filename\n", __progname);
742 "%s: usage: common option to the client "
743 "-w <write-bytes> -r <read-bytes> -T times -p port -s server -D\n",
745 fprintf(stderr, "usage: %s server -p port\n", __progname);
751 * do argument processing and call networking functions
755 rxperf_server(int argc, char **argv)
757 int port = DEFAULT_PORT;
763 while ((ch = getopt(argc, argv, "r:d:p:w:jm:4")) != -1) {
767 rx_debugFile = fopen(optarg, "w");
768 if (rx_debugFile == NULL)
769 err(1, "fopen %s", optarg);
771 errx(1, "compiled without RXDEBUG");
775 rxread_size = strtol(optarg, &ptr, 0);
776 if (ptr != 0 && ptr[0] != '\0')
777 errx(1, "can't resolve readsize");
778 if (rxread_size > sizeof(somebuf))
779 errx(1, "%d > sizeof(somebuf) (%d)", rxread_size,
783 port = strtol(optarg, &ptr, 0);
784 if (ptr != 0 && ptr[0] != '\0')
785 errx(1, "can't resolve portname");
788 rxwrite_size = strtol(optarg, &ptr, 0);
789 if (ptr != 0 && ptr[0] != '\0')
790 errx(1, "can't resolve writesize");
791 if (rxwrite_size > sizeof(somebuf))
792 errx(1, "%d > sizeof(somebuf) (%d)", rxwrite_size,
799 maxmtu = strtol(optarg, &ptr, 0);
800 if (ptr && *ptr != '\0')
801 errx(1, "can't resolve rx maxmtu to use");
814 do_server(htons(port), nojumbo, maxmtu);
820 * do argument processing and call networking functions
824 rxperf_client(int argc, char **argv)
826 char *host = DEFAULT_HOST;
827 int bytes = DEFAULT_BYTES;
828 int port = DEFAULT_PORT;
829 char *filename = NULL;
840 cmd = RX_PERF_UNKNOWN;
842 while ((ch = getopt(argc, argv, "T:S:R:b:c:d:p:r:s:w:f:Djm:4")) != -1) {
845 bytes = strtol(optarg, &ptr, 0);
846 if (ptr && *ptr != '\0')
847 errx(1, "can't resolve number of bytes to transfer");
850 if (strcasecmp(optarg, "send") == 0)
852 else if (strcasecmp(optarg, "recv") == 0)
854 else if (strcasecmp(optarg, "rpc") == 0)
856 else if (strcasecmp(optarg, "file") == 0)
859 errx(1, "unknown command %s", optarg);
863 rx_debugFile = fopen(optarg, "w");
864 if (rx_debugFile == NULL)
865 err(1, "fopen %s", optarg);
867 errx(1, "compiled without RXDEBUG");
871 port = strtol(optarg, &ptr, 0);
872 if (ptr != 0 && ptr[0] != '\0')
873 errx(1, "can't resolve portname");
876 rxread_size = strtol(optarg, &ptr, 0);
877 if (ptr != 0 && ptr[0] != '\0')
878 errx(1, "can't resolve readsize");
879 if (rxread_size > sizeof(somebuf))
880 errx(1, "%d > sizeof(somebuf) (%d)", rxread_size,
884 host = strdup(optarg);
889 rxwrite_size = strtol(optarg, &ptr, 0);
890 if (ptr != 0 && ptr[0] != '\0')
891 errx(1, "can't resolve writesize");
892 if (rxwrite_size > sizeof(somebuf))
893 errx(1, "%d > sizeof(somebuf) (%d)", rxwrite_size,
897 times = strtol(optarg, &ptr, 0);
898 if (ptr && *ptr != '\0')
899 errx(1, "can't resolve number of bytes to transfer");
902 sendtimes = strtol(optarg, &ptr, 0);
903 if (ptr && *ptr != '\0')
904 errx(1, "can't resolve number of bytes to transfer");
907 recvtimes = strtol(optarg, &ptr, 0);
908 if (ptr && *ptr != '\0')
909 errx(1, "can't resolve number of bytes to transfer");
918 errx(1, "compiled without RXDEBUG");
925 maxmtu = strtol(optarg, &ptr, 0);
926 if (ptr && *ptr != '\0')
927 errx(1, "can't resolve rx maxmtu to use");
940 if (cmd == RX_PERF_UNKNOWN)
941 errx(1, "no command given to the client");
943 do_client(host, htons(port), filename, cmd, times, bytes, sendtimes,
944 recvtimes, dumpstats, nojumbo, maxmtu);
950 * setup world and call cmd
954 main(int argc, char **argv)
958 __progname = strrchr(argv[0], '/');
960 __progname = argv[0];
962 signal(SIGUSR1, sigusr1);
963 signal(SIGINT, sigint);
965 LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid);
967 memset(somebuf, 0, sizeof(somebuf));
969 if (argc >= 2 && strcmp(argv[1], "server") == 0)
970 rxperf_server(argc - 1, argv + 1);
971 else if (argc >= 2 && strcmp(argv[1], "client") == 0)
972 rxperf_client(argc - 1, argv + 1);