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