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