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