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 <afs/param.h>
13 #include <sys/types.h>
21 #include <netinet/in.h>
27 #include "../rx_clock.h"
29 #include "../rx_globals.h"
30 #include "../rx_null.h"
32 #include <afs/afsutil.h>
35 #define osi_Alloc(n) (char *) malloc(n)
39 int print = 1, eventlog = 0, rxlog = 0;
41 int burst; struct clock burstTime;
42 struct clock retryTime;
43 extern int rx_initSendWindow, rx_initReceiveWindow;
44 extern int rxi_nSendFrags, rxi_nRecvFrags;
45 extern rx_intentionallyDroppedPacketsPer100;
46 extern int (*rxi_syscallp)();
49 struct clock waitTime, computeTime;
53 void intSignal(int ignore) {
57 void quitSignal(int ignore) {
58 static int quitCount = 0;
59 if (++quitCount > 1) Quit("rx_ctest: second quit signal, aborting");
60 rx_debugFile = debugFile = fopen("rx_ctest.db", "w");
61 if (debugFile) rx_PrintStats(debugFile);
64 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
65 int test_syscall(a3, a4, a5)
72 old = signal(SIGSYS, SIG_IGN);
73 rcode = syscall (31 /* AFS_SYSCALL */, 28 /* AFSCALL_CALL */, a3, a4, a5);
84 struct hostent *hostent;
87 struct rx_connection *conn;
90 int nCalls = 1, nBytes = 1;
91 int bufferSize = 2000;
96 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
98 rxi_syscallp = test_syscall;
103 while (argc && **argv == '-') {
104 if (strcmp(*argv, "-silent") == 0) print = 0;
105 else if (strcmp(*argv, "-nc") == 0) nCalls = atoi(*++argv), argc--;
106 else if (strcmp(*argv, "-nb") == 0) nBytes = atoi(*++argv), argc--;
107 else if (strcmp(*argv, "-npb") == 0) rx_nPackets = atoi(*++argv), argc--;
108 else if (!strcmp(*argv, "-nsf"))
109 rxi_nSendFrags = atoi(*++argv), argc--;
110 else if (!strcmp(*argv, "-nrf"))
111 rxi_nRecvFrags = atoi(*++argv), argc--;
112 else if (strcmp(*argv, "-twind") == 0)
113 rx_initSendWindow = atoi(*++argv), argc--;
114 else if (strcmp(*argv, "-rwind") == 0)
115 rx_initReceiveWindow = atoi(*++argv), argc--;
116 else if (strcmp(*argv, "-rxlog") == 0) rxlog = 1;
117 else if (strcmp(*argv, "-logstdout") == 0) logstdout = 1;
118 else if (strcmp(*argv, "-eventlog") == 0) eventlog = 1;
119 else if (strcmp(*argv, "-drop") == 0) rx_intentionallyDroppedPacketsPer100 = atoi(*++argv), argc--;
120 else if (strcmp(*argv, "-burst") == 0) {
121 burst = atoi(*++argv), argc--;
122 burstTime.sec = atoi(*++argv), argc--;
123 burstTime.usec = atoi(*++argv), argc--;
125 else if (strcmp(*argv, "-retry") == 0) {
126 retryTime.sec = atoi(*++argv), argc--;
127 retryTime.usec = atoi(*++argv), argc--;
129 else if (strcmp(*argv, "-timeout") == 0) timeout = atoi(*++argv), argc--;
130 else if (strcmp(*argv, "-fill") == 0) fillPackets++;
131 else if (strcmp(*argv, "-file") == 0) sendFile = *++argv, argc--;
132 else if (strcmp(*argv, "-timereadvs") == 0) timeReadvs = 1;
133 else if (strcmp(*argv, "-wait") == 0) {
134 /* Wait time between calls--to test lastack code */
135 waitTime.sec = atoi(*++argv), argc--;
136 waitTime.usec = atoi(*++argv), argc--;
138 else if (strcmp(*argv, "-compute") == 0) {
139 /* Simulated "compute" time for each call--to test acknowledgement protocol. This is simulated by doing an iomgr_select: imperfect, admittedly. */
140 computeTime.sec = atoi(*++argv), argc--;
141 computeTime.usec = atoi(*++argv), argc--;
143 else if (strcmp(*argv, "-fd") == 0) {
144 /* Open at least this many fd's. */
145 setFD = atoi(*++argv), argc--;
147 else {err = 1;break;}
150 if (err || argc != 1)
151 Quit("usage: rx_ctest [-silent] [-rxlog] [-eventlog] [-nc NCALLS] [-np NPACKETS] hostname");
152 hostname = *argv++, argc--;
154 if (rxlog || eventlog) {
155 if (logstdout) debugFile = stdout;
156 else debugFile = fopen("rx_ctest.db", "w");
157 if (debugFile == NULL) Quit("Couldn't open rx_ctest.db");
158 if (rxlog) rx_debugFile = debugFile;
159 if (eventlog) rxevent_debugFile = debugFile;
162 signal(SIGINT, intSignal);/*Changed to sigquit since dbx is broken right now */
164 signal(SIGQUIT, quitSignal);
168 if (afs_winsockInit()<0) {
169 printf("Can't initialize winsock.\n");
174 hostent = gethostbyname(hostname);
175 if (!hostent) Abort("host %s not found", hostname);
176 if (hostent->h_length != 4)
177 Abort("host address is disagreeable length (%d)", hostent->h_length);
178 bcopy(hostent->h_addr, (char *)&host, sizeof(host));
181 if (rx_Init(0) != 0) {
182 printf("RX failed to initialize, exiting.\n");
186 printf("rx_socket=%d\n", rx_socket);
189 printf("Using %d packet buffers\n", rx_nPackets);
191 conn = rx_NewConnection(host, htons(2500), 3, rxnull_NewClientSecurityObject(), 0);
193 if (!conn) Abort("unable to make a new connection");
195 /* Set initial parameters. This is (currently) not the approved interface */
196 if (burst) conn->peer->burstSize = conn->peer->burst = burst;
197 if (!clock_IsZero(&burstTime)) conn->peer->burstWait = burstTime;
198 if (!clock_IsZero(&retryTime)) conn->peer->timeout = retryTime;
200 if (sendFile) SendFile(sendFile, conn);
202 buffer = (char *) osi_Alloc(bufferSize);
204 struct clock startTime;
210 call = rx_NewCall(conn);
211 if (!call) Abort("unable to make a new call");
213 clock_GetTime(&startTime);
214 for (bytesSent = 0; bytesSent < nBytes; bytesSent += nSent) {
216 tryCount = (bufferSize > nBytes - bytesSent)? nBytes - bytesSent: bufferSize;
217 nSent = rx_Write(call, buffer, tryCount);
218 if (nSent == 0) break;
221 for (bytesRead = 0; nbytes = rx_Read(call, buffer, bufferSize); bytesRead += nbytes) {};
222 if (print) printf("Received %d characters in response\n", bytesRead);
223 err = rx_EndCall(call, 0);
224 if (err) printf("Error %d returned from rpc call\n", err);
226 struct clock totalTime;
228 clock_GetTime(&totalTime);
229 clock_Sub(&totalTime, &startTime);
230 elapsedTime = clock_Float(&totalTime);
231 fprintf(stderr, "Sent %d bytes in %0.3f seconds: %0.0f bytes per second\n",
232 bytesSent, elapsedTime, bytesSent/elapsedTime);
234 if (!clock_IsZero(&computeTime)) {
235 t.tv_sec = computeTime.sec;
236 t.tv_usec = computeTime.usec;
237 if (select(0, 0, 0, 0, &t) != 0) Quit("Select didn't return 0");
239 if (!clock_IsZero(&waitTime)) {
241 t.tv_sec = waitTime.sec;
242 t.tv_usec = waitTime.usec;
243 #ifdef AFS_PTHREAD_ENV
246 IOMGR_Sleep(t.tv_sec);
250 if (debugFile) rx_PrintPeerStats(debugFile, rx_PeerOf(conn));
251 rx_PrintPeerStats(stdout, rx_PeerOf(conn));
253 Quit("testclient: done!\n");
258 struct rx_connection *conn;
260 struct rx_call *call;
263 int blockSize, bytesLeft;
267 struct clock startTime;
268 int receivedStore = 0;
269 struct clock totalReadvDelay;
273 #include <sys/statfs.h>
274 struct statfs tstatfs;
279 clock_Zero(&totalReadvDelay);
281 fd = open(file, O_RDONLY, 0);
282 if (fd < 0) Abort("Couldn't open %s\n", file);
288 /* Unfortunately in AIX valuable fields such as st_blksize are gone from the stat structure!! */
289 fstatfs(fd, &tstatfs);
290 blockSize = tstatfs.f_bsize;
292 blockSize = status.st_blksize;
295 buf = (char *) osi_Alloc(blockSize);
296 bytesLeft = status.st_size;
297 clock_GetTime(&startTime);
298 call = rx_NewCall(conn);
300 if (!receivedStore && rx_GetRemoteStatus(call) == 79) {
302 fprintf(stderr, "Remote status indicates file accepted (\"received store\")\n");
304 nbytes = (bytesLeft > blockSize? blockSize: bytesLeft);
306 code = read(fd, buf, nbytes);
307 if (code != nbytes) {
308 Abort("Only read %d bytes of %d, errno=%d\n", code, nbytes, errno);
310 code = rx_Write(call, buf, nbytes);
311 if (code != nbytes) {
312 Abort("Only wrote %d bytes of %d\n", code, nbytes);
316 while ((nbytes = rx_Read(call, buf, sizeof(buf))) > 0) {
318 while (nbytes--) {putchar(*p); *p++;}
320 if ((err = rx_EndCall(call, 0)) != 0) {
321 fprintf(stderr, "rx_Endcall returned error %d\n", err);
323 struct clock totalTime;
325 clock_GetTime(&totalTime);
326 clock_Sub(&totalTime, &startTime);
327 elapsedTime = totalTime.sec + totalTime.usec/1e6;
328 fprintf(stderr, "Sent %d bytes in %0.3f seconds: %0.0f bytes per second\n",
329 status.st_size, elapsedTime, status.st_size/elapsedTime);
331 float delay = clock_Float(&totalReadvDelay) / nReadvs;
332 fprintf(stderr, "%d readvs, average delay of %0.4f seconds\n", nReadvs, delay);
338 Abort(msg,a,b,c,d,e) {
339 printf((char *) msg, a, b, c, d, e);
342 rx_PrintStats(debugFile);
349 Quit(msg, a,b,c,d,e) {
350 printf((char *) msg, a,b,c,d,e);
353 rx_PrintStats(debugFile);
356 rx_PrintStats(stdout);
362 * Open file descriptors until file descriptor n or higher is returned.
364 #include <sys/stat.h>
373 for (i=0; i<n; i++) {
374 if (fstat(i, &sbuf) == 0)
376 if ((fd = open("/dev/null", 0, 0)) < 0) {