Remove the RCSID macro
[openafs.git] / src / libadmin / test / client.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * This file implements the client related funtions for afscp
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17
18 #include "client.h"
19 #include <afs/cellconfig.h>
20 #include <afs/bosint.h>
21 #include <rx/rxstat.h>
22 #include <afs/afsint.h>
23 #define FSINT_COMMON_XG
24 #include <afs/afscbint.h>
25 #include <afs/kauth.h>
26 #include <afs/kautils.h>
27 #include <afs/ptint.h>
28 #include <afs/ptserver.h>
29 #include <afs/vldbint.h>
30 #include <afs/volint.h>
31 #include <afs/volser.h>
32 #include <ubik.h>
33 #include <ubik_int.h>
34 #ifdef AFS_NT40_ENV
35 #include <winsock2.h>
36 #include <pthread.h>
37 #endif
38
39 /* These aren't coming from a header, currently, so they must stay here. 
40    Fix elsewhere, or leave alone. */
41 extern int RXSTATS_RetrieveProcessRPCStats();
42 extern int RXSTATS_RetrievePeerRPCStats();
43 extern int RXSTATS_QueryProcessRPCStats();
44 extern int RXSTATS_QueryPeerRPCStats();
45 extern int RXSTATS_EnableProcessRPCStats();
46 extern int RXSTATS_EnablePeerRPCStats();
47 extern int RXSTATS_DisableProcessRPCStats();
48 extern int RXSTATS_DisablePeerRPCStats();
49 extern int RXSTATS_ClearProcessRPCStats();
50 extern int RXSTATS_ClearPeerRPCStats();
51
52 /*
53  * This structure stores the client and server function lists.
54  * This is kept separate from the actual interface definitions
55  * since an rpc interface can be offered by several servers
56  * (e.g. ubik and rxstat)
57  *
58  * The purpose of these functions is to allow a mapping from interfaceId
59  * to text representations of server process names and function names.
60  */
61
62 typedef struct {
63     const char **functionList;
64     size_t functionListLen;
65 } interface_function_list_t, *interface_function_list_p;
66
67 #ifdef AFS_NT40_ENV
68
69 /*
70  * On NT, you cannot define an array of character pointers in a dll
71  * and then access this array outside the dll via a global initialization
72  * because the msvc compiler will complain that the initializer is not
73  * a constant (i.e. C2099: initializer is not a constant).  This is because
74  * the dllimport and dllexport c language extensions cause references
75  * to the character array to go through another level of indirection -
76  * and this indirection is unknown at compilation time.
77  *
78  * To get around this problem I hand initialize this array on NT only
79  */
80
81 static interface_function_list_t afs_server;
82 static interface_function_list_t afscb_server;
83 static interface_function_list_t bos_server;
84 static interface_function_list_t kauth_kaa_server;
85 static interface_function_list_t kauth_kam_server;
86 static interface_function_list_t kauth_kat_server;
87 static interface_function_list_t pts_server;
88 static interface_function_list_t rxstat_server;
89 static interface_function_list_t ubik_disk_server;
90 static interface_function_list_t ubik_vote_server;
91 static interface_function_list_t vl_server;
92 static interface_function_list_t vol_server;
93 static pthread_once_t pthread_func_list_once = PTHREAD_ONCE_INIT;
94 static int pthread_func_list_done;
95
96 static void
97 cr_list(void)
98 {
99     afs_server.functionList = RXAFS_function_names;
100     afs_server.functionListLen = RXAFS_NO_OF_STAT_FUNCS;
101     afscb_server.functionList = RXAFSCB_function_names;
102     afscb_server.functionListLen = RXAFSCB_NO_OF_STAT_FUNCS;
103     bos_server.functionList = BOZO_function_names;
104     bos_server.functionListLen = BOZO_NO_OF_STAT_FUNCS;
105     kauth_kaa_server.functionList = KAA_function_names;
106     kauth_kaa_server.functionListLen = KAA_NO_OF_STAT_FUNCS;
107     kauth_kam_server.functionList = KAM_function_names;
108     kauth_kam_server.functionListLen = KAM_NO_OF_STAT_FUNCS;
109     kauth_kat_server.functionList = KAT_function_names;
110     kauth_kat_server.functionListLen = KAT_NO_OF_STAT_FUNCS;
111     pts_server.functionList = PR_function_names;
112     pts_server.functionListLen = PR_NO_OF_STAT_FUNCS;
113     rxstat_server.functionList = RXSTATS_function_names;
114     rxstat_server.functionListLen = RXSTATS_NO_OF_STAT_FUNCS;
115     ubik_disk_server.functionList = DISK_function_names;
116     ubik_disk_server.functionListLen = DISK_NO_OF_STAT_FUNCS;
117     ubik_vote_server.functionList = VOTE_function_names;
118     ubik_vote_server.functionListLen = VOTE_NO_OF_STAT_FUNCS;
119     vl_server.functionList = VL_function_names;
120     vl_server.functionListLen = VL_NO_OF_STAT_FUNCS;
121     vol_server.functionList = AFSVolfunction_names;
122     vol_server.functionListLen = AFSVolNO_OF_STAT_FUNCS;
123     pthread_func_list_done = 1;
124 }
125
126 #else
127
128 static interface_function_list_t afs_server = {
129     RXAFS_function_names,
130     RXAFS_NO_OF_STAT_FUNCS
131 };
132
133 static interface_function_list_t afscb_server = {
134     RXAFSCB_function_names,
135     RXAFSCB_NO_OF_STAT_FUNCS
136 };
137
138 static interface_function_list_t bos_server = {
139     BOZO_function_names,
140     BOZO_NO_OF_STAT_FUNCS
141 };
142
143 static interface_function_list_t kauth_kaa_server = {
144     KAA_function_names,
145     KAA_NO_OF_STAT_FUNCS
146 };
147
148 static interface_function_list_t kauth_kam_server = {
149     KAM_function_names,
150     KAM_NO_OF_STAT_FUNCS
151 };
152
153 static interface_function_list_t kauth_kat_server = {
154     KAT_function_names,
155     KAT_NO_OF_STAT_FUNCS
156 };
157
158 static interface_function_list_t pts_server = {
159     PR_function_names,
160     PR_NO_OF_STAT_FUNCS
161 };
162
163 static interface_function_list_t rxstat_server = {
164     RXSTATS_function_names,
165     RXSTATS_NO_OF_STAT_FUNCS
166 };
167
168 static interface_function_list_t ubik_disk_server = {
169     DISK_function_names,
170     DISK_NO_OF_STAT_FUNCS,
171 };
172
173 static interface_function_list_t ubik_vote_server = {
174     VOTE_function_names,
175     VOTE_NO_OF_STAT_FUNCS,
176 };
177
178 static interface_function_list_t vl_server = {
179     VL_function_names,
180     VL_NO_OF_STAT_FUNCS
181 };
182
183 static interface_function_list_t vol_server = {
184     AFSVolfunction_names,
185     AFSVolNO_OF_STAT_FUNCS
186 };
187
188 #endif /* AFS_NT40_ENV */
189
190 static interface_function_list_t unknown_server = {
191     0,
192     0
193 };
194
195 typedef struct {
196     afs_uint32 interfaceId;
197     const char *interfaceName;
198     interface_function_list_p functionList;
199 } interface_t, *interface_p;
200
201 interface_t int_list[] = {
202     {RXAFS_STATINDEX,
203      "file server",
204      &afs_server},
205
206     {RXSTATS_STATINDEX,
207      "rx stats",
208      &rxstat_server},
209
210     {RXAFSCB_STATINDEX,
211      "cache manager",
212      &afscb_server},
213
214     {PR_STATINDEX,
215      "pts server",
216      &pts_server},
217
218     {DISK_STATINDEX,
219      "ubik disk server",
220      &ubik_disk_server},
221
222     {VOTE_STATINDEX,
223      "ubik vote server",
224      &ubik_vote_server},
225
226     {VL_STATINDEX,
227      "vldb server",
228      &vl_server},
229
230     {AFSVolSTATINDEX,
231      "vol server",
232      &vol_server},
233
234     {BOZO_STATINDEX,
235      "bos server",
236      &bos_server},
237
238     {KAA_STATINDEX,
239      "kas kaa server",
240      &kauth_kaa_server},
241
242     {KAM_STATINDEX,
243      "kas kam server",
244      &kauth_kam_server},
245
246     {KAT_STATINDEX,
247      "kas kat server",
248      &kauth_kat_server},
249
250     /*
251      * Note the code below assumes that the following entry is the last entry
252      * in this array
253      */
254
255     {0, "unknown", &unknown_server}
256 };
257
258 /*
259  * Utility functions
260  */
261
262 int
263 DoClientLocalCellGet(struct cmd_syndesc *as, void *arock)
264 {
265     afs_status_t st = 0;
266     char cellName[MAXCELLCHARS];
267
268     if (!afsclient_LocalCellGet(cellName, &st)) {
269         ERR_ST_EXT("afsclient_LocalCellGet", st);
270     }
271
272     printf("This machine belongs to cell: %s\n", cellName);
273
274     return 0;
275 }
276
277 int
278 DoClientMountPointCreate(struct cmd_syndesc *as, void *arock)
279 {
280     typedef enum { DIRECTORY, VOLUME, READWRITE,
281         CHECK
282     } DoClientMountPointCreate_parm_t;
283     afs_status_t st = 0;
284     const char *directory = NULL;
285     const char *volume = NULL;
286     vol_type_t vol_type = READ_ONLY;
287     vol_check_t vol_check = DONT_CHECK_VOLUME;
288
289     if (as->parms[DIRECTORY].items) {
290         directory = as->parms[DIRECTORY].items->data;
291     }
292
293     if (as->parms[VOLUME].items) {
294         volume = as->parms[VOLUME].items->data;
295     }
296
297     if (as->parms[READWRITE].items) {
298         vol_type = READ_WRITE;
299     }
300
301     if (as->parms[CHECK].items) {
302         vol_check = CHECK_VOLUME;
303     }
304
305     if (!afsclient_MountPointCreate
306         (cellHandle, directory, volume, vol_type, vol_check, &st)) {
307         ERR_ST_EXT("afsclient_MountPointCreate", st);
308     }
309
310     return 0;
311 }
312
313 static void
314 Print_afs_serverEntry_p(afs_serverEntry_p serv, const char *prefix)
315 {
316     int i = 0;
317
318     printf("%sInformation for server %s\n", prefix, serv->serverName);
319     if (serv->serverType & DATABASE_SERVER) {
320         printf("%s\tIt is a database server\n", prefix);
321     }
322     if (serv->serverType & FILE_SERVER) {
323         printf("%s\tIt is a file server\n", prefix);
324     }
325     printf("%s\tServer addresses:%s\n", prefix, serv->serverName);
326     while (serv->serverAddress[i] != 0) {
327         printf("\t\t%s%x\n", prefix, serv->serverAddress[i++]);
328     }
329 }
330
331 int
332 DoClientAFSServerGet(struct cmd_syndesc *as, void *arock)
333 {
334     typedef enum { SERVER } DoClientAFSServerGet_parm_t;
335     afs_status_t st = 0;
336     const char *server = NULL;
337     afs_serverEntry_t entry;
338
339     if (as->parms[SERVER].items) {
340         server = as->parms[SERVER].items->data;
341     }
342
343     if (!afsclient_AFSServerGet(cellHandle, server, &entry, &st)) {
344         ERR_ST_EXT("afsclient_AFSServerGet", st);
345     }
346
347     Print_afs_serverEntry_p(&entry, "");
348
349     return 0;
350 }
351
352 int
353 DoClientAFSServerList(struct cmd_syndesc *as, void *arock)
354 {
355     afs_status_t st = 0;
356     afs_serverEntry_t entry;
357     void *iter = NULL;
358
359     if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &st)) {
360         ERR_ST_EXT("afsclient_AFSServerGetBegin", st);
361     }
362
363     while (afsclient_AFSServerGetNext(iter, &entry, &st)) {
364         Print_afs_serverEntry_p(&entry, "");
365     }
366
367     if (st != ADMITERATORDONE) {
368         ERR_ST_EXT("afsclient_AFSServerGetNext", st);
369     }
370
371     if (!afsclient_AFSServerGetDone(iter, &st)) {
372         ERR_ST_EXT("afsclient_AFSServerGetDone", st);
373     }
374
375
376     return 0;
377 }
378
379 static void
380 Print_afs_RPCStatsState_p(afs_RPCStatsState_p state, const char *prefix)
381 {
382     printf("%sThe rpc stats state is: ", prefix);
383     switch (*state) {
384     case AFS_RPC_STATS_DISABLED:
385         printf("disabled\n");
386         break;
387     case AFS_RPC_STATS_ENABLED:
388         printf("enabled\n");
389         break;
390     }
391 }
392
393 typedef struct {
394     const char *tag;
395     afs_stat_source_t value;
396 } afs_type_map_t, *afs_type_map_p;
397
398 static afs_type_map_t map[] = {
399     {"bosserver", AFS_BOSSERVER},
400     {"fileserver", AFS_FILESERVER},
401     {"kaserver", AFS_KASERVER},
402     {"ptserver", AFS_PTSERVER},
403     {"volserver", AFS_VOLSERVER},
404     {"vlserver", AFS_VLSERVER},
405     {"client", AFS_CLIENT},
406     {0, 0}
407 };
408
409 static int
410 GetStatPortFromString(const char *type, int *port)
411 {
412     char *end;
413     long tport;
414
415     errno = 0;
416     tport = strtol(type, &end, 0);
417     if (tport == 0 || end == type || *end != '\0') {
418         return 0;
419     }
420
421     *port = (int)tport;
422     return 1;
423 }
424
425 static int
426 GetStatSourceFromString(const char *type, afs_stat_source_t * src, int *port)
427 {
428     int i;
429     size_t type_len = strlen(type);
430
431     for (i = 0; (map[i].tag) && strncasecmp(type, map[i].tag, type_len); i++);
432
433     if (map[i].tag == 0) {
434         /*
435          * Try to convert string to port number
436          */
437         if (GetStatPortFromString(type, port)) {
438             return 0;
439         }
440
441         fprintf(stderr,
442                 "couldn't convert server to type, try one of the "
443                 "following:\n");
444         for (i = 0; map[i].tag; i++) {
445             fprintf(stderr, "%s ", map[i].tag);
446         }
447
448         ERR_EXT("");
449     } else {
450         *src = map[i].value;
451         return 1;
452     }
453 }
454
455 typedef enum {
456     AFS_PEER_STATS,
457     AFS_PROCESS_STATS
458 } afs_stat_type_t, *afs_stat_type_p;
459
460 static afs_stat_type_t
461 GetStatTypeFromString(const char *type)
462 {
463     afs_stat_type_t rc;
464
465     if (!strcmp(type, "peer")) {
466         rc = AFS_PEER_STATS;
467     } else if (!strcmp(type, "process")) {
468         rc = AFS_PROCESS_STATS;
469     } else {
470         ERR_EXT("stat_type must be process or peer");
471     }
472
473     return rc;
474 }
475
476 int
477 DoClientRPCStatsStateGet(struct cmd_syndesc *as, void *arock)
478 {
479     typedef enum { SERVER, PROCESS,
480         STAT_TYPE
481     } DoClientRPCStatsStateGet_parm_t;
482     afs_status_t st = 0;
483     struct rx_connection *conn;
484     int servAddr = 0;
485     afs_stat_source_t type;
486     int srvrPort;
487     int typeIsValid = 0;
488     afs_stat_type_t which = 0;
489     afs_RPCStatsState_t state;
490
491     if (as->parms[PROCESS].items) {
492         typeIsValid =
493             GetStatSourceFromString(as->parms[PROCESS].items->data, &type,
494                                     &srvrPort);
495     }
496
497     if (as->parms[STAT_TYPE].items) {
498         which = GetStatTypeFromString(as->parms[STAT_TYPE].items->data);
499     }
500
501     if (as->parms[SERVER].items) {
502         if (typeIsValid) {
503             if (!afsclient_RPCStatOpen
504                 (cellHandle, as->parms[SERVER].items->data, type, &conn,
505                  &st)) {
506                 ERR_ST_EXT("afsclient_RPCStatOpen", st);
507             }
508         } else {
509             if (!afsclient_RPCStatOpenPort
510                 (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
511                  &st)) {
512                 ERR_ST_EXT("afsclient_RPCStatOpenPort", st);
513             }
514         }
515     }
516
517     if (which == AFS_PEER_STATS) {
518         if (!util_RPCStatsStateGet
519             (conn, RXSTATS_QueryPeerRPCStats, &state, &st)) {
520             ERR_ST_EXT("util_RPCStatsStateGet", st);
521         }
522     } else {
523         if (!util_RPCStatsStateGet
524             (conn, RXSTATS_QueryProcessRPCStats, &state, &st)) {
525             ERR_ST_EXT("util_RPCStatsStateGet", st);
526         }
527     }
528
529     Print_afs_RPCStatsState_p(&state, "");
530
531     afsclient_RPCStatClose(conn, 0);
532
533     return 0;
534 }
535
536 int
537 DoClientRPCStatsStateEnable(struct cmd_syndesc *as, void *arock)
538 {
539     typedef enum { SERVER, PROCESS, STAT_TYPE } DoClientRPCStatsEnable_parm_t;
540     afs_status_t st = 0;
541     struct rx_connection *conn;
542     int servAddr = 0;
543     afs_stat_source_t type;
544     int srvrPort;
545     int typeIsValid = 0;
546     afs_stat_type_t which = 0;
547
548     if (as->parms[PROCESS].items) {
549         typeIsValid =
550             GetStatSourceFromString(as->parms[PROCESS].items->data, &type,
551                                     &srvrPort);
552     }
553
554     if (as->parms[STAT_TYPE].items) {
555         which = GetStatTypeFromString(as->parms[STAT_TYPE].items->data);
556     }
557
558     if (as->parms[SERVER].items) {
559         if (typeIsValid) {
560             if (!afsclient_RPCStatOpen
561                 (cellHandle, as->parms[SERVER].items->data, type, &conn,
562                  &st)) {
563                 ERR_ST_EXT("afsclient_RPCStatOpen", st);
564             }
565         } else {
566             if (!afsclient_RPCStatOpenPort
567                 (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
568                  &st)) {
569                 ERR_ST_EXT("afsclient_RPCStatOpenPort", st);
570             }
571         }
572     }
573
574     if (which == AFS_PEER_STATS) {
575         if (!util_RPCStatsStateEnable(conn, RXSTATS_EnablePeerRPCStats, &st)) {
576             ERR_ST_EXT("util_RPCStatsStateEnable", st);
577         }
578     } else {
579         if (!util_RPCStatsStateEnable
580             (conn, RXSTATS_EnableProcessRPCStats, &st)) {
581             ERR_ST_EXT("util_RPCStatsStateEnable", st);
582         }
583     }
584
585     afsclient_RPCStatClose(conn, 0);
586
587     return 0;
588 }
589
590 int
591 DoClientRPCStatsStateDisable(struct cmd_syndesc *as, void *arock)
592 {
593     typedef enum { SERVER, PROCESS,
594         STAT_TYPE
595     } DoClientRPCStatsDisable_parm_t;
596     afs_status_t st = 0;
597     struct rx_connection *conn;
598     int servAddr = 0;
599     afs_stat_source_t type;
600     int srvrPort;
601     int typeIsValid = 0;
602     afs_stat_type_t which = 0;
603
604     if (as->parms[PROCESS].items) {
605         typeIsValid =
606             GetStatSourceFromString(as->parms[PROCESS].items->data, &type,
607                                     &srvrPort);
608     }
609
610     if (as->parms[STAT_TYPE].items) {
611         which = GetStatTypeFromString(as->parms[STAT_TYPE].items->data);
612     }
613
614     if (as->parms[SERVER].items) {
615         if (typeIsValid) {
616             if (!afsclient_RPCStatOpen
617                 (cellHandle, as->parms[SERVER].items->data, type, &conn,
618                  &st)) {
619                 ERR_ST_EXT("afsclient_RPCStatOpen", st);
620             }
621         } else {
622             if (!afsclient_RPCStatOpenPort
623                 (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
624                  &st)) {
625                 ERR_ST_EXT("afsclient_RPCStatOpenPort", st);
626             }
627         }
628     }
629
630     if (which == AFS_PEER_STATS) {
631         if (!util_RPCStatsStateDisable
632             (conn, RXSTATS_DisablePeerRPCStats, &st)) {
633             ERR_ST_EXT("util_RPCStatsStateDisable", st);
634         }
635     } else {
636         if (!util_RPCStatsStateDisable
637             (conn, RXSTATS_DisableProcessRPCStats, &st)) {
638             ERR_ST_EXT("util_RPCStatsStateDisable", st);
639         }
640     }
641
642     afsclient_RPCStatClose(conn, 0);
643
644     return 0;
645 }
646
647 static void
648 Print_afs_RPCStats_p(afs_RPCStats_p stat, interface_function_list_p f_list,
649                      const char *prefix)
650 {
651     afs_int32 index = stat->s.stats_v1.func_index;
652
653     if (index > ((afs_int32) f_list->functionListLen - 1)) {
654         printf("%sUnknown function ", prefix);
655     } else {
656         printf("%s%s ", prefix,
657                f_list->functionList[stat->s.stats_v1.func_index]);
658     }
659
660     if (!hiszero(stat->s.stats_v1.invocations)) {
661         printf("%sinvoc (%u.%u) bytes_sent (%u.%u) bytes_rcvd (%u.%u)\n",
662                prefix, hgethi(stat->s.stats_v1.invocations),
663                hgetlo(stat->s.stats_v1.invocations),
664                hgethi(stat->s.stats_v1.bytes_sent),
665                hgetlo(stat->s.stats_v1.bytes_sent),
666                hgethi(stat->s.stats_v1.bytes_rcvd),
667                hgetlo(stat->s.stats_v1.bytes_rcvd)
668             );
669         printf("\tqsum %d.%06d\tqsqr %d.%06d"
670                "\tqmin %d.%06d\tqmax %d.%06d\n",
671                stat->s.stats_v1.queue_time_sum.sec,
672                stat->s.stats_v1.queue_time_sum.usec,
673                stat->s.stats_v1.queue_time_sum_sqr.sec,
674                stat->s.stats_v1.queue_time_sum_sqr.usec,
675                stat->s.stats_v1.queue_time_min.sec,
676                stat->s.stats_v1.queue_time_min.usec,
677                stat->s.stats_v1.queue_time_max.sec,
678                stat->s.stats_v1.queue_time_max.usec);
679         printf("\txsum %d.%06d\txsqr %d.%06d"
680                "\txmin %d.%06d\txmax %d.%06d\n",
681                stat->s.stats_v1.execution_time_sum.sec,
682                stat->s.stats_v1.execution_time_sum.usec,
683                stat->s.stats_v1.execution_time_sum_sqr.sec,
684                stat->s.stats_v1.execution_time_sum_sqr.usec,
685                stat->s.stats_v1.execution_time_min.sec,
686                stat->s.stats_v1.execution_time_min.usec,
687                stat->s.stats_v1.execution_time_max.sec,
688                stat->s.stats_v1.execution_time_max.usec);
689     } else {
690         printf("never invoked\n");
691     }
692 }
693
694 int
695 DoClientRPCStatsList(struct cmd_syndesc *as, void *arock)
696 {
697     typedef enum { SERVER, PROCESS, STAT_TYPE } DoClientRPCStatsList_parm_t;
698     afs_status_t st = 0;
699     struct rx_connection *conn;
700     int servAddr = 0;
701     afs_stat_source_t type;
702     int srvrPort;
703     int typeIsValid = 0;
704     afs_stat_type_t which = 0;
705     afs_RPCStats_t stats;
706     void *iter;
707     int i = 0;
708
709 #ifdef AFS_NT40_ENV
710     (pthread_func_list_done
711      || pthread_once(&pthread_func_list_once, cr_list));
712 #endif
713
714     if (as->parms[PROCESS].items) {
715         typeIsValid =
716             GetStatSourceFromString(as->parms[PROCESS].items->data, &type,
717                                     &srvrPort);
718     }
719
720     if (as->parms[STAT_TYPE].items) {
721         which = GetStatTypeFromString(as->parms[STAT_TYPE].items->data);
722     }
723
724     if (as->parms[SERVER].items) {
725         if (typeIsValid) {
726             if (!afsclient_RPCStatOpen
727                 (cellHandle, as->parms[SERVER].items->data, type, &conn,
728                  &st)) {
729                 ERR_ST_EXT("afsclient_RPCStatOpen", st);
730             }
731         } else {
732             if (!afsclient_RPCStatOpenPort
733                 (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
734                  &st)) {
735                 ERR_ST_EXT("afsclient_RPCStatOpenPort", st);
736             }
737         }
738     }
739
740     if (which == AFS_PEER_STATS) {
741         if (!util_RPCStatsGetBegin
742             (conn, RXSTATS_RetrievePeerRPCStats, &iter, &st)) {
743             ERR_ST_EXT("util_RPCStatsGetBegin", st);
744         }
745     } else {
746         if (!util_RPCStatsGetBegin
747             (conn, RXSTATS_RetrieveProcessRPCStats, &iter, &st)) {
748             ERR_ST_EXT("util_RPCStatsGetBegin", st);
749         }
750     }
751
752     printf("Listing rpc stats at server %s process %s:\n",
753            as->parms[SERVER].items->data, as->parms[PROCESS].items->data);
754
755     while (util_RPCStatsGetNext(iter, &stats, &st)) {
756
757         /*
758          * Print a new heading for each stat collection
759          */
760
761         if (stats.s.stats_v1.func_index == 0) {
762
763             printf("\n\n");
764
765             /*
766              * Look up the interface in our list
767              */
768
769             for (i = 0; i < ((sizeof(int_list) - 1) / sizeof(interface_t));
770                  i++) {
771                 if (stats.s.stats_v1.interfaceId == int_list[i].interfaceId) {
772                     break;
773                 }
774             }
775
776             /*
777              * Print out a meaningful header for each stat collection
778              */
779
780             if (which == AFS_PEER_STATS) {
781                 struct in_addr ina;
782                 ina.s_addr = htonl(stats.s.stats_v1.remote_peer);
783
784                 printf("%s stats for remote peer located at %s port %u "
785                        "%s %s as a %s via the %s interface\n",
786                        as->parms[PROCESS].items->data, inet_ntoa(ina),
787                        stats.s.stats_v1.remote_port,
788                        ((stats.s.stats_v1.
789                          remote_is_server) ? "accessed by" : "accessing"),
790                        as->parms[PROCESS].items->data,
791                        ((stats.s.stats_v1.
792                          remote_is_server) ? "client" : "server"),
793                        int_list[i].interfaceName);
794             } else {
795                 printf("%s stats for the %s interface " "accessed as a %s\n",
796                        as->parms[PROCESS].items->data,
797                        int_list[i].interfaceName,
798                        ((stats.s.stats_v1.
799                          remote_is_server) ? "client" : "server")
800                     );
801             }
802         }
803         Print_afs_RPCStats_p(&stats, int_list[i].functionList, "    ");
804     }
805
806     if (st != ADMITERATORDONE) {
807         ERR_ST_EXT("util_RPCStatsGetNext", st);
808     }
809
810     if (!util_RPCStatsGetDone(iter, &st)) {
811         ERR_ST_EXT("util_RPCStatsGetDone", st);
812     }
813
814     afsclient_RPCStatClose(conn, 0);
815
816     return 0;
817 }
818
819 int
820 DoClientRPCStatsClear(struct cmd_syndesc *as, void *arock)
821 {
822     typedef enum { SERVER, PROCESS, STAT_TYPE, CLEAR_ALL, CLEAR_INVOCATIONS,
823         CLEAR_BYTES_SENT, CLEAR_BYTES_RCVD,
824         CLEAR_QUEUE_TIME_SUM, CLEAR_QUEUE_TIME_SQUARE,
825         CLEAR_QUEUE_TIME_MIN, CLEAR_QUEUE_TIME_MAX,
826         CLEAR_EXEC_TIME_SUM, CLEAR_EXEC_TIME_SQUARE,
827         CLEAR_EXEC_TIME_MIN, CLEAR_EXEC_TIME_MAX
828     } DoClientRPCStatsClear_parm_t;
829     afs_status_t st = 0;
830     struct rx_connection *conn;
831     int servAddr = 0;
832     afs_stat_source_t type;
833     int srvrPort;
834     int typeIsValid = 0;
835     afs_stat_type_t which = 0;
836     afs_RPCStatsClearFlag_t flag = 0;
837     int seen_all = 0;
838     int seen_any = 0;
839
840     if (as->parms[PROCESS].items) {
841         typeIsValid =
842             GetStatSourceFromString(as->parms[PROCESS].items->data, &type,
843                                     &srvrPort);
844     }
845
846     if (as->parms[STAT_TYPE].items) {
847         which = GetStatTypeFromString(as->parms[STAT_TYPE].items->data);
848     }
849
850     if (as->parms[SERVER].items) {
851         if (typeIsValid) {
852             if (!afsclient_RPCStatOpen
853                 (cellHandle, as->parms[SERVER].items->data, type, &conn,
854                  &st)) {
855                 ERR_ST_EXT("afsclient_RPCStatOpen", st);
856             }
857         } else {
858             if (!afsclient_RPCStatOpenPort
859                 (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
860                  &st)) {
861                 ERR_ST_EXT("afsclient_RPCStatOpenPort", st);
862             }
863         }
864     }
865
866     if (as->parms[CLEAR_ALL].items) {
867         seen_all = 1;
868         seen_any = 1;
869         flag = AFS_RX_STATS_CLEAR_ALL;
870     }
871
872     if (as->parms[CLEAR_INVOCATIONS].items) {
873         if (seen_all) {
874             ERR_EXT("cannot specify additional flags when "
875                     "specifying clear_all");
876         }
877         seen_any = 1;
878         flag |= AFS_RX_STATS_CLEAR_INVOCATIONS;
879     }
880
881     if (as->parms[CLEAR_BYTES_SENT].items) {
882         if (seen_all) {
883             ERR_EXT("cannot specify additional flags when "
884                     "specifying clear_all");
885         }
886         seen_any = 1;
887         flag |= AFS_RX_STATS_CLEAR_BYTES_SENT;
888     }
889
890     if (as->parms[CLEAR_BYTES_RCVD].items) {
891         if (seen_all) {
892             ERR_EXT("cannot specify additional flags when "
893                     "specifying clear_all");
894         }
895         seen_any = 1;
896         flag |= AFS_RX_STATS_CLEAR_BYTES_RCVD;
897     }
898
899     if (as->parms[CLEAR_QUEUE_TIME_SUM].items) {
900         if (seen_all) {
901             ERR_EXT("cannot specify additional flags when "
902                     "specifying clear_all");
903         }
904         seen_any = 1;
905         flag |= AFS_RX_STATS_CLEAR_QUEUE_TIME_SUM;
906     }
907
908     if (as->parms[CLEAR_QUEUE_TIME_SQUARE].items) {
909         if (seen_all) {
910             ERR_EXT("cannot specify additional flags when "
911                     "specifying clear_all");
912         }
913         seen_any = 1;
914         flag |= AFS_RX_STATS_CLEAR_QUEUE_TIME_SQUARE;
915     }
916
917     if (as->parms[CLEAR_QUEUE_TIME_MIN].items) {
918         if (seen_all) {
919             ERR_EXT("cannot specify additional flags when "
920                     "specifying clear_all");
921         }
922         seen_any = 1;
923         flag |= AFS_RX_STATS_CLEAR_QUEUE_TIME_MIN;
924     }
925
926     if (as->parms[CLEAR_QUEUE_TIME_MAX].items) {
927         if (seen_all) {
928             ERR_EXT("cannot specify additional flags when "
929                     "specifying clear_all");
930         }
931         seen_any = 1;
932         flag |= AFS_RX_STATS_CLEAR_QUEUE_TIME_MAX;
933     }
934
935     if (as->parms[CLEAR_EXEC_TIME_SUM].items) {
936         if (seen_all) {
937             ERR_EXT("cannot specify additional flags when "
938                     "specifying clear_all");
939         }
940         seen_any = 1;
941         flag |= AFS_RX_STATS_CLEAR_EXEC_TIME_SUM;
942     }
943
944     if (as->parms[CLEAR_EXEC_TIME_SQUARE].items) {
945         if (seen_all) {
946             ERR_EXT("cannot specify additional flags when "
947                     "specifying clear_all");
948         }
949         seen_any = 1;
950         flag |= AFS_RX_STATS_CLEAR_EXEC_TIME_SQUARE;
951     }
952
953     if (as->parms[CLEAR_EXEC_TIME_MIN].items) {
954         if (seen_all) {
955             ERR_EXT("cannot specify additional flags when "
956                     "specifying clear_all");
957         }
958         seen_any = 1;
959         flag |= AFS_RX_STATS_CLEAR_EXEC_TIME_MIN;
960     }
961
962     if (as->parms[CLEAR_EXEC_TIME_MAX].items) {
963         if (seen_all) {
964             ERR_EXT("cannot specify additional flags when "
965                     "specifying clear_all");
966         }
967         seen_any = 1;
968         flag |= AFS_RX_STATS_CLEAR_EXEC_TIME_MAX;
969     }
970
971     if (!seen_any) {
972         ERR_EXT("you must specify something to clear");
973     }
974
975     if (which == AFS_PEER_STATS) {
976         if (!util_RPCStatsClear(conn, RXSTATS_ClearPeerRPCStats, flag, &st)) {
977             ERR_ST_EXT("util_RPCStatsClear", st);
978         }
979     } else {
980         if (!util_RPCStatsClear
981             (conn, RXSTATS_ClearProcessRPCStats, flag, &st)) {
982             ERR_ST_EXT("util_RPCStatsClear", st);
983         }
984     }
985
986     afsclient_RPCStatClose(conn, 0);
987
988     return 0;
989 }
990
991 int
992 DoClientRPCStatsVersionGet(struct cmd_syndesc *as, void *arock)
993 {
994     typedef enum { SERVER, PROCESS } DoClientRPCStatsVersionGet_parm_t;
995     afs_status_t st = 0;
996     struct rx_connection *conn;
997     afs_stat_source_t type;
998     int servAddr = 0;
999     int srvrPort;
1000     int typeIsValid = 0;
1001     afs_RPCStatsVersion_t version;
1002
1003     if (as->parms[PROCESS].items) {
1004         typeIsValid =
1005             GetStatSourceFromString(as->parms[PROCESS].items->data, &type,
1006                                     &srvrPort);
1007     }
1008
1009     if (as->parms[SERVER].items) {
1010         if (typeIsValid) {
1011             if (!afsclient_RPCStatOpen
1012                 (cellHandle, as->parms[SERVER].items->data, type, &conn,
1013                  &st)) {
1014                 ERR_ST_EXT("afsclient_RPCStatOpen", st);
1015             }
1016         } else {
1017             if (!afsclient_RPCStatOpenPort
1018                 (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
1019                  &st)) {
1020                 ERR_ST_EXT("afsclient_RPCStatOpenPort", st);
1021             }
1022         }
1023     }
1024
1025     if (!util_RPCStatsVersionGet(conn, &version, &st)) {
1026         ERR_ST_EXT("util_RPCStatsVersionGet", st);
1027     }
1028
1029     printf("the rpc stat version number is %u\n", version);
1030
1031     afsclient_RPCStatClose(conn, 0);
1032
1033     return 0;
1034 }
1035
1036 static void
1037 Print_afs_CMServerPref_p(afs_CMServerPref_p pref)
1038 {
1039     afs_uint32 taddr;
1040
1041     taddr = pref->ipAddr;
1042     printf("%d.%d.%d.%d\t\t\t%d\n", (taddr >> 24) & 0xff,
1043            (taddr >> 16) & 0xff, (taddr >> 8) & 0xff, taddr & 0xff,
1044            pref->ipRank);
1045 }
1046
1047 int
1048 DoClientCMGetServerPrefs(struct cmd_syndesc *as, void *arock)
1049 {
1050     afs_status_t st = 0;
1051     typedef enum { SERVER, PORT } DoClientCMGetServerPrefs_parm_t;
1052     struct rx_connection *conn;
1053     int servAddr = 0;
1054     int srvrPort = AFSCONF_CALLBACKPORT;
1055     afs_CMServerPref_t prefs;
1056     void *iter;
1057
1058 #ifdef AFS_NT40_ENV
1059     (pthread_func_list_done
1060      || pthread_once(&pthread_func_list_once, cr_list));
1061 #endif
1062
1063     if (as->parms[PORT].items) {
1064         if (!GetStatPortFromString(as->parms[PORT].items->data, &srvrPort)) {
1065             ERR_EXT("Couldn't undertand port number");
1066         }
1067     }
1068
1069     if (as->parms[SERVER].items) {
1070         if (!afsclient_CMStatOpenPort
1071             (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
1072              &st)) {
1073             ERR_ST_EXT("afsclient_CMStatOpenPort", st);
1074         }
1075     }
1076
1077     if (!util_CMGetServerPrefsBegin(conn, &iter, &st)) {
1078         ERR_ST_EXT("util_CMGetServerPrefsBegin", st);
1079     }
1080
1081     printf("Listing CellServDB for %s at port %s:\n",
1082            as->parms[SERVER].items->data, as->parms[PORT].items->data);
1083
1084     while (util_CMGetServerPrefsNext(iter, &prefs, &st)) {
1085
1086         Print_afs_CMServerPref_p(&prefs);
1087     }
1088
1089     if (st != ADMITERATORDONE) {
1090         ERR_ST_EXT("util_CMGetServerPrefsNext", st);
1091     }
1092
1093     if (!util_CMGetServerPrefsDone(iter, &st)) {
1094         ERR_ST_EXT("util_CMGetServerPrefsDone", st);
1095     }
1096
1097     afsclient_CMStatClose(conn, 0);
1098
1099     return 0;
1100 }
1101
1102 static void
1103 Print_afs_CMListCell_p(afs_CMListCell_p cellInfo)
1104 {
1105     int i;
1106     afs_uint32 taddr;
1107
1108     printf("Cell %s on hosts", cellInfo->cellname);
1109     for (i = 0; i < UTIL_MAX_CELL_HOSTS && cellInfo->serverAddr[i]; i++) {
1110         taddr = cellInfo->serverAddr[i];
1111         printf(" %d.%d.%d.%d", (taddr >> 24) & 0xff, (taddr >> 16) & 0xff,
1112                (taddr >> 8) & 0xff, taddr & 0xff);
1113     }
1114     printf("\n");
1115 }
1116
1117 int
1118 DoClientCMListCells(struct cmd_syndesc *as, void *arock)
1119 {
1120     afs_status_t st = 0;
1121     typedef enum { SERVER, PORT } DoClientCMListCells_parm_t;
1122     struct rx_connection *conn;
1123     int servAddr = 0;
1124     int srvrPort = AFSCONF_CALLBACKPORT;
1125     afs_CMListCell_t cellInfo;
1126     void *iter;
1127
1128 #ifdef AFS_NT40_ENV
1129     (pthread_func_list_done
1130      || pthread_once(&pthread_func_list_once, cr_list));
1131 #endif
1132
1133     if (as->parms[PORT].items) {
1134         if (!GetStatPortFromString(as->parms[PORT].items->data, &srvrPort)) {
1135             ERR_EXT("Couldn't undertand port number");
1136         }
1137     }
1138
1139     if (as->parms[SERVER].items) {
1140         if (!afsclient_CMStatOpenPort
1141             (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
1142              &st)) {
1143             ERR_ST_EXT("afsclient_CMStatOpenPort", st);
1144         }
1145     }
1146
1147     if (!util_CMListCellsBegin(conn, &iter, &st)) {
1148         ERR_ST_EXT("util_CMListCellsBegin", st);
1149     }
1150
1151     printf("Listing CellServDB for %s at port %s:\n",
1152            as->parms[SERVER].items->data, as->parms[PORT].items->data);
1153
1154     while (util_CMListCellsNext(iter, &cellInfo, &st)) {
1155
1156         Print_afs_CMListCell_p(&cellInfo);
1157     }
1158
1159     if (st != ADMITERATORDONE) {
1160         ERR_ST_EXT("util_CMListCellsNext", st);
1161     }
1162
1163     if (!util_CMListCellsDone(iter, &st)) {
1164         ERR_ST_EXT("util_CMListCellsDone", st);
1165     }
1166
1167     afsclient_CMStatClose(conn, 0);
1168
1169     return 0;
1170 }
1171
1172 int
1173 DoClientCMLocalCell(struct cmd_syndesc *as, void *arock)
1174 {
1175     afs_status_t st = 0;
1176     typedef enum { SERVER, PORT } DoClientCMLocalCell_parm_t;
1177     struct rx_connection *conn;
1178     int servAddr = 0;
1179     int srvrPort = AFSCONF_CALLBACKPORT;
1180     afs_CMCellName_t cellname;
1181
1182 #ifdef AFS_NT40_ENV
1183     (pthread_func_list_done
1184      || pthread_once(&pthread_func_list_once, cr_list));
1185 #endif
1186
1187     if (as->parms[PORT].items) {
1188         if (!GetStatPortFromString(as->parms[PORT].items->data, &srvrPort)) {
1189             ERR_EXT("Couldn't undertand port number");
1190         }
1191     }
1192
1193     if (as->parms[SERVER].items) {
1194         if (!afsclient_CMStatOpenPort
1195             (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
1196              &st)) {
1197             ERR_ST_EXT("afsclient_CMStatOpenPort", st);
1198         }
1199     }
1200
1201     if (!util_CMLocalCell(conn, cellname, &st)) {
1202         ERR_ST_EXT("util_CMLocalCell", st);
1203     }
1204
1205     printf("Client %s (port %s) is in cell %s\n",
1206            as->parms[SERVER].items->data, as->parms[PORT].items->data,
1207            cellname);
1208
1209     afsclient_CMStatClose(conn, 0);
1210
1211     return 0;
1212 }
1213
1214 static void
1215 Print_afs_ClientConfig_p(afs_ClientConfig_p config)
1216 {
1217     printf("    clientVersion:  %d\n", config->clientVersion);
1218     printf("    serverVersion:  %d\n", config->serverVersion);
1219     printf("    nChunkFiles:    %d\n", config->c.config_v1.nChunkFiles);
1220     printf("    nStatCaches:    %d\n", config->c.config_v1.nStatCaches);
1221     printf("    nDataCaches:    %d\n", config->c.config_v1.nDataCaches);
1222     printf("    nVolumeCaches:  %d\n", config->c.config_v1.nVolumeCaches);
1223     printf("    firstChunkSize: %d\n", config->c.config_v1.firstChunkSize);
1224     printf("    otherChunkSize: %d\n", config->c.config_v1.otherChunkSize);
1225     printf("    cacheSize:      %d\n", config->c.config_v1.cacheSize);
1226     printf("    setTime:        %d\n", config->c.config_v1.setTime);
1227     printf("    memCache:       %d\n", config->c.config_v1.memCache);
1228
1229 }
1230
1231 int
1232 DoClientCMClientConfig(struct cmd_syndesc *as, void *arock)
1233 {
1234     afs_status_t st = 0;
1235     typedef enum { SERVER, PORT } DoClientCMLocalCell_parm_t;
1236     struct rx_connection *conn;
1237     int servAddr = 0;
1238     int srvrPort = AFSCONF_CALLBACKPORT;
1239     afs_ClientConfig_t config;
1240
1241 #ifdef AFS_NT40_ENV
1242     (pthread_func_list_done
1243      || pthread_once(&pthread_func_list_once, cr_list));
1244 #endif
1245
1246     if (as->parms[PORT].items) {
1247         if (!GetStatPortFromString(as->parms[PORT].items->data, &srvrPort)) {
1248             ERR_EXT("Couldn't undertand port number");
1249         }
1250     }
1251
1252     if (as->parms[SERVER].items) {
1253         if (!afsclient_CMStatOpenPort
1254             (cellHandle, as->parms[SERVER].items->data, srvrPort, &conn,
1255              &st)) {
1256             ERR_ST_EXT("afsclient_CMStatOpenPort", st);
1257         }
1258     }
1259
1260     if (!util_CMClientConfig(conn, &config, &st)) {
1261         ERR_ST_EXT("util_CMClientConfig", st);
1262     }
1263
1264     printf("Cache configuration for client %s (port %s):\n\n",
1265            as->parms[SERVER].items->data, as->parms[PORT].items->data);
1266
1267     Print_afs_ClientConfig_p(&config);
1268
1269     printf("\n");
1270
1271     afsclient_CMStatClose(conn, 0);
1272
1273     return 0;
1274 }
1275
1276 void
1277 SetupClientAdminCmd(void)
1278 {
1279     struct cmd_syndesc *ts;
1280
1281     ts = cmd_CreateSyntax("ClientLocalCellGet", DoClientLocalCellGet, NULL,
1282                           "get the name of this machine's cell");
1283     SetupCommonCmdArgs(ts);
1284
1285     ts = cmd_CreateSyntax("ClientMountPointCreate", DoClientMountPointCreate,
1286                           NULL, "create a mount point");
1287     cmd_AddParm(ts, "-directory", CMD_SINGLE, CMD_REQUIRED,
1288                 "directory where mount point will be created");
1289     cmd_AddParm(ts, "-volume", CMD_SINGLE, CMD_REQUIRED,
1290                 "the name of the volume to mount");
1291     cmd_AddParm(ts, "-readwrite", CMD_FLAG, CMD_OPTIONAL,
1292                 "mount a read write volume");
1293     cmd_AddParm(ts, "-check", CMD_FLAG, CMD_OPTIONAL,
1294                 "check that the volume exists before mounting");
1295     SetupCommonCmdArgs(ts);
1296
1297     ts = cmd_CreateSyntax("ClientAFSServerGet", DoClientAFSServerGet, NULL,
1298                           "retrieve information about an afs server");
1299     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED, "server to query");
1300     SetupCommonCmdArgs(ts);
1301
1302     ts = cmd_CreateSyntax("ClientAFSServerList", DoClientAFSServerList, NULL,
1303                           "retrieve information about all afs "
1304                           "servers in a cell");
1305     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1306                 "server where command will execute");
1307     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1308                 "process to query <bosserver fileserver ptserver "
1309                 "kaserver client vlserver volserver>");
1310     cmd_AddParm(ts, "-stat_type", CMD_SINGLE, CMD_REQUIRED,
1311                 "stats to retrieve <peer or process>");
1312     SetupCommonCmdArgs(ts);
1313
1314     ts = cmd_CreateSyntax("ClientRPCStatsStateGet", DoClientRPCStatsStateGet,
1315                           NULL, "retrieve the rpc stat collection state");
1316     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1317                 "server where command will execute");
1318     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1319                 "process to query <bosserver fileserver ptserver "
1320                 "kaserver client vlserver volserver>");
1321     cmd_AddParm(ts, "-stat_type", CMD_SINGLE, CMD_REQUIRED,
1322                 "stats to retrieve <peer or process>");
1323     SetupCommonCmdArgs(ts);
1324
1325     ts = cmd_CreateSyntax("ClientRPCStatsStateEnable",
1326                           DoClientRPCStatsStateEnable, NULL,
1327                           "set the rpc stat collection state to on");
1328     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1329                 "server where command will execute");
1330     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1331                 "process to query <bosserver fileserver ptserver "
1332                 "kaserver client vlserver volserver>");
1333     cmd_AddParm(ts, "-stat_type", CMD_SINGLE, CMD_REQUIRED,
1334                 "stats to retrieve <peer or process>");
1335     SetupCommonCmdArgs(ts);
1336
1337     ts = cmd_CreateSyntax("ClientRPCStatsStateDisable",
1338                           DoClientRPCStatsStateDisable, NULL,
1339                           "set the rpc stat collection state to off");
1340     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1341                 "server where command will execute");
1342     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1343                 "process to query <bosserver fileserver ptserver "
1344                 "kaserver client vlserver volserver>");
1345     cmd_AddParm(ts, "-stat_type", CMD_SINGLE, CMD_REQUIRED,
1346                 "stats to retrieve <peer or process>");
1347     SetupCommonCmdArgs(ts);
1348
1349     ts = cmd_CreateSyntax("ClientRPCStatsList", DoClientRPCStatsList, NULL,
1350                           "list the rpc stats");
1351     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1352                 "server where command will execute");
1353     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1354                 "process to query <bosserver fileserver ptserver "
1355                 "kaserver client vlserver volserver>");
1356     cmd_AddParm(ts, "-stat_type", CMD_SINGLE, CMD_REQUIRED,
1357                 "stats to retrieve <peer or process>");
1358     SetupCommonCmdArgs(ts);
1359
1360     ts = cmd_CreateSyntax("ClientRPCStatsClear", DoClientRPCStatsClear, NULL,
1361                           "reset rpc stat counters");
1362     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1363                 "server where command will execute");
1364     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1365                 "process to query <bosserver fileserver ptserver "
1366                 "kaserver client vlserver volserver>");
1367     cmd_AddParm(ts, "-stat_type", CMD_SINGLE, CMD_REQUIRED,
1368                 "stats to retrieve <peer or process>");
1369     cmd_AddParm(ts, "-clear_all", CMD_FLAG, CMD_OPTIONAL,
1370                 "clear all existing counters");
1371     cmd_AddParm(ts, "-clear_invocations", CMD_FLAG, CMD_OPTIONAL,
1372                 "clear invocation count");
1373     cmd_AddParm(ts, "-clear_bytes_sent", CMD_FLAG, CMD_OPTIONAL,
1374                 "clear bytes_sent count");
1375     cmd_AddParm(ts, "-clear_bytes_rcvd", CMD_FLAG, CMD_OPTIONAL,
1376                 "clear bytes_rcvd count");
1377     cmd_AddParm(ts, "-clear_queue_time_sum", CMD_FLAG, CMD_OPTIONAL,
1378                 "clear queue time sum");
1379     cmd_AddParm(ts, "-clear_queue_time_square", CMD_FLAG, CMD_OPTIONAL,
1380                 "clear queue time square");
1381     cmd_AddParm(ts, "-clear_queue_time_min", CMD_FLAG, CMD_OPTIONAL,
1382                 "clear queue time min");
1383     cmd_AddParm(ts, "-clear_queue_time_max", CMD_FLAG, CMD_OPTIONAL,
1384                 "clear queue time max");
1385     cmd_AddParm(ts, "-clear_exec_time_sum", CMD_FLAG, CMD_OPTIONAL,
1386                 "clear exec time sum");
1387     cmd_AddParm(ts, "-clear_exec_time_square", CMD_FLAG, CMD_OPTIONAL,
1388                 "clear exec time square");
1389     cmd_AddParm(ts, "-clear_exec_time_min", CMD_FLAG, CMD_OPTIONAL,
1390                 "clear exec time min");
1391     cmd_AddParm(ts, "-clear_exec_time_max", CMD_FLAG, CMD_OPTIONAL,
1392                 "clear exec time max");
1393     SetupCommonCmdArgs(ts);
1394
1395     ts = cmd_CreateSyntax("ClientRPCStatsVersionGet",
1396                           DoClientRPCStatsVersionGet, NULL,
1397                           "list the server's rpc stats version");
1398     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1399                 "server where command will execute");
1400     cmd_AddParm(ts, "-process", CMD_SINGLE, CMD_REQUIRED,
1401                 "process to query <bosserver fileserver ptserver "
1402                 "kaserver client vlserver volserver>");
1403     SetupCommonCmdArgs(ts);
1404
1405     ts = cmd_CreateSyntax("ClientCMGetServerPrefs", DoClientCMGetServerPrefs,
1406                           NULL, "list a client's server preferences ");
1407     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1408                 "server where command will execute");
1409     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "UDP port to query");
1410     SetupCommonCmdArgs(ts);
1411
1412     ts = cmd_CreateSyntax("ClientCMListCells", DoClientCMListCells, NULL,
1413                           "list a client's CellServDB ");
1414     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1415                 "server where command will execute");
1416     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "UDP port to query");
1417     SetupCommonCmdArgs(ts);
1418
1419     ts = cmd_CreateSyntax("ClientCMLocalCell", DoClientCMLocalCell, NULL,
1420                           "get the name of the client's local cell");
1421     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1422                 "server where command will execute");
1423     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "UDP port to query");
1424     SetupCommonCmdArgs(ts);
1425
1426     ts = cmd_CreateSyntax("ClientCMClientConfig", DoClientCMClientConfig, NULL,
1427                           "get the client's cache configuration");
1428     cmd_AddParm(ts, "-server", CMD_SINGLE, CMD_REQUIRED,
1429                 "server where command will execute");
1430     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "UDP port to query");
1431     SetupCommonCmdArgs(ts);
1432 }