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
12 * Test of the xstat_fs module.
14 *------------------------------------------------------------------------*/
16 #include <afsconfig.h>
17 #include <afs/param.h>
21 #include "xstat_fs.h" /*Interface for xstat_fs module */
22 #include <afs/cmd.h> /*Command line interpreter */
23 #include <afs/afsutil.h>
26 * Command line parameter indices.
27 * P_FS_NAMES : List of FileServer names.
28 * P_COLL_IDS : List of collection IDs to pick up.
29 * P_ONESHOT : Are we gathering exactly one round of data?
30 * P_DEBUG : Enable debugging output?
42 static int debugging_on
= 0; /*Are we debugging? */
43 static int one_shot
= 0; /*Single round of data collection? */
45 static char *opNames
[] = {
76 static char *xferOpNames
[] = {
82 /*------------------------------------------------------------------------
86 * Print out the AFS_XSTATSCOLL_CALL_INFO collection we just
96 * All the info we need is nestled into xstat_fs_Results.
100 *------------------------------------------------------------------------*/
105 int i
; /*Loop variable */
106 int numInt32s
; /*# int32words returned */
107 afs_int32
*currInt32
; /*Ptr to current afs_int32 value */
108 char *printableTime
; /*Ptr to printable time string */
109 time_t probeTime
= xstat_fs_Results
.probeTime
;
112 * Just print out the results of the particular probe.
114 numInt32s
= xstat_fs_Results
.data
.AFS_CollData_len
;
115 currInt32
= (afs_int32
*) (xstat_fs_Results
.data
.AFS_CollData_val
);
116 printableTime
= ctime(&probeTime
);
117 printableTime
[strlen(printableTime
) - 1] = '\0';
119 printf("AFS_XSTATSCOLL_CALL_INFO (coll %d) for FS %s\n[Probe %u, %s]\n\n",
120 xstat_fs_Results
.collectionNumber
,
121 xstat_fs_Results
.connP
->hostName
, xstat_fs_Results
.probeNum
,
125 printf("\n[%u entries returned at %" AFS_PTR_FMT
"]\n\n", numInt32s
, currInt32
);
127 for (i
= 0; i
< numInt32s
; i
++)
128 printf("%u ", *currInt32
++);
134 /*------------------------------------------------------------------------
135 * PrintOverallPerfInfo
138 * Print out overall performance numbers.
141 * a_ovP : Ptr to the overall performance numbers.
147 * Nothing interesting.
151 *------------------------------------------------------------------------*/
154 PrintOverallPerfInfo(struct afs_PerfStats
*a_ovP
)
156 printf("\t%10u numPerfCalls\n\n", a_ovP
->numPerfCalls
);
159 * Vnode cache section.
161 printf("\t%10u vcache_L_Entries\n", a_ovP
->vcache_L_Entries
);
162 printf("\t%10u vcache_L_Allocs\n", a_ovP
->vcache_L_Allocs
);
163 printf("\t%10u vcache_L_Gets\n", a_ovP
->vcache_L_Gets
);
164 printf("\t%10u vcache_L_Reads\n", a_ovP
->vcache_L_Reads
);
165 printf("\t%10u vcache_L_Writes\n\n", a_ovP
->vcache_L_Writes
);
167 printf("\t%10u vcache_S_Entries\n", a_ovP
->vcache_S_Entries
);
168 printf("\t%10u vcache_S_Allocs\n", a_ovP
->vcache_S_Allocs
);
169 printf("\t%10u vcache_S_Gets\n", a_ovP
->vcache_S_Gets
);
170 printf("\t%10u vcache_S_Reads\n", a_ovP
->vcache_S_Reads
);
171 printf("\t%10u vcache_S_Writes\n\n", a_ovP
->vcache_S_Writes
);
173 printf("\t%10u vcache_H_Entries\n", a_ovP
->vcache_H_Entries
);
174 printf("\t%10u vcache_H_Gets\n", a_ovP
->vcache_H_Gets
);
175 printf("\t%10u vcache_H_Replacements\n\n", a_ovP
->vcache_H_Replacements
);
178 * Directory package section.
180 printf("\t%10u dir_Buffers\n", a_ovP
->dir_Buffers
);
181 printf("\t%10u dir_Calls\n", a_ovP
->dir_Calls
);
182 printf("\t%10u dir_IOs\n\n", a_ovP
->dir_IOs
);
187 printf("\t%10u rx_packetRequests\n", a_ovP
->rx_packetRequests
);
188 printf("\t%10u rx_noPackets_RcvClass\n", a_ovP
->rx_noPackets_RcvClass
);
189 printf("\t%10u rx_noPackets_SendClass\n", a_ovP
->rx_noPackets_SendClass
);
190 printf("\t%10u rx_noPackets_SpecialClass\n",
191 a_ovP
->rx_noPackets_SpecialClass
);
192 printf("\t%10u rx_socketGreedy\n", a_ovP
->rx_socketGreedy
);
193 printf("\t%10u rx_bogusPacketOnRead\n", a_ovP
->rx_bogusPacketOnRead
);
194 printf("\t%10u rx_bogusHost\n", a_ovP
->rx_bogusHost
);
195 printf("\t%10u rx_noPacketOnRead\n", a_ovP
->rx_noPacketOnRead
);
196 printf("\t%10u rx_noPacketBuffersOnRead\n",
197 a_ovP
->rx_noPacketBuffersOnRead
);
198 printf("\t%10u rx_selects\n", a_ovP
->rx_selects
);
199 printf("\t%10u rx_sendSelects\n", a_ovP
->rx_sendSelects
);
200 printf("\t%10u rx_packetsRead_RcvClass\n",
201 a_ovP
->rx_packetsRead_RcvClass
);
202 printf("\t%10u rx_packetsRead_SendClass\n",
203 a_ovP
->rx_packetsRead_SendClass
);
204 printf("\t%10u rx_packetsRead_SpecialClass\n",
205 a_ovP
->rx_packetsRead_SpecialClass
);
206 printf("\t%10u rx_dataPacketsRead\n", a_ovP
->rx_dataPacketsRead
);
207 printf("\t%10u rx_ackPacketsRead\n", a_ovP
->rx_ackPacketsRead
);
208 printf("\t%10u rx_dupPacketsRead\n", a_ovP
->rx_dupPacketsRead
);
209 printf("\t%10u rx_spuriousPacketsRead\n", a_ovP
->rx_spuriousPacketsRead
);
210 printf("\t%10u rx_packetsSent_RcvClass\n",
211 a_ovP
->rx_packetsSent_RcvClass
);
212 printf("\t%10u rx_packetsSent_SendClass\n",
213 a_ovP
->rx_packetsSent_SendClass
);
214 printf("\t%10u rx_packetsSent_SpecialClass\n",
215 a_ovP
->rx_packetsSent_SpecialClass
);
216 printf("\t%10u rx_ackPacketsSent\n", a_ovP
->rx_ackPacketsSent
);
217 printf("\t%10u rx_pingPacketsSent\n", a_ovP
->rx_pingPacketsSent
);
218 printf("\t%10u rx_abortPacketsSent\n", a_ovP
->rx_abortPacketsSent
);
219 printf("\t%10u rx_busyPacketsSent\n", a_ovP
->rx_busyPacketsSent
);
220 printf("\t%10u rx_dataPacketsSent\n", a_ovP
->rx_dataPacketsSent
);
221 printf("\t%10u rx_dataPacketsReSent\n", a_ovP
->rx_dataPacketsReSent
);
222 printf("\t%10u rx_dataPacketsPushed\n", a_ovP
->rx_dataPacketsPushed
);
223 printf("\t%10u rx_ignoreAckedPacket\n", a_ovP
->rx_ignoreAckedPacket
);
224 printf("\t%10u rx_totalRtt_Sec\n", a_ovP
->rx_totalRtt_Sec
);
225 printf("\t%10u rx_totalRtt_Usec\n", a_ovP
->rx_totalRtt_Usec
);
226 printf("\t%10u rx_minRtt_Sec\n", a_ovP
->rx_minRtt_Sec
);
227 printf("\t%10u rx_minRtt_Usec\n", a_ovP
->rx_minRtt_Usec
);
228 printf("\t%10u rx_maxRtt_Sec\n", a_ovP
->rx_maxRtt_Sec
);
229 printf("\t%10u rx_maxRtt_Usec\n", a_ovP
->rx_maxRtt_Usec
);
230 printf("\t%10u rx_nRttSamples\n", a_ovP
->rx_nRttSamples
);
231 printf("\t%10u rx_nServerConns\n", a_ovP
->rx_nServerConns
);
232 printf("\t%10u rx_nClientConns\n", a_ovP
->rx_nClientConns
);
233 printf("\t%10u rx_nPeerStructs\n", a_ovP
->rx_nPeerStructs
);
234 printf("\t%10u rx_nCallStructs\n", a_ovP
->rx_nCallStructs
);
235 printf("\t%10u rx_nFreeCallStructs\n", a_ovP
->rx_nFreeCallStructs
);
236 printf("\t%10u rx_nBusies\n\n", a_ovP
->rx_nBusies
);
238 printf("\t%10u fs_nBusies\n", a_ovP
->fs_nBusies
);
239 printf("\t%10u fs_GetCapabilities\n\n", a_ovP
->fs_nGetCaps
);
241 * Host module fields.
243 printf("\t%10u host_NumHostEntries\n", a_ovP
->host_NumHostEntries
);
244 printf("\t%10u host_HostBlocks\n", a_ovP
->host_HostBlocks
);
245 printf("\t%10u host_NonDeletedHosts\n", a_ovP
->host_NonDeletedHosts
);
246 printf("\t%10u host_HostsInSameNetOrSubnet\n",
247 a_ovP
->host_HostsInSameNetOrSubnet
);
248 printf("\t%10u host_HostsInDiffSubnet\n", a_ovP
->host_HostsInDiffSubnet
);
249 printf("\t%10u host_HostsInDiffNetwork\n",
250 a_ovP
->host_HostsInDiffNetwork
);
251 printf("\t%10u host_NumClients\n", a_ovP
->host_NumClients
);
252 printf("\t%10u host_ClientBlocks\n\n", a_ovP
->host_ClientBlocks
);
254 printf("\t%10u sysname_ID\n", a_ovP
->sysname_ID
);
258 /*------------------------------------------------------------------------
262 * Print out the contents of an RPC op timing structure.
265 * a_opIdx : Index of the AFS operation we're printing number on.
266 * a_opTimeP : Ptr to the op timing structure to print.
272 * Nothing interesting.
276 *------------------------------------------------------------------------*/
279 PrintOpTiming(int a_opIdx
, struct fs_stats_opTimingData
*a_opTimeP
)
282 ("%15s: %u ops (%u OK); sum=%lu.%06lu, sqr=%lu.%06lu, min=%lu.%06lu, max=%lu.%06lu\n",
283 opNames
[a_opIdx
], a_opTimeP
->numOps
, a_opTimeP
->numSuccesses
,
284 (long)a_opTimeP
->sumTime
.tv_sec
, (long)a_opTimeP
->sumTime
.tv_usec
,
285 (long)a_opTimeP
->sqrTime
.tv_sec
, (long)a_opTimeP
->sqrTime
.tv_usec
,
286 (long)a_opTimeP
->minTime
.tv_sec
, (long)a_opTimeP
->minTime
.tv_usec
,
287 (long)a_opTimeP
->maxTime
.tv_sec
, (long)a_opTimeP
->maxTime
.tv_usec
);
291 /*------------------------------------------------------------------------
295 * Print out the contents of a data transfer structure.
298 * a_opIdx : Index of the AFS operation we're printing number on.
299 * a_xferP : Ptr to the data transfer structure to print.
305 * Nothing interesting.
309 *------------------------------------------------------------------------*/
312 PrintXferTiming(int a_opIdx
, struct fs_stats_xferData
*a_xferP
)
315 ("%s: %u xfers (%u OK), time sum=%lu.%06lu, sqr=%lu.%06lu, min=%lu.%06lu, max=%lu.%06lu\n",
316 xferOpNames
[a_opIdx
], a_xferP
->numXfers
, a_xferP
->numSuccesses
,
317 (long)a_xferP
->sumTime
.tv_sec
, (long)a_xferP
->sumTime
.tv_usec
,
318 (long)a_xferP
->sqrTime
.tv_sec
, (long)a_xferP
->sqrTime
.tv_usec
,
319 (long)a_xferP
->minTime
.tv_sec
, (long)a_xferP
->minTime
.tv_usec
,
320 (long)a_xferP
->maxTime
.tv_sec
, (long)a_xferP
->maxTime
.tv_usec
);
321 printf("\t[bytes: sum=%u, min=%u, max=%u]\n", a_xferP
->sumBytes
,
322 a_xferP
->minBytes
, a_xferP
->maxBytes
);
324 ("\t[buckets: 0: %u, 1: %u, 2: %u, 3: %u, 4: %u, 5: %u, 6: %u, 7: %u, 8: %u]\n",
325 a_xferP
->count
[0], a_xferP
->count
[1], a_xferP
->count
[2],
326 a_xferP
->count
[3], a_xferP
->count
[4], a_xferP
->count
[5],
327 a_xferP
->count
[6], a_xferP
->count
[7], a_xferP
->count
[8]);
331 /*------------------------------------------------------------------------
332 * PrintDetailedPerfInfo
335 * Print out a set of detailed performance numbers.
338 * a_detP : Ptr to detailed perf numbers to print.
344 * Nothing interesting.
348 *------------------------------------------------------------------------*/
351 PrintDetailedPerfInfo(struct fs_stats_DetailedStats
*a_detP
)
353 int currIdx
; /*Loop variable */
355 printf("\t%10lu epoch\n", (long) a_detP
->epoch
.tv_sec
);
357 for (currIdx
= 0; currIdx
< FS_STATS_NUM_RPC_OPS
; currIdx
++)
358 PrintOpTiming(currIdx
, &(a_detP
->rpcOpTimes
[currIdx
]));
360 for (currIdx
= 0; currIdx
< FS_STATS_NUM_XFER_OPS
; currIdx
++)
361 PrintXferTiming(currIdx
, &(a_detP
->xferOpTimes
[currIdx
]));
365 /*------------------------------------------------------------------------
369 * Print out the AFS_XSTATSCOLL_FULL_PERF_INFO collection we just
379 * All the info we need is nestled into xstat_fs_Results.
383 *------------------------------------------------------------------------*/
386 PrintFullPerfInfo(void)
389 struct fs_stats_FullPerfStats
*fullPerfP
; /*Ptr to full perf stats */
390 struct fs_stats_FullPerfStats buffer
; /* to decode the stats */
391 char *printableTime
; /*Ptr to printable time
393 time_t probeTime
= xstat_fs_Results
.probeTime
;
394 static afs_int32 fullPerfInt32s
= (sizeof(struct fs_stats_FullPerfStats
) >> 2); /*Correct # int32s to rcv */
396 printableTime
= ctime(&probeTime
);
397 printableTime
[strlen(printableTime
) - 1] = '\0';
399 ("AFS_XSTATSCOLL_FULL_PERF_INFO (coll %d) for FS %s\n[Probe %u, %s]\n\n",
400 xstat_fs_Results
.collectionNumber
, xstat_fs_Results
.connP
->hostName
,
401 xstat_fs_Results
.probeNum
, printableTime
);
404 xstat_fs_DecodeFullPerfStats(&fullPerfP
,
405 xstat_fs_Results
.data
.AFS_CollData_val
,
406 xstat_fs_Results
.data
.AFS_CollData_len
,
409 afs_int32 numInt32s
= xstat_fs_Results
.data
.AFS_CollData_len
; /*# int32words received */
410 printf("** Data size mismatch in full performance collection!\n");
411 printf("** Expecting %u, got %u\n", fullPerfInt32s
, numInt32s
);
413 PrintOverallPerfInfo(&(fullPerfP
->overall
));
414 PrintDetailedPerfInfo(&(fullPerfP
->det
));
419 /*------------------------------------------------------------------------
423 * Print out the AFS_XSTATSCOLL_PERF_INFO collection we just
433 * All the info we need is nestled into xstat_fs_Results.
437 *------------------------------------------------------------------------*/
442 static afs_int32 perfInt32s
= (sizeof(struct afs_PerfStats
) >> 2); /*Correct # int32s to rcv */
443 afs_int32 numInt32s
; /*# int32words received */
444 struct afs_PerfStats
*perfP
; /*Ptr to performance stats */
445 char *printableTime
; /*Ptr to printable time string */
446 time_t probeTime
= xstat_fs_Results
.probeTime
;
448 numInt32s
= xstat_fs_Results
.data
.AFS_CollData_len
;
449 if (numInt32s
!= perfInt32s
) {
450 printf("** Data size mismatch in performance collection!");
451 printf("** Expecting %u, got %u\n", perfInt32s
, numInt32s
);
455 printableTime
= ctime(&probeTime
);
456 printableTime
[strlen(printableTime
) - 1] = '\0';
457 perfP
= (struct afs_PerfStats
*)
458 (xstat_fs_Results
.data
.AFS_CollData_val
);
460 printf("AFS_XSTATSCOLL_PERF_INFO (coll %d) for FS %s\n[Probe %u, %s]\n\n",
461 xstat_fs_Results
.collectionNumber
,
462 xstat_fs_Results
.connP
->hostName
, xstat_fs_Results
.probeNum
,
465 PrintOverallPerfInfo(perfP
);
468 static char *CbCounterStrings
[] = {
474 "DeleteAllCallBacks",
475 "nFEs", "nCBs", "nblks",
478 "GSS1", "GSS2", "GSS3", "GSS4", "GSS5"
483 PrintCbCounters(void) {
484 int numInt32s
= sizeof(CbCounterStrings
)/sizeof(char *);
486 afs_int32
*val
=xstat_fs_Results
.data
.AFS_CollData_val
;
488 if (numInt32s
> xstat_fs_Results
.data
.AFS_CollData_len
)
489 numInt32s
= xstat_fs_Results
.data
.AFS_CollData_len
;
491 for (i
=0; i
<numInt32s
; i
++) {
492 printf("\t%10u %s\n", val
[i
], CbCounterStrings
[i
]);
497 /*------------------------------------------------------------------------
501 * Handler routine passed to the xstat_fs module. This handler is
502 * called immediately after a poll of one of the File Servers has
503 * taken place. All it needs to know is exported by the xstat_fs
504 * module, namely the data structure where the probe results are
515 * See above. All we do now is print out what we got.
519 *------------------------------------------------------------------------*/
524 static char rn
[] = "FS_Handler"; /*Routine name */
527 ("\n------------------------------------------------------------\n");
530 * If the probe failed, there isn't much we can do except gripe.
532 if (xstat_fs_Results
.probeOK
) {
533 printf("%s: Probe %u to File Server '%s' failed, code=%d\n", rn
,
534 xstat_fs_Results
.probeNum
, xstat_fs_Results
.connP
->hostName
,
535 xstat_fs_Results
.probeOK
);
541 int numInt32s
= xstat_fs_Results
.data
.AFS_CollData_len
;
542 afs_int32
*entry
= xstat_fs_Results
.data
.AFS_CollData_val
;
544 printf("debug: got collection number %d\n", xstat_fs_Results
.collectionNumber
);
545 printf("debug: collection data length is %d\n", numInt32s
);
546 for (i
= 0; i
< numInt32s
; i
++) {
547 printf("debug: entry %d %u\n", i
, entry
[i
]);
552 switch (xstat_fs_Results
.collectionNumber
) {
553 case AFS_XSTATSCOLL_CALL_INFO
:
557 case AFS_XSTATSCOLL_PERF_INFO
:
561 case AFS_XSTATSCOLL_FULL_PERF_INFO
:
565 case AFS_XSTATSCOLL_CBSTATS
:
570 printf("** Unknown collection: %d\n",
571 xstat_fs_Results
.collectionNumber
);
575 * Return the happy news.
581 /*------------------------------------------------------------------------
585 * Given a pointer to the list of File Servers we'll be polling
586 * (or, in fact, any list at all), compute the length of the list.
589 * struct cmd_item *a_firstItem : Ptr to first item in list.
592 * Length of the above list.
595 * Nothing interesting.
599 *------------------------------------------------------------------------*/
602 CountListItems(struct cmd_item
*a_firstItem
)
605 int list_len
; /*List length */
606 struct cmd_item
*curr_item
; /*Ptr to current item */
609 curr_item
= a_firstItem
;
616 curr_item
= curr_item
->next
;
626 /*------------------------------------------------------------------------
630 * Routine called by the command line interpreter to execute the
631 * meat of the program. We count the number of File Servers
632 * to watch, allocate enough space to remember all the connection
633 * info for them, then go for it.
637 * a_s : Ptr to the command line syntax descriptor.
640 * 0, but may exit the whole program on an error!
643 * Nothing interesting.
647 *------------------------------------------------------------------------*/
650 RunTheTest(struct cmd_syndesc
*a_s
, void *dummy
)
652 static char rn
[] = "RunTheTest"; /*Routine name */
653 int code
; /*Return code */
654 int numFSs
; /*# File Servers to monitor */
655 int numCollIDs
; /*# collections to fetch */
656 int currFS
; /*Loop index */
657 int currCollIDIdx
; /*Index of current collection ID */
658 afs_int32
*collIDP
; /*Ptr to array of collection IDs */
659 afs_int32
*currCollIDP
; /*Ptr to current collection ID */
660 struct cmd_item
*curr_item
; /*Current FS cmd line record */
661 struct sockaddr_in FSSktArray
[20]; /*File Server socket array - FIX! */
662 struct hostent
*he
; /*Host entry */
663 struct timeval tv
; /*Time structure */
664 int sleep_secs
; /*Number of seconds to sleep */
665 int initFlags
; /*Flags passed to the init fcn */
666 int waitCode
; /*Result of LWP_WaitProcess() */
667 int freq
; /*Frequency of polls */
668 int period
; /*Time in minutes of data collection */
671 * Are we doing one-shot measurements?
673 if (a_s
->parms
[P_ONESHOT
].items
!= 0)
677 * Are we doing debugging output?
679 if (a_s
->parms
[P_DEBUG
].items
!= 0)
683 * Pull out the number of File Servers to watch and the number of
684 * collections to get.
686 numFSs
= CountListItems(a_s
->parms
[P_FS_NAMES
].items
);
687 numCollIDs
= CountListItems(a_s
->parms
[P_COLL_IDS
].items
);
689 /* Get the polling frequency */
690 if (a_s
->parms
[P_FREQUENCY
].items
!= 0)
691 freq
= atoi(a_s
->parms
[P_FREQUENCY
].items
->data
);
693 freq
= 30; /* default to 30 seconds */
695 /* Get the time duration to run the tests */
696 if (a_s
->parms
[P_PERIOD
].items
!= 0)
697 period
= atoi(a_s
->parms
[P_PERIOD
].items
->data
);
699 period
= 10; /* default to 10 minutes */
703 * Fill in the socket array for each of the File Servers listed.
705 curr_item
= a_s
->parms
[P_FS_NAMES
].items
;
706 for (currFS
= 0; currFS
< numFSs
; currFS
++) {
707 FSSktArray
[currFS
].sin_family
= AF_INET
;
708 FSSktArray
[currFS
].sin_port
= htons(7000); /* FileServer port */
709 he
= hostutil_GetHostByName(curr_item
->data
);
711 fprintf(stderr
, "[%s] Can't get host info for '%s'\n", rn
,
715 memcpy(&(FSSktArray
[currFS
].sin_addr
.s_addr
), he
->h_addr
, 4);
718 * Move to the next File Server name.
720 curr_item
= curr_item
->next
;
722 } /*Get socket info for each File Server */
725 * Create and fill up the array of desired collection IDs.
728 printf("Allocating %d long(s) for coll ID\n", numCollIDs
);
731 collIDP
= calloc(numCollIDs
, sizeof(afs_int32
));
735 currCollIDP
= collIDP
;
736 curr_item
= a_s
->parms
[P_COLL_IDS
].items
;
737 for (currCollIDIdx
= 0; currCollIDIdx
< numCollIDs
; currCollIDIdx
++) {
738 *currCollIDP
= (afs_int32
) (atoi(curr_item
->data
));
740 printf("CollID at index %d is %d\n", currCollIDIdx
, *currCollIDP
);
741 curr_item
= curr_item
->next
;
746 * Crank up the File Server prober, then sit back and have fun.
748 printf("\nStarting up the xstat_fs service, ");
751 initFlags
|= XSTAT_FS_INITFLAG_DEBUGGING
;
752 printf("debugging enabled, ");
754 printf("no debugging, ");
756 initFlags
|= XSTAT_FS_INITFLAG_ONE_SHOT
;
757 printf("one-shot operation\n");
759 printf("continuous operation\n");
761 code
= xstat_fs_Init(numFSs
, /*Num servers */
762 FSSktArray
, /*File Server socket array */
763 freq
, /*Probe frequency */
764 FS_Handler
, /*Handler routine */
765 initFlags
, /*Initialization flags */
766 numCollIDs
, /*Number of collection IDs */
767 collIDP
); /*Ptr to collection ID array */
769 fprintf(stderr
, "[%s] Error returned by xstat_fs_Init: %d\n", rn
,
771 xstat_fs_Cleanup(1); /*Get rid of malloc'ed structures */
777 * One-shot operation; just wait for the collection to be done.
780 printf("[%s] Calling LWP_WaitProcess() on event %" AFS_PTR_FMT
"\n", rn
,
782 waitCode
= LWP_WaitProcess(&terminationEvent
);
784 printf("[%s] Returned from LWP_WaitProcess()\n", rn
);
788 "[%s] Error %d encountered by LWP_WaitProcess()\n",
793 * Continuous operation.
795 sleep_secs
= 60 * period
; /*length of data collection */
797 ("xstat_fs service started, main thread sleeping for %d secs.\n",
801 * Let's just fall asleep for a while, then we'll clean up.
803 tv
.tv_sec
= sleep_secs
;
805 code
= IOMGR_Select(0, /*Num fds */
806 0, /*Descriptors ready for reading */
807 0, /*Descriptors ready for writing */
808 0, /*Descriptors with exceptional conditions */
809 &tv
); /*Timeout structure */
812 "[%s] IOMGR_Select() returned non-zero value: %d\n", rn
,
818 * We're all done. Clean up, put the last nail in Rx, then
822 printf("\nYawn, main thread just woke up. Cleaning things out...\n");
824 xstat_fs_Cleanup(1); /*Get rid of malloc'ed data */
830 #include "AFS_component_version_number.c"
833 main(int argc
, char **argv
)
835 static char rn
[] = "xstat_fs_test"; /*Routine name */
836 afs_int32 code
; /*Return code */
837 struct cmd_syndesc
*ts
; /*Ptr to cmd line syntax desc */
840 * Set up the commands we understand.
842 ts
= cmd_CreateSyntax("initcmd", RunTheTest
, 0, 0, "initialize the program");
843 cmd_AddParm(ts
, "-fsname", CMD_LIST
, CMD_REQUIRED
,
844 "File Server name(s) to monitor");
845 cmd_AddParm(ts
, "-collID", CMD_LIST
, CMD_REQUIRED
,
846 "Collection(s) to fetch");
847 cmd_AddParm(ts
, "-onceonly", CMD_FLAG
, CMD_OPTIONAL
,
848 "Collect results exactly once, then quit");
849 cmd_AddParm(ts
, "-frequency", CMD_SINGLE
, CMD_OPTIONAL
,
850 "poll frequency, in seconds");
851 cmd_AddParm(ts
, "-period", CMD_SINGLE
, CMD_OPTIONAL
,
852 "data collection time, in minutes");
853 cmd_AddParm(ts
, "-debug", CMD_FLAG
, CMD_OPTIONAL
,
854 "turn on debugging output");
857 * Parse command-line switches & execute the test, then get the
860 code
= cmd_Dispatch(argc
, argv
);
862 fprintf(stderr
, "[%s] Call to cmd_Dispatch() failed; code is %d\n",