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
42 #include <afsconfig.h>
43 #include <afs/param.h>
46 #ifdef HAVE_SYS_FILE_H
53 #include <rx/rx_null.h>
54 #include <rx/rx_globals.h>
55 #include <rx/rx_packet.h>
57 #ifdef AFS_PTHREAD_ENV
59 #define MAX_THREADS 128
62 #define DEFAULT_PORT 7009 /* To match tcpdump */
63 #define DEFAULT_HOST "127.0.0.1"
64 #define DEFAULT_BYTES 1024 * 1024
65 #define RXPERF_BUFSIZE 512 * 1024
67 enum { RX_PERF_VERSION = 3 };
68 enum { RX_SERVER_ID = 147 };
69 enum { RX_PERF_UNKNOWN = -1,
76 enum { RXPERF_MAGIC_COOKIE = 0x4711 };
83 #define DBFPRINT(x) do { printf x ; } while(0)
91 exit(2); /* XXX profiler */
98 exit(2); /* XXX profiler */
105 static struct timeval timer_start;
106 static struct timeval timer_stop;
107 static int timer_check = 0;
113 gettimeofday(&timer_start, NULL);
121 end_and_print_timer(char *str)
123 long long start_l, stop_l;
126 assert(timer_check == 0);
127 gettimeofday(&timer_stop, NULL);
128 start_l = timer_start.tv_sec * 1000000 + timer_start.tv_usec;
129 stop_l = timer_stop.tv_sec * 1000000 + timer_stop.tv_usec;
130 printf("%s:\t%8llu msec\n", str, (stop_l - start_l) / 1000);
138 str2addr(const char *s)
140 struct in_addr server;
144 #define INADDR_NONE 0xffffffff
146 if (inet_addr(s) != INADDR_NONE)
148 h = gethostbyname(s);
150 memcpy(&server, h->h_addr_list[0], sizeof(server));
151 return server.s_addr;
162 get_sec(int serverp, struct rx_securityClass **sec, int *secureindex)
165 *sec = rxnull_NewServerSecurityObject();
168 *sec = rxnull_NewClientSecurityObject();
174 * process the "RPC" and return the results
177 char somebuf[RXPERF_BUFSIZE];
179 afs_int32 rxwrite_size = sizeof(somebuf);
180 afs_int32 rxread_size = sizeof(somebuf);
181 afs_int32 use_rx_readv = 0;
184 do_readbytes(struct rx_call *call, afs_int32 bytes)
186 struct iovec tiov[RX_MAXIOVECS];
197 if (size > RX_MAX_PACKET_DATA_SIZE)
198 size = RX_MAX_PACKET_DATA_SIZE;
199 code = rx_Readv(call, tiov, &tnio, RX_MAXIOVECS, size);
201 code = rx_Read(call, somebuf, size);
211 do_sendbytes(struct rx_call *call, afs_int32 bytes)
219 if (rx_Write(call, somebuf, size) != size)
228 rxperf_ExecuteRequest(struct rx_call *call)
237 afs_uint32 *readwrite;
241 DBFPRINT(("got a request\n"));
243 if (rx_Read32(call, &version) != 4) {
244 warn("rx_Read failed to read version");
248 if (htonl(RX_PERF_VERSION) != version) {
249 warnx("client has wrong version");
253 if (rx_Read32(call, &command) != 4) {
254 warnx("rx_Read failed to read command");
257 command = ntohl(command);
259 if (rx_Read32(call, &data) != 4) {
260 warnx("rx_Read failed to read size");
263 rxread_size = ntohl(data);
264 if (rxread_size > sizeof(somebuf)) {
265 warnx("rxread_size too large %d", rxread_size);
269 if (rx_Read32(call, &data) != 4) {
270 warnx("rx_Read failed to write size");
273 rxwrite_size = ntohl(data);
274 if (rxwrite_size > sizeof(somebuf)) {
275 warnx("rxwrite_size too large %d", rxwrite_size);
281 DBFPRINT(("got a send request\n"));
283 if (rx_Read32(call, &bytes) != 4) {
284 warnx("rx_Read failed to read bytes");
287 bytes = ntohl(bytes);
289 DBFPRINT(("reading(%d) ", bytes));
290 do_readbytes(call, bytes);
292 data = htonl(RXPERF_MAGIC_COOKIE);
293 if (rx_Write32(call, &data) != 4) {
294 warnx("rx_Write failed when sending back result");
297 DBFPRINT(("done\n"));
301 DBFPRINT(("got a rpc request, reading commands\n"));
303 if (rx_Read32(call, &recvb) != 4) {
304 warnx("rx_Read failed to read recvbytes");
307 recvb = ntohl(recvb);
308 if (rx_Read32(call, &sendb) != 4) {
309 warnx("rx_Read failed to read sendbytes");
312 sendb = ntohl(sendb);
314 DBFPRINT(("read(%d) ", recvb));
315 if (do_readbytes(call, recvb)) {
316 warnx("do_readbytes failed");
319 DBFPRINT(("send(%d) ", sendb));
320 if (do_sendbytes(call, sendb)) {
321 warnx("sendbytes failed");
325 DBFPRINT(("done\n"));
327 data = htonl(RXPERF_MAGIC_COOKIE);
328 if (rx_Write32(call, &data) != 4) {
329 warnx("rx_Write failed when sending back magic cookie");
335 if (rx_Read32(call, &data) != 4)
336 errx(1, "failed to read num from client");
339 readwrite = malloc(num * sizeof(afs_uint32));
340 if (readwrite == NULL)
343 if (rx_Read(call, (char*)readwrite, num * sizeof(afs_uint32)) !=
344 num * sizeof(afs_uint32))
345 errx(1, "failed to read recvlist from client");
347 for (i = 0; i < num; i++) {
348 if (readwrite[i] == 0) {
349 DBFPRINT(("readp %d", readwrite[i]));
353 bytes = ntohl(readwrite[i]) * sizeof(afs_uint32);
356 DBFPRINT(("read\n"));
357 do_readbytes(call, bytes);
359 do_sendbytes(call, bytes);
360 DBFPRINT(("send\n"));
366 DBFPRINT(("got a recv request\n"));
368 if (rx_Read32(call, &bytes) != 4) {
369 warnx("rx_Read failed to read bytes");
372 bytes = ntohl(bytes);
374 DBFPRINT(("sending(%d) ", bytes));
375 do_sendbytes(call, bytes);
377 data = htonl(RXPERF_MAGIC_COOKIE);
378 if (rx_Write32(call, &data) != 4) {
379 warnx("rx_Write failed when sending back result");
382 DBFPRINT(("done\n"));
386 warnx("client sent a unsupported command");
389 DBFPRINT(("done with command\n"));
399 do_server(short port, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
400 int udpbufsz, int nostats, int hotthread,
401 int minprocs, int maxprocs)
403 struct rx_service *service;
404 struct rx_securityClass *secureobj;
409 if (afs_winsockInit() < 0) {
410 printf("Can't initialize winsock.\n");
416 rx_EnableHotThread();
421 rx_SetUdpBufSize(udpbufsz);
423 ret = rx_Init(htons(port));
425 errx(1, "rx_Init failed");
431 rx_SetMaxMTU(maxmtu);
434 rx_SetMaxReceiveWindow(maxwsize);
435 rx_SetMaxSendWindow(maxwsize);
439 rx_SetMinPeerTimeout(minpeertimeout);
442 get_sec(1, &secureobj, &secureindex);
445 rx_NewService(0, RX_SERVER_ID, "rxperf", &secureobj, secureindex,
446 rxperf_ExecuteRequest);
448 errx(1, "Cant create server");
450 rx_SetMinProcs(service, minprocs);
451 rx_SetMaxProcs(service, maxprocs);
453 rx_SetCheckReach(service, 1);
465 readfile(const char *filename, afs_uint32 ** readwrite, afs_uint32 * size)
474 *readwrite = malloc(sizeof(afs_uint32) * len);
475 buf = malloc(RXPERF_BUFSIZE);
477 if (*readwrite == NULL)
480 f = fopen(filename, "r");
484 while (fgets(buf, sizeof(buf), f) != NULL) {
487 *readwrite = realloc(*readwrite, len * sizeof(afs_uint32));
488 if (*readwrite == NULL)
493 data = htonl(strtol(buf, &ptr, 0));
494 if (ptr && ptr == buf)
495 errx(1, "can't resolve number of bytes to transfer");
500 (*readwrite)[num] = data;
513 struct rx_connection *conn;
523 client_thread( void *vparams)
525 struct client_data *params = (struct client_data *)vparams;
526 struct rx_call *call;
529 afs_uint32 *readwrite;
534 for (i = 0; i < params->times; i++) {
536 DBFPRINT(("starting command "));
538 call = rx_NewCall(params->conn);
540 errx(1, "rx_NewCall failed");
542 data = htonl(RX_PERF_VERSION);
543 if (rx_Write32(call, &data) != 4)
544 errx(1, "rx_Write failed to send version (err %d)", rx_Error(call));
546 data = htonl(params->command);
547 if (rx_Write32(call, &data) != 4)
548 errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
550 data = htonl(rxread_size);
551 if (rx_Write32(call, &data) != 4)
552 errx(1, "rx_Write failed to send read size (err %d)", rx_Error(call));
553 data = htonl(rxwrite_size);
554 if (rx_Write32(call, &data) != 4)
555 errx(1, "rx_Write failed to send write read (err %d)", rx_Error(call));
558 switch (params->command) {
560 DBFPRINT(("command "));
562 data = htonl(params->bytes);
563 if (rx_Write32(call, &data) != 4)
564 errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
566 DBFPRINT(("sending(%d) ", params->bytes));
567 if (do_readbytes(call, params->bytes))
568 errx(1, "sendbytes (err %d)", rx_Error(call));
570 if (rx_Read32(call, &data) != 4)
571 errx(1, "failed to read result from server (err %d)", rx_Error(call));
573 if (data != htonl(RXPERF_MAGIC_COOKIE))
574 warn("server send wrong magic cookie in responce");
576 DBFPRINT(("done\n"));
580 DBFPRINT(("command "));
582 data = htonl(params->bytes);
583 if (rx_Write32(call, &data) != 4)
584 errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
586 DBFPRINT(("sending(%d) ", params->bytes));
587 if (do_sendbytes(call, params->bytes))
588 errx(1, "sendbytes (err %d)", rx_Error(call));
590 if (rx_Read32(call, &data) != 4)
591 errx(1, "failed to read result from server (err %d)", rx_Error(call));
593 if (data != htonl(RXPERF_MAGIC_COOKIE))
594 warn("server send wrong magic cookie in responce");
596 DBFPRINT(("done\n"));
600 DBFPRINT(("commands "));
602 data = htonl(params->sendbytes);
603 if (rx_Write32(call, &data) != 4)
604 errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
606 data = htonl(params->readbytes);
607 if (rx_Write32(call, &data) != 4)
608 errx(1, "rx_Write failed to send command (err %d)", rx_Error(call));
610 DBFPRINT(("send(%d) ", params->sendbytes));
611 if (do_sendbytes(call, params->sendbytes))
612 errx(1, "sendbytes (err %d)", rx_Error(call));
614 DBFPRINT(("recv(%d) ", params->readbytes));
615 if (do_readbytes(call, params->readbytes))
616 errx(1, "sendbytes (err %d)", rx_Error(call));
618 if (rx_Read32(call, &data) != 4)
619 errx(1, "failed to read result from server (err %d)", rx_Error(call));
621 if (data != htonl(RXPERF_MAGIC_COOKIE))
622 warn("server send wrong magic cookie in responce");
624 DBFPRINT(("done\n"));
629 readfile(params->filename, &readwrite, &num);
632 if (rx_Write32(call, &data) != 4)
633 errx(1, "rx_Write failed to send size (err %d)", rx_Error(call));
635 if (rx_Write(call, (char *)readwrite, num * sizeof(afs_uint32))
636 != num * sizeof(afs_uint32))
637 errx(1, "rx_Write failed to send list (err %d)", rx_Error(call));
639 for (j = 0; j < num; j++) {
640 if (readwrite[j] == 0)
643 size = ntohl(readwrite[j]) * sizeof(afs_uint32);
646 if (do_readbytes(call, size))
647 errx(1, "sendbytes (err %d)", rx_Error(call));
648 DBFPRINT(("read\n"));
650 if (do_sendbytes(call, size))
651 errx(1, "sendbytes (err %d)", rx_Error(call));
652 DBFPRINT(("send\n"));
663 #ifdef AFS_PTHREAD_ENV
675 do_client(const char *server, short port, char *filename, afs_int32 command,
676 afs_int32 times, afs_int32 bytes, afs_int32 sendbytes, afs_int32 readbytes,
677 int dumpstats, int nojumbo, int maxmtu, int maxwsize, int minpeertimeout,
678 int udpbufsz, int nostats, int hotthread, int threads)
680 struct rx_connection *conn;
682 struct rx_securityClass *secureobj;
686 struct client_data *params;
688 #ifdef AFS_PTHREAD_ENV
690 pthread_t thread[MAX_THREADS];
691 pthread_attr_t tattr;
695 params = calloc(1, sizeof(struct client_data));
698 if (afs_winsockInit() < 0) {
699 printf("Can't initialize winsock.\n");
705 rx_EnableHotThread();
710 addr = str2addr(server);
712 rx_SetUdpBufSize(udpbufsz);
716 errx(1, "rx_Init failed");
722 rx_SetMaxMTU(maxmtu);
725 rx_SetMaxReceiveWindow(maxwsize);
726 rx_SetMaxSendWindow(maxwsize);
730 rx_SetMinPeerTimeout(minpeertimeout);
733 get_sec(0, &secureobj, &secureindex);
737 sprintf(stamp, "RPC: threads\t%d, times\t%d, write bytes\t%d, read bytes\t%d",
738 threads, times, sendbytes, readbytes);
741 sprintf(stamp, "RECV: threads\t%d, times\t%d, bytes\t%d",
742 threads, times, bytes);
745 sprintf(stamp, "SEND: threads\t%d, times\t%d, bytes\t%d",
746 threads, times, bytes);
749 sprintf(stamp, "FILE %s: threads\t%d, times\t%d, bytes\t%d",
750 filename, threads, times, bytes);
754 conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
756 errx(1, "failed to contact server");
758 #ifdef AFS_PTHREAD_ENV
759 pthread_attr_init(&tattr);
760 pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
764 params->filename = filename;
765 params->command = command;
766 params->times = times;
767 params->bytes = bytes;
768 params->sendbytes = sendbytes;
769 params->readbytes = readbytes;
773 #ifdef AFS_PTHREAD_ENV
774 for ( i=0; i<threads; i++) {
775 pthread_create(&thread[i], &tattr, client_thread, params);
776 if ( (i + 1) % RX_MAXCALLS == 0 ) {
777 conn = rx_NewConnection(addr, htons(port), RX_SERVER_ID, secureobj, secureindex);
779 struct client_data *new_params = malloc(sizeof(struct client_data));
780 memcpy(new_params, params, sizeof(struct client_data));
781 new_params->conn = conn;
787 client_thread(params);
790 #ifdef AFS_PTHREAD_ENV
791 for ( i=0; i<threads; i++)
792 pthread_join(thread[i], &status);
795 end_and_print_timer(stamp);
796 DBFPRINT(("done for good\n"));
799 rx_PrintStats(stdout);
800 rx_PrintPeerStats(stdout, rx_PeerOf(conn));
804 #ifdef AFS_PTHREAD_ENV
805 pthread_attr_destroy(&tattr);
816 fprintf(stderr, "usage: %s client -c send -b <bytes>\n", getprogname());
817 fprintf(stderr, "usage: %s client -c recv -b <bytes>\n", getprogname());
819 "usage: %s client -c rpc -S <sendbytes> -R <recvbytes>\n",
821 fprintf(stderr, "usage: %s client -c file -f filename\n", getprogname());
823 "%s: usage: common option to the client "
824 "-w <write-bytes> -r <read-bytes> -T times -p port -s server -D\n",
826 fprintf(stderr, "usage: %s server -p port\n", getprogname());
834 * do argument processing and call networking functions
838 rxperf_server(int argc, char **argv)
840 short port = DEFAULT_PORT;
844 int udpbufsz = 64 * 1024;
849 int minpeertimeout = 0;
853 while ((ch = getopt(argc, argv, "r:d:p:P:w:W:HNjm:u:4:s:S:V")) != -1) {
857 rx_debugFile = fopen(optarg, "w");
858 if (rx_debugFile == NULL)
859 err(1, "fopen %s", optarg);
861 errx(1, "compiled without RXDEBUG");
865 rxread_size = strtol(optarg, &ptr, 0);
866 if (ptr != 0 && ptr[0] != '\0')
867 errx(1, "can't resolve readsize");
868 if (rxread_size > sizeof(somebuf))
869 errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxread_size,
873 minprocs = strtol(optarg, &ptr, 0);
874 if (ptr != 0 && ptr[0] != '\0')
875 errx(1, "can't resolve minprocs");
878 maxprocs = strtol(optarg, &ptr, 0);
879 if (ptr != 0 && ptr[0] != '\0')
880 errx(1, "can't resolve maxprocs");
883 minpeertimeout = strtol(optarg, &ptr, 0);
884 if (ptr != 0 && ptr[0] != '\0')
885 errx(1, "can't resolve min peer timeout");
888 port = (short) strtol(optarg, &ptr, 0);
889 if (ptr != 0 && ptr[0] != '\0')
890 errx(1, "can't resolve portname");
893 rxwrite_size = strtol(optarg, &ptr, 0);
894 if (ptr != 0 && ptr[0] != '\0')
895 errx(1, "can't resolve writesize");
896 if (rxwrite_size > sizeof(somebuf))
897 errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxwrite_size,
910 maxmtu = strtol(optarg, &ptr, 0);
911 if (ptr && *ptr != '\0')
912 errx(1, "can't resolve rx maxmtu to use");
915 udpbufsz = strtol(optarg, &ptr, 0) * 1024;
916 if (ptr && *ptr != '\0')
917 errx(1, "can't resolve upd buffer size (Kbytes)");
923 maxwsize = strtol(optarg, &ptr, 0);
924 if (ptr && *ptr != '\0')
925 errx(1, "can't resolve max send/recv window size (packets)");
938 do_server(port, nojumbo, maxmtu, maxwsize, minpeertimeout, udpbufsz,
939 nostats, hotthreads, minprocs, maxprocs);
945 * do argument processing and call networking functions
949 rxperf_client(int argc, char **argv)
951 char *host = DEFAULT_HOST;
952 int bytes = DEFAULT_BYTES;
953 short port = DEFAULT_PORT;
954 char *filename = NULL;
965 int udpbufsz = 64 * 1024;
967 int minpeertimeout = 0;
971 cmd = RX_PERF_UNKNOWN;
973 while ((ch = getopt(argc, argv, "T:S:R:b:c:d:p:P:r:s:w:W:f:HDNjm:u:4:t:V")) != -1) {
976 bytes = strtol(optarg, &ptr, 0);
977 if (ptr && *ptr != '\0')
978 errx(1, "can't resolve number of bytes to transfer");
981 if (strcasecmp(optarg, "send") == 0)
983 else if (strcasecmp(optarg, "recv") == 0)
985 else if (strcasecmp(optarg, "rpc") == 0)
987 else if (strcasecmp(optarg, "file") == 0)
990 errx(1, "unknown command %s", optarg);
994 rx_debugFile = fopen(optarg, "w");
995 if (rx_debugFile == NULL)
996 err(1, "fopen %s", optarg);
998 errx(1, "compiled without RXDEBUG");
1002 minpeertimeout = strtol(optarg, &ptr, 0);
1003 if (ptr != 0 && ptr[0] != '\0')
1004 errx(1, "can't resolve min peer timeout");
1007 port = (short) strtol(optarg, &ptr, 0);
1008 if (ptr != 0 && ptr[0] != '\0')
1009 errx(1, "can't resolve portname");
1012 rxread_size = strtol(optarg, &ptr, 0);
1013 if (ptr != 0 && ptr[0] != '\0')
1014 errx(1, "can't resolve readsize");
1015 if (rxread_size > sizeof(somebuf))
1016 errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxread_size,
1020 host = strdup(optarg);
1028 rxwrite_size = strtol(optarg, &ptr, 0);
1029 if (ptr != 0 && ptr[0] != '\0')
1030 errx(1, "can't resolve writesize");
1031 if (rxwrite_size > sizeof(somebuf))
1032 errx(1, "%d > sizeof(somebuf) (%"AFS_SIZET_FMT")", rxwrite_size,
1036 maxwsize = strtol(optarg, &ptr, 0);
1037 if (ptr && *ptr != '\0')
1038 errx(1, "can't resolve max send/recv window size (packets)");
1041 times = strtol(optarg, &ptr, 0);
1042 if (ptr && *ptr != '\0')
1043 errx(1, "can't resolve number of times to execute rpc");
1046 sendbytes = strtol(optarg, &ptr, 0);
1047 if (ptr && *ptr != '\0')
1048 errx(1, "can't resolve number of bytes to send");
1051 readbytes = strtol(optarg, &ptr, 0);
1052 if (ptr && *ptr != '\0')
1053 errx(1, "can't resolve number of bytes to receive");
1056 #ifdef AFS_PTHREAD_ENV
1057 threads = strtol(optarg, &ptr, 0);
1058 if (ptr && *ptr != '\0')
1059 errx(1, "can't resolve number of threads to execute");
1060 if (threads > MAX_THREADS)
1061 errx(1, "too many threads");
1063 errx(1, "Not built for pthreads");
1082 maxmtu = strtol(optarg, &ptr, 0);
1083 if (ptr && *ptr != '\0')
1084 errx(1, "can't resolve rx maxmtu to use");
1087 udpbufsz = strtol(optarg, &ptr, 0) * 1024;
1088 if (ptr && *ptr != '\0')
1089 errx(1, "can't resolve upd buffer size (Kbytes)");
1099 if (nostats && dumpstats)
1100 errx(1, "cannot set both -N and -D");
1102 if (threads > 1 && cmd == RX_PERF_FILE)
1103 errx(1, "cannot use multiple threads with file command");
1108 if (cmd == RX_PERF_UNKNOWN)
1109 errx(1, "no command given to the client");
1111 do_client(host, port, filename, cmd, times, bytes, sendbytes,
1112 readbytes, dumpstats, nojumbo, maxmtu, maxwsize, minpeertimeout,
1113 udpbufsz, nostats, hotthreads, threads);
1119 * setup world and call cmd
1123 main(int argc, char **argv)
1125 #ifndef AFS_PTHREAD_ENV
1129 setprogname(argv[0]);
1131 #ifndef AFS_NT40_ENV
1132 signal(SIGUSR1, sigusr1);
1133 signal(SIGINT, sigint);
1136 #ifndef AFS_PTHREAD_ENV
1137 LWP_InitializeProcessSupport(LWP_NORMAL_PRIORITY, &pid);
1140 memset(somebuf, 0, sizeof(somebuf));
1142 if (argc >= 2 && strcmp(argv[1], "server") == 0)
1143 rxperf_server(argc - 1, argv + 1);
1144 else if (argc >= 2 && strcmp(argv[1], "client") == 0)
1145 rxperf_client(argc - 1, argv + 1);