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 #ifdef HAVE_SYS_FILE_H
21 #include <rx/rx_clock.h>
23 #include <rx/rx_globals.h>
24 #include <rx/rx_null.h>
25 #include <afs/afsutil.h>
28 #define osi_Alloc(n) malloc(n)
32 int print
= 1, eventlog
= 0, rxlog
= 0;
36 struct clock waitTime
, computeTime
;
39 void Abort(const char *msg
, ...);
41 int SendFile(char *file
, struct rx_connection
*conn
);
50 quitSignal(int ignore
)
52 static int quitCount
= 0;
54 Quit("rx_ctest: second quit signal, aborting");
55 rx_debugFile
= debugFile
= fopen("rx_ctest.db", "w");
57 rx_PrintStats(debugFile
);
60 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
62 test_syscall(afs_uint32 a3
, afs_uint32 a4
, void *a5
)
67 old
= signal(SIGSYS
, SIG_IGN
);
69 syscall(31 /* AFS_SYSCALL */ , 28 /* AFSCALL_CALL */ , a3
, a4
, a5
);
77 main(int argc
, char **argv
)
80 struct hostent
*hostent
;
83 struct rx_connection
*conn
;
87 int nCalls
= 1, nBytes
= 1;
88 int bufferSize
= 4000000;
94 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV)
96 rxi_syscallp
= test_syscall
;
102 while (argc
&& **argv
== '-') {
103 if (strcmp(*argv
, "-silent") == 0)
105 if (strcmp(*argv
, "-jumbo") == 0)
107 else if (strcmp(*argv
, "-nc") == 0)
108 nCalls
= atoi(*++argv
), argc
--;
109 else if (strcmp(*argv
, "-nb") == 0)
110 nBytes
= atoi(*++argv
), argc
--;
111 else if (strcmp(*argv
, "-np") == 0)
112 rx_nPackets
= atoi(*++argv
), argc
--;
113 else if (!strcmp(*argv
, "-nsf"))
114 rxi_nSendFrags
= atoi(*++argv
), argc
--;
115 else if (!strcmp(*argv
, "-nrf"))
116 rxi_nRecvFrags
= atoi(*++argv
), argc
--;
117 else if (strcmp(*argv
, "-twind") == 0)
118 rx_initSendWindow
= atoi(*++argv
), argc
--;
119 else if (strcmp(*argv
, "-rwind") == 0)
120 rx_initReceiveWindow
= atoi(*++argv
), argc
--;
121 else if (strcmp(*argv
, "-rxlog") == 0)
123 else if (strcmp(*argv
, "-logstdout") == 0)
125 else if (strcmp(*argv
, "-eventlog") == 0)
127 else if (strcmp(*argv
, "-drop") == 0) {
129 rx_intentionallyDroppedPacketsPer100
= atoi(*++argv
), argc
--;
131 fprintf(stderr
, "ERROR: Compiled without RXDEBUG\n");
133 } else if (strcmp(*argv
, "-timeout") == 0)
134 timeout
= atoi(*++argv
), argc
--;
135 else if (strcmp(*argv
, "-fill") == 0)
137 else if (strcmp(*argv
, "-file") == 0)
138 sendFile
= *++argv
, argc
--;
139 else if (strcmp(*argv
, "-timereadvs") == 0)
141 else if (strcmp(*argv
, "-wait") == 0) {
142 /* Wait time between calls--to test lastack code */
143 waitTime
.sec
= atoi(*++argv
), argc
--;
144 waitTime
.usec
= atoi(*++argv
), argc
--;
145 } else if (strcmp(*argv
, "-compute") == 0) {
146 /* Simulated "compute" time for each call--to test acknowledgement protocol. This is simulated by doing an iomgr_select: imperfect, admittedly. */
147 computeTime
.sec
= atoi(*++argv
), argc
--;
148 computeTime
.usec
= atoi(*++argv
), argc
--;
149 } else if (strcmp(*argv
, "-fd") == 0) {
150 /* Open at least this many fd's. */
151 setFD
= atoi(*++argv
), argc
--;
158 if (err
|| argc
!= 1)
159 Quit("usage: rx_ctest [-silent] [-rxlog] [-eventlog] [-nc NCALLS] [-np NPACKETS] hostname");
160 hostname
= *argv
++, argc
--;
162 if (rxlog
|| eventlog
) {
166 debugFile
= fopen("rx_ctest.db", "w");
167 if (debugFile
== NULL
)
168 Quit("Couldn't open rx_ctest.db");
170 rx_debugFile
= debugFile
;
172 rxevent_debugFile
= debugFile
;
175 signal(SIGINT
, intSignal
); /*Changed to sigquit since dbx is broken right now */
177 signal(SIGQUIT
, quitSignal
);
181 if (afs_winsockInit() < 0) {
182 printf("Can't initialize winsock.\n");
185 rx_EnableHotThread();
188 rx_SetUdpBufSize(256 * 1024);
193 hostent
= gethostbyname(hostname
);
195 Abort("host %s not found", hostname
);
196 if (hostent
->h_length
!= 4)
197 Abort("host address is disagreeable length (%d)", hostent
->h_length
);
198 memcpy((char *)&host
, hostent
->h_addr
, sizeof(host
));
201 if (rx_Init(0) != 0) {
202 printf("RX failed to initialize, exiting.\n");
206 printf("rx_socket=%d\n", rx_socket
);
209 printf("Using %d packet buffers\n", rx_nPackets
);
212 rx_NewConnection(host
, htons(2500), 3,
213 rxnull_NewClientSecurityObject(), 0);
216 Abort("unable to make a new connection");
219 SendFile(sendFile
, conn
);
221 buffer
= osi_Alloc(bufferSize
);
223 struct clock startTime
;
229 call
= rx_NewCall(conn
);
231 Abort("unable to make a new call");
233 clock_GetTime(&startTime
);
234 for (bytesSent
= 0; bytesSent
< nBytes
; bytesSent
+= nSent
) {
238 nBytes
- bytesSent
) ? nBytes
- bytesSent
: bufferSize
;
239 nSent
= rx_Write(call
, buffer
, tryCount
);
244 for (bytesRead
= 0; (nbytes
= rx_Read(call
, buffer
, bufferSize
));
245 bytesRead
+= nbytes
) {
248 printf("Received %d characters in response\n", bytesRead
);
249 err
= rx_EndCall(call
, 0);
251 printf("Error %d returned from rpc call\n", err
);
253 struct clock totalTime
;
255 clock_GetTime(&totalTime
);
256 clock_Sub(&totalTime
, &startTime
);
257 elapsedTime
= clock_Float(&totalTime
);
259 "Sent %d bytes in %0.3f seconds: %0.0f bytes per second\n",
260 bytesSent
, elapsedTime
, bytesSent
/ elapsedTime
);
262 if (!clock_IsZero(&computeTime
)) {
263 t
.tv_sec
= computeTime
.sec
;
264 t
.tv_usec
= computeTime
.usec
;
265 if (select(0, 0, 0, 0, &t
) != 0)
266 Quit("Select didn't return 0");
268 if (!clock_IsZero(&waitTime
)) {
270 t
.tv_sec
= waitTime
.sec
;
271 t
.tv_usec
= waitTime
.usec
;
272 #ifdef AFS_PTHREAD_ENV
273 select(0, 0, 0, 0, &t
);
275 IOMGR_Sleep(t
.tv_sec
);
279 rx_PrintPeerStats(debugFile
, rx_PeerOf(conn
));
280 rx_PrintPeerStats(stdout
, rx_PeerOf(conn
));
283 Quit("testclient: done!\n");
288 SendFile(char *file
, struct rx_connection
*conn
)
290 struct rx_call
*call
;
293 int blockSize
, bytesLeft
;
297 struct clock startTime
;
298 int receivedStore
= 0;
299 struct clock totalReadvDelay
;
303 #include <sys/statfs.h>
304 struct statfs tstatfs
;
309 clock_Zero(&totalReadvDelay
);
311 fd
= open(file
, O_RDONLY
, 0);
313 Abort("Couldn't open %s\n", file
);
319 /* Unfortunately in AIX valuable fields such as st_blksize are gone from the stat structure!! */
320 fstatfs(fd
, &tstatfs
);
321 blockSize
= tstatfs
.f_bsize
;
323 blockSize
= status
.st_blksize
;
326 buf
= osi_Alloc(blockSize
);
327 bytesLeft
= status
.st_size
;
328 clock_GetTime(&startTime
);
329 call
= rx_NewCall(conn
);
331 if (!receivedStore
&& rx_GetRemoteStatus(call
) == 79) {
334 "Remote status indicates file accepted (\"received store\")\n");
336 nbytes
= (bytesLeft
> blockSize
? blockSize
: bytesLeft
);
338 code
= read(fd
, buf
, nbytes
);
339 if (code
!= nbytes
) {
340 Abort("Only read %d bytes of %d, errno=%d\n", code
, nbytes
,
343 code
= rx_Write(call
, buf
, nbytes
);
344 if (code
!= nbytes
) {
345 Abort("Only wrote %d bytes of %d\n", code
, nbytes
);
349 while ((nbytes
= rx_Read(call
, buf
, sizeof(buf
))) > 0) {
356 if ((err
= rx_EndCall(call
, 0)) != 0) {
357 fprintf(stderr
, "rx_Endcall returned error %d\n", err
);
359 struct clock totalTime
;
361 clock_GetTime(&totalTime
);
362 clock_Sub(&totalTime
, &startTime
);
363 elapsedTime
= totalTime
.sec
+ totalTime
.usec
/ 1e6
;
365 "Sent %d bytes in %0.3f seconds: %0.0f bytes per second\n",
366 (int) status
.st_size
, elapsedTime
, status
.st_size
/ elapsedTime
);
368 float delay
= clock_Float(&totalReadvDelay
) / nReadvs
;
369 fprintf(stderr
, "%d readvs, average delay of %0.4f seconds\n",
379 Abort(const char *msg
, ...)
389 rx_PrintStats(debugFile
);
401 rx_PrintStats(debugFile
);
404 rx_PrintStats(stdout
);
410 * Open file descriptors until file descriptor n or higher is returned.
420 for (i
= 0; i
< n
; i
++) {
421 if (fstat(i
, &sbuf
) == 0)
423 if ((fd
= open("/dev/null", 0, 0)) < 0) {