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