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