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