2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* Client test program */
12 #include <afsconfig.h>
13 #include <afs/param.h>
16 #include <sys/types.h>
24 #include <netinet/in.h>
30 #include <rx/rx_clock.h>
32 #include <rx/rx_globals.h>
33 #include <rx/rx_null.h>
35 #include <afs/afsutil.h>
38 #define osi_Alloc(n) (char *) malloc(n)
42 int print = 1, eventlog = 0, rxlog = 0;
45 struct clock burstTime;
46 struct clock retryTime;
49 struct clock waitTime, computeTime;
52 void Abort(const char *msg, ...);
54 int SendFile(char *file, struct rx_connection *conn);
63 quitSignal(int ignore)
65 static int quitCount = 0;
67 Quit("rx_ctest: second quit signal, aborting");
68 rx_debugFile = debugFile = fopen("rx_ctest.db", "w");
70 rx_PrintStats(debugFile);
73 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
75 test_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
80 old = signal(SIGSYS, SIG_IGN);
82 syscall(31 /* AFS_SYSCALL */ , 28 /* AFSCALL_CALL */ , a3, a4, a5);
90 main(int argc, char **argv)
93 struct hostent *hostent;
96 struct rx_connection *conn;
99 int nCalls = 1, nBytes = 1;
100 int bufferSize = 4000000;
106 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
108 rxi_syscallp = test_syscall;
114 while (argc && **argv == '-') {
115 if (strcmp(*argv, "-silent") == 0)
117 if (strcmp(*argv, "-jumbo") == 0)
119 else if (strcmp(*argv, "-nc") == 0)
120 nCalls = atoi(*++argv), argc--;
121 else if (strcmp(*argv, "-nb") == 0)
122 nBytes = atoi(*++argv), argc--;
123 else if (strcmp(*argv, "-np") == 0)
124 rx_nPackets = atoi(*++argv), argc--;
125 else if (!strcmp(*argv, "-nsf"))
126 rxi_nSendFrags = atoi(*++argv), argc--;
127 else if (!strcmp(*argv, "-nrf"))
128 rxi_nRecvFrags = atoi(*++argv), argc--;
129 else if (strcmp(*argv, "-twind") == 0)
130 rx_initSendWindow = atoi(*++argv), argc--;
131 else if (strcmp(*argv, "-rwind") == 0)
132 rx_initReceiveWindow = atoi(*++argv), argc--;
133 else if (strcmp(*argv, "-rxlog") == 0)
135 else if (strcmp(*argv, "-logstdout") == 0)
137 else if (strcmp(*argv, "-eventlog") == 0)
139 else if (strcmp(*argv, "-drop") == 0) {
141 rx_intentionallyDroppedPacketsPer100 = atoi(*++argv), argc--;
143 fprintf(stderr, "ERROR: Compiled without RXDEBUG\n");
146 else if (strcmp(*argv, "-burst") == 0) {
147 burst = atoi(*++argv), argc--;
148 burstTime.sec = atoi(*++argv), argc--;
149 burstTime.usec = atoi(*++argv), argc--;
150 } else if (strcmp(*argv, "-retry") == 0) {
151 retryTime.sec = atoi(*++argv), argc--;
152 retryTime.usec = atoi(*++argv), argc--;
153 } else if (strcmp(*argv, "-timeout") == 0)
154 timeout = atoi(*++argv), argc--;
155 else if (strcmp(*argv, "-fill") == 0)
157 else if (strcmp(*argv, "-file") == 0)
158 sendFile = *++argv, argc--;
159 else if (strcmp(*argv, "-timereadvs") == 0)
161 else if (strcmp(*argv, "-wait") == 0) {
162 /* Wait time between calls--to test lastack code */
163 waitTime.sec = atoi(*++argv), argc--;
164 waitTime.usec = atoi(*++argv), argc--;
165 } else if (strcmp(*argv, "-compute") == 0) {
166 /* Simulated "compute" time for each call--to test acknowledgement protocol. This is simulated by doing an iomgr_select: imperfect, admittedly. */
167 computeTime.sec = atoi(*++argv), argc--;
168 computeTime.usec = atoi(*++argv), argc--;
169 } else if (strcmp(*argv, "-fd") == 0) {
170 /* Open at least this many fd's. */
171 setFD = atoi(*++argv), argc--;
178 if (err || argc != 1)
179 Quit("usage: rx_ctest [-silent] [-rxlog] [-eventlog] [-nc NCALLS] [-np NPACKETS] hostname");
180 hostname = *argv++, argc--;
182 if (rxlog || eventlog) {
186 debugFile = fopen("rx_ctest.db", "w");
187 if (debugFile == NULL)
188 Quit("Couldn't open rx_ctest.db");
190 rx_debugFile = debugFile;
192 rxevent_debugFile = debugFile;
195 signal(SIGINT, intSignal); /*Changed to sigquit since dbx is broken right now */
197 signal(SIGQUIT, quitSignal);
201 if (afs_winsockInit() < 0) {
202 printf("Can't initialize winsock.\n");
205 rx_EnableHotThread();
208 rx_SetUdpBufSize(256 * 1024);
213 hostent = gethostbyname(hostname);
215 Abort("host %s not found", hostname);
216 if (hostent->h_length != 4)
217 Abort("host address is disagreeable length (%d)", hostent->h_length);
218 memcpy((char *)&host, hostent->h_addr, sizeof(host));
221 if (rx_Init(0) != 0) {
222 printf("RX failed to initialize, exiting.\n");
226 printf("rx_socket=%d\n", rx_socket);
229 printf("Using %d packet buffers\n", rx_nPackets);
232 rx_NewConnection(host, htons(2500), 3,
233 rxnull_NewClientSecurityObject(), 0);
236 Abort("unable to make a new connection");
238 /* Set initial parameters. This is (currently) not the approved interface */
240 conn->peer->burstSize = conn->peer->burst = burst;
241 if (!clock_IsZero(&burstTime))
242 conn->peer->burstWait = burstTime;
243 if (!clock_IsZero(&retryTime))
244 conn->peer->rtt = _8THMSEC(&retryTime);
246 SendFile(sendFile, conn);
248 buffer = (char *)osi_Alloc(bufferSize);
250 struct clock startTime;
256 call = rx_NewCall(conn);
258 Abort("unable to make a new call");
260 clock_GetTime(&startTime);
261 for (bytesSent = 0; bytesSent < nBytes; bytesSent += nSent) {
265 nBytes - bytesSent) ? nBytes - bytesSent : bufferSize;
266 nSent = rx_Write(call, buffer, tryCount);
271 for (bytesRead = 0; (nbytes = rx_Read(call, buffer, bufferSize));
272 bytesRead += nbytes) {
275 printf("Received %d characters in response\n", bytesRead);
276 err = rx_EndCall(call, 0);
278 printf("Error %d returned from rpc call\n", err);
280 struct clock totalTime;
282 clock_GetTime(&totalTime);
283 clock_Sub(&totalTime, &startTime);
284 elapsedTime = clock_Float(&totalTime);
286 "Sent %d bytes in %0.3f seconds: %0.0f bytes per second\n",
287 bytesSent, elapsedTime, bytesSent / elapsedTime);
289 if (!clock_IsZero(&computeTime)) {
290 t.tv_sec = computeTime.sec;
291 t.tv_usec = computeTime.usec;
292 if (select(0, 0, 0, 0, &t) != 0)
293 Quit("Select didn't return 0");
295 if (!clock_IsZero(&waitTime)) {
297 t.tv_sec = waitTime.sec;
298 t.tv_usec = waitTime.usec;
299 #ifdef AFS_PTHREAD_ENV
300 select(0, 0, 0, 0, &t);
302 IOMGR_Sleep(t.tv_sec);
306 rx_PrintPeerStats(debugFile, rx_PeerOf(conn));
307 rx_PrintPeerStats(stdout, rx_PeerOf(conn));
310 Quit("testclient: done!\n");
315 SendFile(char *file, struct rx_connection *conn)
317 struct rx_call *call;
320 int blockSize, bytesLeft;
324 struct clock startTime;
325 int receivedStore = 0;
326 struct clock totalReadvDelay;
330 #include <sys/statfs.h>
331 struct statfs tstatfs;
336 clock_Zero(&totalReadvDelay);
338 fd = open(file, O_RDONLY, 0);
340 Abort("Couldn't open %s\n", file);
346 /* Unfortunately in AIX valuable fields such as st_blksize are gone from the stat structure!! */
347 fstatfs(fd, &tstatfs);
348 blockSize = tstatfs.f_bsize;
350 blockSize = status.st_blksize;
353 buf = (char *)osi_Alloc(blockSize);
354 bytesLeft = status.st_size;
355 clock_GetTime(&startTime);
356 call = rx_NewCall(conn);
358 if (!receivedStore && rx_GetRemoteStatus(call) == 79) {
361 "Remote status indicates file accepted (\"received store\")\n");
363 nbytes = (bytesLeft > blockSize ? blockSize : bytesLeft);
365 code = read(fd, buf, nbytes);
366 if (code != nbytes) {
367 Abort("Only read %d bytes of %d, errno=%d\n", code, nbytes,
370 code = rx_Write(call, buf, nbytes);
371 if (code != nbytes) {
372 Abort("Only wrote %d bytes of %d\n", code, nbytes);
376 while ((nbytes = rx_Read(call, buf, sizeof(buf))) > 0) {
383 if ((err = rx_EndCall(call, 0)) != 0) {
384 fprintf(stderr, "rx_Endcall returned error %d\n", err);
386 struct clock totalTime;
388 clock_GetTime(&totalTime);
389 clock_Sub(&totalTime, &startTime);
390 elapsedTime = totalTime.sec + totalTime.usec / 1e6;
392 "Sent %d bytes in %0.3f seconds: %0.0f bytes per second\n",
393 (int) status.st_size, elapsedTime, status.st_size / elapsedTime);
395 float delay = clock_Float(&totalReadvDelay) / nReadvs;
396 fprintf(stderr, "%d readvs, average delay of %0.4f seconds\n",
406 Abort(const char *msg, ...)
416 rx_PrintStats(debugFile);
428 rx_PrintStats(debugFile);
431 rx_PrintStats(stdout);
437 * Open file descriptors until file descriptor n or higher is returned.
439 #include <sys/stat.h>
448 for (i = 0; i < n; i++) {
449 if (fstat(i, &sbuf) == 0)
451 if ((fd = open("/dev/null", 0, 0)) < 0) {