2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include <afs/param.h>
15 #include <afs/afs_Admin.h>
18 #include <afs/afs_Admin.h>
19 #include "afs_AdminInternal.h"
20 #include <afs/pthread_glock.h>
21 #include <afs/cellconfig.h>
22 #include <afs/dirpath.h>
23 #include <afs/com_err.h>
24 #include <afs/kautils.h>
26 #include <afs/vlserver.h>
27 #include <afs/pterror.h>
28 #include <afs/bnode.h>
29 #include <afs/volser.h>
30 #include <afs/afscbint.h>
32 #include <rx/rxstat.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
42 #include "afs_utilAdmin.h"
45 * AIX 4.2 has PTHREAD_CREATE_UNDETACHED and not PTHREAD_CREATE_JOINABLE
47 * This fix should be done more centrally, but there's no time right now.
49 #if defined(AFS_AIX_ENV)
50 # if !defined(PTHREAD_CREATE_JOINABLE) && defined(PTHREAD_CREATE_UNDETACHED)
51 # define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED
55 #define ERRCODE_RANGE 8
56 static pthread_once_t error_init_once = PTHREAD_ONCE_INIT;
57 static int error_init_done;
63 initialize_KA_error_table();
64 initialize_RXK_error_table();
65 initialize_KTC_error_table();
66 initialize_ACFG_error_table();
67 initialize_CMD_error_table();
68 initialize_VL_error_table();
69 initialize_PT_error_table();
70 initialize_BZ_error_table();
71 initialize_U_error_table();
72 initialize_AB_error_table();
73 initialize_AF_error_table();
74 initialize_AL_error_table();
75 initialize_AC_error_table();
76 initialize_AK_error_table();
77 initialize_AM_error_table();
78 initialize_AP_error_table();
79 initialize_AU_error_table();
80 initialize_AV_error_table();
81 initialize_VOLS_error_table();
86 util_AdminErrorCodeTranslate(afs_status_t errorCode, int langId,
87 const char **errorTextP, afs_status_p st)
93 if (errorTextP == NULL) {
94 tst = ADMUTILERRORTEXTPNULL;
95 goto fail_util_AdminErrorCodeTranslate;
102 if (!error_init_done)
103 pthread_once(&error_init_once, init_once);
104 code = (afs_int32) errorCode;
105 *errorTextP = afs_error_message(code);
108 fail_util_AdminErrorCodeTranslate:
117 * The iterator functions and data for the database server retrieval functions.
120 typedef struct database_server_get {
123 struct afsconf_dir *conf;
124 struct afsconf_cell cell;
125 util_databaseServerEntry_t server[CACHED_ITEMS];
126 } database_server_get_t, *database_server_get_p;
129 GetDatabaseServerRPC(void *rpc_specific, int slot, int *last_item,
130 int *last_item_contains_data, afs_status_p st)
133 afs_status_t tst = 0;
134 database_server_get_p serv = (database_server_get_p) rpc_specific;
136 serv->server[slot].serverAddress =
137 ntohl(serv->cell.hostAddr[serv->index].sin_addr.s_addr);
138 strcpy(serv->server[slot].serverName, serv->cell.hostName[serv->index]);
142 * See if we've processed all the entries
145 if (serv->index == serv->total) {
147 *last_item_contains_data = 1;
158 GetDatabaseServerFromCache(void *rpc_specific, int slot, void *dest,
162 afs_status_t tst = 0;
163 database_server_get_p serv = (database_server_get_p) rpc_specific;
165 memcpy(dest, (const void *)&serv->server[slot],
166 sizeof(util_databaseServerEntry_t));
176 DestroyDatabaseServer(void *rpc_specific, afs_status_p st)
179 afs_status_t tst = 0;
180 database_server_get_p serv = (database_server_get_p) rpc_specific;
182 afsconf_Close(serv->conf);
192 * util_DatabaseServerGetBegin - begin iterating over the database
193 * server machines in a cell.
197 * IN cellName - the cell where database servers reside.
199 * OUT iterationIdP - upon successful completion contains an iterator that
200 * can be passed to util_DatabaseServerGetNext.
204 * No locks are obtained or released by this function
212 * Returns != 0 upon successful completion.
216 util_DatabaseServerGetBegin(const char *cellName, void **iterationIdP,
220 afs_status_t tst = 0;
221 afs_admin_iterator_p iter =
222 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
223 database_server_get_p serv =
224 (database_server_get_p) calloc(1, sizeof(database_server_get_t));
225 char copyCell[MAXCELLCHARS];
231 if ((cellName == NULL) || (*cellName == 0)) {
232 tst = ADMUTILCELLNAMENULL;
233 goto fail_util_DatabaseServerGetBegin;
236 if (iterationIdP == NULL) {
237 goto fail_util_DatabaseServerGetBegin;
240 if ((iter == NULL) || (serv == NULL)) {
242 goto fail_util_DatabaseServerGetBegin;
246 * Fill in the serv structure
249 serv->conf = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
250 if (serv->conf == NULL) {
251 tst = ADMUTILCANTOPENCELLSERVDB;
252 goto fail_util_DatabaseServerGetBegin;
256 * We must copy the cellname because afsconf_GetCellInfo
257 * actually writes over the cell name it is passed.
259 strncpy(copyCell, cellName, MAXCELLCHARS - 1);
261 afsconf_GetCellInfo(serv->conf, copyCell, AFSCONF_KAUTHSERVICE,
264 goto fail_util_DatabaseServerGetBegin;
267 serv->total = serv->cell.numServers;
269 (iter, (void *)serv, GetDatabaseServerRPC, GetDatabaseServerFromCache,
270 NULL, DestroyDatabaseServer, &tst)) {
271 *iterationIdP = (void *)iter;
273 goto fail_util_DatabaseServerGetBegin;
277 fail_util_DatabaseServerGetBegin:
295 * util_DatabaseServerGetNext - get the next server address.
299 * IN iterationId - an iterator returned by util_DatabaseServerGetBegin
301 * OUT serverAddressP - upon successful completion contains the next
302 * server address in the cell.
306 * This function locks the iterator for the duration of its processing.
314 * Returns != 0 upon successful completion.
319 util_DatabaseServerGetNext(const void *iterationId,
320 util_databaseServerEntry_p serverP,
324 afs_status_t tst = 0;
325 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
328 tst = ADMITERATORNULL;
329 goto fail_util_DatabaseServerGetNext;
332 if (serverP == NULL) {
333 tst = ADMUTILSERVERADDRESSPNULL;
334 goto fail_util_DatabaseServerGetNext;
337 rc = IteratorNext(iter, (void *)serverP, &tst);
339 fail_util_DatabaseServerGetNext:
348 * util_DatabaseServerGetDone - stop using a database iterator.
352 * IN iterationId - an iterator returned by util_DatabaseServerGetBegin
356 * This function locks the iterator for the duration of its processing.
357 * And then destroys it before returning.
365 * Returns != 0 upon successful completion.
369 util_DatabaseServerGetDone(const void *iterationId, afs_status_p st)
372 afs_status_t tst = 0;
373 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
376 * Validate parameters
380 tst = ADMITERATORNULL;
381 goto fail_util_DatabaseServerGetDone;
384 rc = IteratorDone(iter, &tst);
386 fail_util_DatabaseServerGetDone:
395 * GetServerAddressFromName - translate a character string server name
396 * to an integer representation of an IP address.
400 * IN serverName - the character string server name in either foo.com
401 * format, or 123.12.1.1 format.
403 * OUT serverAddress - an integer that is filled with the correct address
404 * in host byte order upon successful completion.
408 * No locks are obtained or released by this function
412 * On many platforms, gethostbyname is not thread safe. Since we are
413 * only working under NT for now I'll use it directly. In future UNIX
414 * ports, a wrapper function should be written to call the correct function
415 * on the particular platform.
419 * Returns != 0 upon successful completion.
423 util_AdminServerAddressGetFromName(const char *serverName, int *serverAddress,
427 afs_status_t tst = 0;
428 struct hostent *server;
429 int part1, part2, part3, part4;
432 if ((serverName == NULL) || (*serverName == 0)) {
433 tst = ADMUTILSERVERNAMENULL;
434 goto fail_util_AdminServerAddressGetFromName;
437 if (serverAddress == NULL) {
438 tst = ADMUTILSERVERADDRESSNULL;
439 goto fail_util_AdminServerAddressGetFromName;
443 sscanf(serverName, "%d.%d.%d.%d", &part1, &part2, &part3, &part4);
444 if (num_converted == 4) {
445 *serverAddress = (part1 << 24) | (part2 << 16) | (part3 << 8) | part4;
448 server = gethostbyname(serverName);
449 if (server != NULL) {
450 memcpy((void *)serverAddress, (const void *)server->h_addr,
452 *serverAddress = ntohl(*serverAddress);
454 tst = ADMUTILCANTGETSERVERNAME;
456 goto fail_util_AdminServerAddressGetFromName;
462 fail_util_AdminServerAddressGetFromName:
472 * This file contains functions that can be used to create iterator
473 * functions within the api. I have attempted to make these functions
474 * generic so that they can be used across the admin components.
476 * The functions in this file are a generalized producer/consumer
477 * implementation. They manage access to a queue of data. The only
478 * assumption these functions make about this data is that it is
479 * stored in a queue which is implemented via an array. These functions
480 * know about the index into the array, but they know nothing about
481 * the contents of the array.
483 * The data specific functions you implement will have to create some
484 * data specific storage structure that will have an array
485 * of size CACHED_ITEMS data items. This structure will also need to
486 * store any necessary parameters/state variables you need to issue the
487 * rpc to retrieve the next item.
489 * In order to use the generic functions, you must implement four functions
490 * for each type of data you wish to retrieve. The functions are:
492 * validate_specific_data_func - this function is handed a void pointer
493 * that points to the rpc specific data you've allocated. The function
494 * should examine the data for validity and return an appropriate error.
495 * This function is called every time the iterator is validated.
497 * destroy_specific_data_func - this function is handed a void pointer
498 * that points to the rpc specific data you've allocated. It should
499 * destroy any components of the specific data as required and then
500 * return. The void pointer is free'd by the generic functions.
502 * get_cached_data_func - this function is handed a void pointer
503 * that points to the rpc specific data you've allocated, an index
504 * into the cache of the item to be copied to the caller, and a void
505 * pointer where the cache item should be copied.
507 * make_rpc_func - this function is handed a void pointer that points
508 * to the rpc specific data you've allocated, an index into the cache
509 * of the item to be filled with the next retrieved item, and an int
510 * pointer that should be set to 1 if there are no more items to be
511 * retrieved. The assumption made by the generic functions is that
512 * the last_item status requires an individual rpc - the data isn't
513 * piggybacked on the last data item.
517 * IteratorDelete - delete an iterator.
521 * IN interator - the iterator to delete.
525 * No locks are held by this function.
529 * Returns != 0 upon successful completion.
533 IteratorDelete(afs_admin_iterator_p iter, afs_status_p st)
536 afs_status_t tst = 0;
538 if (pthread_mutex_destroy(&iter->mutex)) {
539 tst = ADMMUTEXDESTROY;
540 goto fail_IteratorDelete;
542 if (pthread_cond_destroy(&iter->add_item)) {
543 tst = ADMCONDDESTROY;
544 goto fail_IteratorDelete;
546 if (pthread_cond_destroy(&iter->remove_item)) {
547 tst = ADMCONDDESTROY;
548 goto fail_IteratorDelete;
551 if (iter->destroy_specific != NULL) {
552 iter->destroy_specific(iter->rpc_specific, &tst);
554 free(iter->rpc_specific);
567 * DataGet - the background thread that is spawned for every
568 * IteratorBegin call that is successful. This thread tries
569 * to fetch the data from the server ahead of the
570 * IteratorNext calls.
574 * IN arg - the address of the iterator structure to be used for this
579 * The iterator mutex is used by this function to protect elements
580 * of the iterator structure.
584 * Returns != 0 upon successful completion.
590 afs_admin_iterator_p iter = (afs_admin_iterator_p) arg;
592 afs_status_t tst = 0;
593 int mutex_locked = 0;
595 int last_item_contains_data = 0;
597 if (pthread_mutex_lock(&iter->mutex)) {
598 iter->st = ADMMUTEXLOCK;
607 * Check to see if there's room for this datum. If not, wait
608 * on the consumer to free up another slot.
611 while (iter->cache_slots_used == CACHED_ITEMS) {
612 if (pthread_cond_wait(&iter->remove_item, &iter->mutex)) {
613 iter->st = ADMCONDWAIT;
619 * Check to see if someone called Done and terminated the request.
620 * We could have gone to sleep above when the buffer was full and
621 * instead of being awoken because another slot is open, we were
622 * awoken because the request was terminated.
625 if (iter->request_terminated) {
629 if (pthread_mutex_unlock(&iter->mutex)) {
630 iter->st = ADMMUTEXUNLOCK;
637 * Make an rpc without holding the iter mutex
638 * We reference an item in the principal cache here without
639 * holding the mutex. This is safe because:
640 * 1. The iter structure is ref counted and won't be deleted
641 * from underneath us.
642 * 2. cache_queue_tail is always one item ahead of the consumer
643 * thread so we are the only thread accessing this member.
646 iter->make_rpc(iter->rpc_specific, iter->cache_queue_tail, &last_item,
647 &last_item_contains_data, &tst);
649 if (pthread_mutex_lock(&iter->mutex)) {
650 iter->st = ADMMUTEXLOCK;
657 * Check to see if someone called Done and terminated the request
660 if (iter->request_terminated) {
665 * Check the rc of the rpc, and see if there are no more items
675 * Check to see if this is the last item produced by the rpc.
676 * If it isn't, add the item to the cache and proceed.
677 * If it is, check to see if the last item contains valid data.
678 * If it contains valid data, we need to add it to our cache.
679 * If it doesn't, we mark the iterator as complete.
682 if ((!last_item) || ((last_item) && (last_item_contains_data))) {
683 iter->cache_queue_tail =
684 (iter->cache_queue_tail + 1) % CACHED_ITEMS;
685 iter->cache_slots_used++;
688 iter->st = ADMITERATORDONE;
689 iter->done_iterating = 1;
691 * There's a small chance that the consumer emptied the
692 * cache queue while we were making the last rpc and has
693 * since gone to sleep waiting for more data. In this case
694 * there will never be more data so we signal him here.
696 pthread_cond_signal(&iter->add_item);
702 * If the cache was empty and we just added another item, signal
706 if (iter->cache_slots_used == 1) {
707 if (pthread_cond_signal(&iter->add_item)) {
708 iter->st = ADMCONDSIGNAL;
718 * If we are exiting with an error, signal the consumer in the event
719 * they were waiting for us to produce more data
723 pthread_cond_signal(&iter->add_item);
727 pthread_mutex_unlock(&iter->mutex);
734 * IsValidIterator - verify the validity of a afs_admin_iterator_t.
738 * IN interator - the interator to be verified.
742 * We assume the iter->mutex lock is already held.
746 * Returns != 0 upon successful completion.
750 IsValidIterator(const afs_admin_iterator_p iterator, afs_status_p st)
753 afs_status_t tst = 0;
756 * Validate input parameters
759 if (iterator == NULL) {
760 tst = ADMITERATORNULL;
761 goto fail_IsValidIterator;
764 if ((iterator->begin_magic != BEGIN_MAGIC)
765 || (iterator->end_magic != END_MAGIC)) {
766 tst = ADMITERATORBADMAGICNULL;
767 goto fail_IsValidIterator;
770 if (iterator->is_valid == 0) {
771 tst = ADMITERATORINVALID;
772 goto fail_IsValidIterator;
776 * Call the iterator specific validation function
779 if (iterator->validate_specific != NULL) {
780 if (!iterator->validate_specific(iterator->rpc_specific, &tst)) {
781 goto fail_IsValidIterator;
786 fail_IsValidIterator:
795 * IteratorNext - return the next datum in an interator.
799 * IN interator - the iterator containing the data.
801 * IN dest - the address where the data should be copied.
805 * Lock the iterator upon entry, and hold it during the duration of this
810 * Returns != 0 upon successful completion.
814 IteratorNext(afs_admin_iterator_p iter, void *dest, afs_status_p st)
817 afs_status_t tst = 0;
821 * We have to lock the iterator before we validate it
824 if (pthread_mutex_lock(&iter->mutex)) {
826 goto fail_IteratorNext;
831 if (!IsValidIterator(iter, &tst)) {
832 goto fail_IteratorNext;
835 if (iter->request_terminated == 1) {
836 tst = ADMITERATORTERMINATED;
837 goto fail_IteratorNext;
840 if ((iter->st != AFS_STATUS_OK) && (iter->st != ADMITERATORDONE)) {
842 goto fail_IteratorNext;
846 * Check to see if there are any queue'd items. If not, wait here
847 * until signalled by the producer.
850 while (iter->cache_slots_used == 0) {
853 * Maybe the producer experienced an rpc failure.
856 if ((!iter->done_iterating) && (iter->st != 0)) {
858 goto fail_IteratorNext;
862 * Maybe there are no queue'd items because the producer is done
865 if (iter->done_iterating) {
867 goto fail_IteratorNext;
870 if (pthread_cond_wait(&iter->add_item, &iter->mutex)) {
872 goto fail_IteratorNext;
877 * Copy the next cached item and update the cached item count
878 * and the index into the cache array
882 get_cached_data(iter->rpc_specific, iter->cache_queue_head, dest,
884 goto fail_IteratorNext;
887 iter->cache_queue_head = (iter->cache_queue_head + 1) % CACHED_ITEMS;
888 iter->cache_slots_used--;
891 * If the cache was full before we removed the item above, the
892 * producer may have been waiting for us to remove an item.
893 * Signal the producer letting him know that we've opened a slot
897 if (iter->cache_slots_used == (CACHED_ITEMS - 1)) {
898 if (pthread_cond_signal(&iter->remove_item)) {
900 goto fail_IteratorNext;
908 if (locked_iter == 1) {
909 pthread_mutex_unlock(&iter->mutex);
919 * IteratorDone - mark the iterator done.
923 * IN interator - the iterator to mark done.
927 * Lock the iterator upon entry, and hold it during the duration of this
932 * Returns != 0 upon successful completion.
936 IteratorDone(afs_admin_iterator_p iter, afs_status_p st)
939 afs_status_t tst = 0;
940 int mutex_locked = 1;
942 if (pthread_mutex_lock(&iter->mutex)) {
944 goto fail_IteratorDone;
950 if (!IsValidIterator(iter, &tst)) {
951 goto fail_IteratorDone;
956 * Depending upon the status of the background worker thread,
957 * we can either join with him immediately (if we know he has
958 * terminated), or we need to tell him the request has been
959 * terminated and then join with him.
962 if (!iter->done_iterating) {
963 iter->request_terminated = 1;
964 iter->cache_slots_used = 0;
965 pthread_cond_signal(&iter->remove_item);
969 * We have to unlock the mutex to allow the background thread to
973 if (pthread_mutex_unlock(&iter->mutex)) {
974 tst = ADMMUTEXUNLOCK;
975 goto fail_IteratorDone;
978 if (iter->make_rpc != NULL) {
979 if (pthread_join(iter->bg_worker, (void **)0)) {
981 goto fail_IteratorDone;
986 * We don't relock the mutex here since we are the only thread
987 * that has access to the iter now
990 rc = IteratorDelete(iter, &tst);
996 pthread_mutex_unlock(&iter->mutex);
1006 * IteratorInit - initialize an iterator.
1010 * IN interator - the iterator to initialize.
1014 * No locks are held by this function.
1018 * Returns != 0 upon successful completion.
1022 IteratorInit(afs_admin_iterator_p iter, void *rpc_specific,
1023 make_rpc_func make_rpc, get_cached_data_func get_cached_data,
1024 validate_specific_data_func validate_specific_data,
1025 destroy_specific_data_func destroy_specific_data,
1029 afs_status_t tst = 0;
1030 int mutex_inited = 0;
1031 int add_item_cond_inited = 0;
1032 int remove_item_cond_inited = 0;
1035 tst = ADMITERATORNULL;
1036 goto fail_IteratorInit;
1039 if (rpc_specific == NULL) {
1040 tst = ADMITERATORRPCSPECIFICNULL;
1041 goto fail_IteratorInit;
1045 * Initialize the iterator structure
1047 iter->begin_magic = BEGIN_MAGIC;
1048 iter->end_magic = END_MAGIC;
1050 iter->cache_slots_used = 0;
1051 iter->done_iterating = 0;
1052 iter->request_terminated = 0;
1053 iter->st = AFS_STATUS_OK;
1054 iter->cache_queue_head = 0;
1055 iter->cache_queue_tail = 0;
1056 iter->cache_slots_used = 0;
1057 iter->rpc_specific = rpc_specific;
1058 iter->make_rpc = make_rpc;
1059 iter->get_cached_data = get_cached_data;
1060 iter->validate_specific = validate_specific_data;
1061 iter->destroy_specific = destroy_specific_data;
1063 if (pthread_mutex_init(&iter->mutex, (const pthread_mutexattr_t *)0)) {
1065 goto fail_IteratorInit;
1070 if (pthread_cond_init(&iter->add_item, (const pthread_condattr_t *)0)) {
1072 goto fail_IteratorInit;
1074 add_item_cond_inited = 1;
1077 if (pthread_cond_init(&iter->remove_item, (const pthread_condattr_t *)0)) {
1079 goto fail_IteratorInit;
1081 remove_item_cond_inited = 1;
1085 * Create a worker thread that will begin to query the server
1086 * and cache responses.
1089 if (iter->make_rpc != NULL) {
1090 pthread_attr_t tattr;
1092 if (pthread_attr_init(&tattr)) {
1093 tst = ADMTHREADATTRINIT;
1094 goto fail_IteratorInit;
1097 if (pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE)) {
1098 tst = ADMTHREADATTRSETDETACHSTATE;
1099 goto fail_IteratorInit;
1102 if (pthread_create(&iter->bg_worker, &tattr, DataGet, (void *)iter)) {
1103 tst = ADMTHREADCREATE;
1104 goto fail_IteratorInit;
1113 pthread_mutex_destroy(&iter->mutex);
1115 if (remove_item_cond_inited) {
1116 pthread_cond_destroy(&iter->remove_item);
1118 if (add_item_cond_inited) {
1119 pthread_cond_destroy(&iter->add_item);
1130 CellHandleIsValid(const void *cellHandle, afs_status_p st)
1133 afs_status_t tst = 0;
1134 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1137 * Validate input parameters
1140 if (c_handle == NULL) {
1141 tst = ADMCLIENTCELLHANDLENULL;
1142 goto fail_CellHandleIsValid;
1145 if ((c_handle->begin_magic != BEGIN_MAGIC)
1146 || (c_handle->end_magic != END_MAGIC)) {
1147 tst = ADMCLIENTCELLHANDLEBADMAGIC;
1148 goto fail_CellHandleIsValid;
1151 if (c_handle->is_valid == 0) {
1152 tst = ADMCLIENTCELLINVALID;
1153 goto fail_CellHandleIsValid;
1157 fail_CellHandleIsValid:
1166 * The iterator functions and data for the rpc statistic retrieval functions
1169 typedef struct rpc_stat_get {
1170 afs_uint32 clock_sec;
1171 afs_uint32 clock_usec;
1174 afs_uint32 clientVersion;
1175 afs_uint32 serverVersion;
1176 struct rpcStats stat_list;
1177 afs_RPCStats_t stats[CACHED_ITEMS];
1178 afs_uint32 *pointer;
1179 } rpc_stat_get_t, *rpc_stat_get_p;
1182 UnmarshallRPCStats(afs_uint32 serverVersion, afs_uint32 ** ptrP,
1186 unsigned int hi, lo;
1189 * Server must always match lower versions. We are version 1.
1192 s->stats_v1.remote_peer = *(ptr++);
1193 s->stats_v1.remote_port = *(ptr++);
1194 s->stats_v1.remote_is_server = *(ptr++);
1195 s->stats_v1.interfaceId = *(ptr++);
1196 s->stats_v1.func_total = *(ptr++);
1197 s->stats_v1.func_index = *(ptr++);
1200 hset64(s->stats_v1.invocations, hi, lo);
1203 hset64(s->stats_v1.bytes_sent, hi, lo);
1206 hset64(s->stats_v1.bytes_rcvd, hi, lo);
1207 s->stats_v1.queue_time_sum.sec = *(ptr++);
1208 s->stats_v1.queue_time_sum.usec = *(ptr++);
1209 s->stats_v1.queue_time_sum_sqr.sec = *(ptr++);
1210 s->stats_v1.queue_time_sum_sqr.usec = *(ptr++);
1211 s->stats_v1.queue_time_min.sec = *(ptr++);
1212 s->stats_v1.queue_time_min.usec = *(ptr++);
1213 s->stats_v1.queue_time_max.sec = *(ptr++);
1214 s->stats_v1.queue_time_max.usec = *(ptr++);
1215 s->stats_v1.execution_time_sum.sec = *(ptr++);
1216 s->stats_v1.execution_time_sum.usec = *(ptr++);
1217 s->stats_v1.execution_time_sum_sqr.sec = *(ptr++);
1218 s->stats_v1.execution_time_sum_sqr.usec = *(ptr++);
1219 s->stats_v1.execution_time_min.sec = *(ptr++);
1220 s->stats_v1.execution_time_min.usec = *(ptr++);
1221 s->stats_v1.execution_time_max.sec = *(ptr++);
1222 s->stats_v1.execution_time_max.usec = *(ptr++);
1227 GetRPCStatsRPC(void *rpc_specific, int slot, int *last_item,
1228 int *last_item_contains_data, afs_status_p st)
1231 afs_status_t tst = 0;
1232 rpc_stat_get_p t = (rpc_stat_get_p) rpc_specific;
1234 t->stats[slot].clientVersion = t->clientVersion;
1235 t->stats[slot].serverVersion = t->serverVersion;
1236 t->stats[slot].statCount = t->total;
1239 * If the server stat version is greater than or equal to my version
1240 * number, it is required to return the values in the client's current
1244 UnmarshallRPCStats(t->serverVersion, &t->pointer, &t->stats[slot].s);
1249 * See if we've processed all the entries
1252 if (t->index == t->total) {
1254 *last_item_contains_data = 1;
1265 GetRPCStatsFromCache(void *rpc_specific, int slot, void *dest,
1269 afs_status_t tst = 0;
1270 rpc_stat_get_p stat = (rpc_stat_get_p) rpc_specific;
1272 memcpy(dest, (const void *)&stat->stats[slot], sizeof(afs_RPCStats_t));
1282 DestroyRPCStats(void *rpc_specific, afs_status_p st)
1285 afs_status_t tst = 0;
1286 rpc_stat_get_p stat = (rpc_stat_get_p) rpc_specific;
1288 if (stat->stat_list.rpcStats_val != NULL) {
1289 free(stat->stat_list.rpcStats_val);
1300 * util_RPCStatsGetBegin - begin retrieving rpc stats for a process
1304 * IN conn - an rx connection to the process to be queried
1306 * IN rpc - the function to call to make the actual rpc
1308 * OUT iterationIdP - an iteration id that can be passed to
1309 * util_RPCStatsGetNext to get the next rpc stat
1313 * No locks are obtained or released by this function
1317 * Returns != 0 upon successful completion.
1322 util_RPCStatsGetBegin(struct rx_connection *conn,
1323 int (*rpc) (struct rx_connection *,
1324 afs_uint32, afs_uint32 *,
1325 afs_uint32 *, afs_uint32 *,
1326 afs_uint32 *, struct rpcStats *),
1327 void **iterationIdP, afs_status_p st)
1330 afs_status_t tst = 0;
1331 afs_admin_iterator_p iter =
1332 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1333 rpc_stat_get_p stat = (rpc_stat_get_p) malloc(sizeof(rpc_stat_get_t));
1336 tst = ADMRXCONNNULL;
1337 goto fail_util_RPCStatsGetBegin;
1341 tst = ADMRPCPTRNULL;
1342 goto fail_util_RPCStatsGetBegin;
1345 if (iterationIdP == NULL) {
1346 tst = ADMITERATIONIDPNULL;
1347 goto fail_util_RPCStatsGetBegin;
1350 if ((iter == NULL) || (stat == NULL)) {
1352 goto fail_util_RPCStatsGetBegin;
1355 stat->stat_list.rpcStats_len = 0;
1356 stat->stat_list.rpcStats_val = 0;
1358 stat->clientVersion = RX_STATS_RETRIEVAL_VERSION;
1361 (*rpc) (conn, stat->clientVersion, &stat->serverVersion,
1362 &stat->clock_sec, &stat->clock_usec, &stat->total,
1366 goto fail_util_RPCStatsGetBegin;
1370 * If there are no statistics, just mark the iterator done and
1374 if (stat->stat_list.rpcStats_len == 0) {
1375 stat->pointer = NULL;
1376 if (!IteratorInit(iter, (void *)stat, NULL, NULL, NULL, NULL, &tst)) {
1377 goto fail_util_RPCStatsGetBegin;
1379 iter->done_iterating = 1;
1380 iter->st = ADMITERATORDONE;
1382 stat->pointer = stat->stat_list.rpcStats_val;
1384 (iter, (void *)stat, GetRPCStatsRPC, GetRPCStatsFromCache, NULL,
1385 DestroyRPCStats, &tst)) {
1386 goto fail_util_RPCStatsGetBegin;
1389 *iterationIdP = (void *)iter;
1392 fail_util_RPCStatsGetBegin:
1410 * util_RPCStatsGetNext - retrieve the next rpc stat from the server
1414 * IN iterationId - an iterator previously returned by
1415 * util_RPCStatsGetBegin.
1417 * OUT stats - upon successful completion contains the next set of stats
1422 * No locks are obtained or released by this function
1426 * Returns != 0 upon successful completion.
1431 util_RPCStatsGetNext(const void *iterationId, afs_RPCStats_p stats,
1435 afs_status_t tst = 0;
1436 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
1438 if (iterationId == NULL) {
1439 tst = ADMITERATIONIDPNULL;
1440 goto fail_util_RPCStatsGetNext;
1443 if (stats == NULL) {
1444 tst = ADMUTILRPCSTATSNULL;
1445 goto fail_util_RPCStatsGetNext;
1448 rc = IteratorNext(iter, (void *)stats, &tst);
1450 fail_util_RPCStatsGetNext:
1459 * util_RPCStatsGetDone - finish using a stats iterator
1463 * IN iterationId - an iterator previously returned by
1464 * util_RPCStatsGetBegin.
1468 * No locks are obtained or released by this function
1472 * Returns != 0 upon successful completion.
1477 util_RPCStatsGetDone(const void *iterationId, afs_status_p st)
1480 afs_status_t tst = 0;
1481 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
1483 if (iterationId == NULL) {
1484 tst = ADMITERATIONIDPNULL;
1485 goto fail_util_RPCStatsGetDone;
1488 rc = IteratorDone(iter, &tst);
1490 fail_util_RPCStatsGetDone:
1499 * util_RPCStatsStateGet - get the current state of rpc stat collection
1503 * IN conn - an rx connection to the process to be queried
1505 * IN rpc - the function to call to make the actual rpc
1507 * OUT state - the rpc stat collection state.
1511 * No locks are obtained or released by this function
1515 * Returns != 0 upon successful completion.
1520 util_RPCStatsStateGet(struct rx_connection *conn,
1521 int (*rpc) (struct rx_connection *,
1522 afs_RPCStatsState_p),
1523 afs_RPCStatsState_p state, afs_status_p st)
1526 afs_status_t tst = 0;
1529 tst = ADMRXCONNNULL;
1530 goto fail_util_RPCStatsStateGet;
1534 tst = ADMRPCPTRNULL;
1535 goto fail_util_RPCStatsStateGet;
1538 if (state == NULL) {
1539 tst = ADMRPCSTATENULL;
1540 goto fail_util_RPCStatsStateGet;
1543 tst = (*rpc) (conn, state);
1549 fail_util_RPCStatsStateGet:
1558 * util_RPCStatsStateEnable - enable rpc stat collection
1563 * IN conn - an rx connection to the process to be modified
1565 * IN rpc - the function to call to make the actual rpc
1569 * No locks are obtained or released by this function
1573 * Returns != 0 upon successful completion.
1578 util_RPCStatsStateEnable(struct rx_connection *conn,
1579 int (*rpc) (struct rx_connection *),
1583 afs_status_t tst = 0;
1586 tst = ADMRXCONNNULL;
1587 goto fail_util_RPCStatsStateEnable;
1591 tst = ADMRPCPTRNULL;
1592 goto fail_util_RPCStatsStateEnable;
1595 tst = (*rpc) (conn);
1601 fail_util_RPCStatsStateEnable:
1610 * util_RPCStatsStateDisable - set the current state of rpc stat collection
1615 * IN conn - an rx connection to the process to be modified
1617 * IN rpc - the function to call to make the actual rpc
1621 * No locks are obtained or released by this function
1625 * Returns != 0 upon successful completion.
1630 util_RPCStatsStateDisable(struct rx_connection *conn,
1631 int (*rpc) (struct rx_connection *),
1635 afs_status_t tst = 0;
1638 tst = ADMRXCONNNULL;
1639 goto fail_util_RPCStatsStateDisable;
1643 tst = ADMRPCPTRNULL;
1644 goto fail_util_RPCStatsStateDisable;
1647 tst = (*rpc) (conn);
1653 fail_util_RPCStatsStateDisable:
1662 * util_RPCStatsClear - clear some or all of the fields in the rpc stat
1663 * collection at a server
1667 * IN conn - an rx connection to the process to be modified
1669 * IN rpc - the function to call to make the actual rpc
1671 * IN flag - a flag containing the fields to be cleared
1676 * No locks are obtained or released by this function
1680 * Returns != 0 upon successful completion.
1685 util_RPCStatsClear(struct rx_connection *conn,
1686 int (*rpc) (struct rx_connection *,
1687 afs_RPCStatsClearFlag_t),
1688 afs_RPCStatsClearFlag_t flag, afs_status_p st)
1691 afs_status_t tst = 0;
1694 tst = ADMRXCONNNULL;
1695 goto fail_util_RPCStatsClear;
1699 tst = ADMRPCPTRNULL;
1700 goto fail_util_RPCStatsClear;
1703 tst = (*rpc) (conn, flag);
1709 fail_util_RPCStatsClear:
1718 * util_RPCStatsVersionGet - get the current version of rpc stat collection
1722 * IN conn - an rx connection to the process to be modified
1724 * OUT version - the version of rpc stat collection at the remote process
1728 * No locks are obtained or released by this function
1732 * Returns != 0 upon successful completion.
1737 util_RPCStatsVersionGet(struct rx_connection *conn,
1738 afs_RPCStatsVersion_p version, afs_status_p st)
1741 afs_status_t tst = 0;
1744 tst = ADMRXCONNNULL;
1745 goto fail_util_RPCStatsVersionGet;
1748 if (version == NULL) {
1749 tst = ADMRPCVERSIONNULL;
1750 goto fail_util_RPCStatsVersionGet;
1753 tst = RXSTATS_QueryRPCStatsVersion(conn, version);
1759 fail_util_RPCStatsVersionGet:
1768 * The iterator for listing CM server preferences
1771 typedef struct cm_srvr_pref_get {
1772 struct rx_connection *conn;
1774 afs_CMServerPref_t srvrPrefs[CACHED_ITEMS];
1775 } cm_srvr_pref_get_t, *cm_srvr_pref_get_p;
1778 GetServerPrefsRPC(void *rpc_specific, int slot, int *last_item,
1779 int *last_item_contains_data, afs_status_p st)
1782 afs_status_t tst = 0;
1783 cm_srvr_pref_get_p t = (cm_srvr_pref_get_p) rpc_specific;
1786 * Get the next entry in the list of server preferences.
1789 RXAFSCB_GetServerPrefs(t->conn, t->index, &t->srvrPrefs[slot].ipAddr,
1790 &t->srvrPrefs[slot].ipRank);
1792 goto fail_GetServerPrefsRPC;
1796 * See if we've processed all the entries
1798 if (t->srvrPrefs[slot].ipAddr == 0xffffffff) {
1800 *last_item_contains_data = 0;
1806 fail_GetServerPrefsRPC:
1815 GetServerPrefsFromCache(void *rpc_specific, int slot, void *dest,
1819 afs_status_t tst = 0;
1820 cm_srvr_pref_get_p prefs = (cm_srvr_pref_get_p) rpc_specific;
1822 memcpy(dest, (const void *)&prefs->srvrPrefs[slot],
1823 sizeof(afs_CMServerPref_t));
1833 * util_CMGetServerPrefsBegin - Begin listing cache manager server preferences
1837 * IN conn - an rx connection to the process to be queried
1839 * OUT iterationIdP - an iteration id that can be passed to
1840 * util_CMGetServerPrefsNext to get the next server preference
1844 * No locks are obtained or released by this function
1848 * Returns != 0 upon successful completion.
1853 util_CMGetServerPrefsBegin(struct rx_connection *conn, void **iterationIdP,
1857 afs_status_t tst = 0;
1858 afs_admin_iterator_p iter;
1859 cm_srvr_pref_get_p pref;
1862 tst = ADMRXCONNNULL;
1863 goto fail_util_CMGetServerPrefsBegin;
1866 iter = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1869 goto fail_util_CMGetServerPrefsBegin;
1872 pref = (cm_srvr_pref_get_p) malloc(sizeof(cm_srvr_pref_get_t));
1876 goto fail_util_CMGetServerPrefsBegin;
1882 (iter, (void *)pref, GetServerPrefsRPC, GetServerPrefsFromCache, NULL,
1886 goto fail_util_CMGetServerPrefsBegin;
1888 *iterationIdP = (void *)iter;
1891 fail_util_CMGetServerPrefsBegin:
1900 * util_CMGetServerPrefsNext - Get next entry in cache manager server
1905 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
1907 * OUT prefs - Next entry in cache manager server preferences.
1911 * No locks are obtained or released by this function
1915 * Returns != 0 upon successful completion.
1920 util_CMGetServerPrefsNext(const void *iterationId, afs_CMServerPref_p prefs,
1924 afs_status_t tst = 0;
1925 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
1927 if (iterationId == NULL) {
1928 tst = ADMITERATIONIDPNULL;
1929 goto fail_util_CMGetServerPrefsNext;
1932 rc = IteratorNext(iter, (void *)prefs, &tst);
1934 fail_util_CMGetServerPrefsNext:
1943 * util_CMGetServerPrefsDone - Finish listing cache manager server
1948 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
1952 * No locks are obtained or released by this function
1956 * Returns != 0 upon successful completion.
1961 util_CMGetServerPrefsDone(const void *iterationId, afs_status_p st)
1964 afs_status_t tst = 0;
1965 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
1967 if (iterationId == NULL) {
1968 tst = ADMITERATIONIDPNULL;
1969 goto fail_util_CMGetServerPrefsDone;
1972 rc = IteratorDone(iter, &tst);
1975 fail_util_CMGetServerPrefsDone:
1984 * The iterator for listing CM CellServDB
1987 typedef struct cm_list_cell_get {
1988 struct rx_connection *conn;
1990 afs_CMListCell_t cell[CACHED_ITEMS];
1991 } cm_list_cell_get_t, *cm_list_cell_get_p;
1994 ListCellsRPC(void *rpc_specific, int slot, int *last_item,
1995 int *last_item_contains_data, afs_status_p st)
1998 afs_status_t tst = 0;
1999 cm_list_cell_get_p t = (cm_list_cell_get_p) rpc_specific;
2005 * Get the next entry in the CellServDB.
2007 name = t->cell[slot].cellname;
2008 sl.serverList_len = 0;
2009 sl.serverList_val = NULL;
2010 memset(t->cell[slot].serverAddr, 0, sizeof(afs_int32)*UTIL_MAX_CELL_HOSTS);
2012 RXAFSCB_GetCellServDB(t->conn, t->index, &name, &sl);
2014 goto fail_ListCellsRPC;
2016 strcpy(t->cell[slot].cellname, name);
2017 if (sl.serverList_val) {
2018 for (n=0; n<sl.serverList_len && n<UTIL_MAX_CELL_HOSTS; n++) {
2019 t->cell[slot].serverAddr[n] = sl.serverList_val[n];
2021 xdr_free(sl.serverList_val, sl.serverList_len);
2025 * See if we've processed all the entries
2027 if (strlen(t->cell[slot].cellname) == 0) {
2029 *last_item_contains_data = 0;
2044 ListCellsFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
2047 afs_status_t tst = 0;
2048 cm_list_cell_get_p cell = (cm_list_cell_get_p) rpc_specific;
2050 memcpy(dest, (const void *)&cell->cell[slot], sizeof(afs_CMListCell_t));
2060 * util_CMListCellsBegin - Begin listing cache manager CellServDB
2064 * IN conn - an rx connection to the process to be queried
2066 * OUT iterationIdP - an iteration id that can be passed to
2067 * util_CMListCellsNext to get the next cell
2071 * No locks are obtained or released by this function
2075 * Returns != 0 upon successful completion.
2080 util_CMListCellsBegin(struct rx_connection *conn, void **iterationIdP,
2084 afs_status_t tst = 0;
2085 afs_admin_iterator_p iter;
2086 cm_list_cell_get_p cell;
2089 tst = ADMRXCONNNULL;
2090 goto fail_util_CMListCellsBegin;
2093 iter = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2096 goto fail_util_CMListCellsBegin;
2099 cell = (cm_list_cell_get_p) malloc(sizeof(cm_list_cell_get_t));
2103 goto fail_util_CMListCellsBegin;
2109 (iter, (void *)cell, ListCellsRPC, ListCellsFromCache, NULL, NULL,
2113 goto fail_util_CMListCellsBegin;
2115 *iterationIdP = (void *)iter;
2118 fail_util_CMListCellsBegin:
2127 * util_CMListCellsNext - Get next entry in cache manager cells
2131 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
2133 * OUT cell - Next entry in cache manager cells.
2137 * No locks are obtained or released by this function
2141 * Returns != 0 upon successful completion.
2146 util_CMListCellsNext(const void *iterationId, afs_CMListCell_p cell,
2150 afs_status_t tst = 0;
2151 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2153 if (iterationId == NULL) {
2154 tst = ADMITERATIONIDPNULL;
2155 goto fail_util_CMListCellsNext;
2158 rc = IteratorNext(iter, (void *)cell, &tst);
2160 fail_util_CMListCellsNext:
2169 * util_CMListCellsDone - Finish listing cache manager cells
2173 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
2177 * No locks are obtained or released by this function
2181 * Returns != 0 upon successful completion.
2186 util_CMListCellsDone(const void *iterationId, afs_status_p st)
2189 afs_status_t tst = 0;
2190 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2192 if (iterationId == NULL) {
2193 tst = ADMITERATIONIDPNULL;
2194 goto fail_util_CMListCellsDone;
2197 rc = IteratorDone(iter, &tst);
2200 fail_util_CMListCellsDone:
2209 * util_CMLocalCell - Get the name of the cache manager's local cell.
2213 * IN conn - an rx connection to the process to be queried
2215 * OUT cellName - the name of the cache manager's local cell.
2219 * No locks are obtained or released by this function
2223 * Returns != 0 upon successful completion.
2228 util_CMLocalCell(struct rx_connection *conn, afs_CMCellName_p cellName,
2232 afs_status_t tst = 0;
2233 afs_CMCellName_p name;
2236 tst = ADMRXCONNNULL;
2237 goto fail_util_CMLocalCell;
2240 if (cellName == NULL) {
2241 tst = ADMCLIENTCMCELLNAMENULL;
2242 goto fail_util_CMLocalCell;
2246 tst = RXAFSCB_GetLocalCell(conn, &name);
2252 fail_util_CMLocalCell:
2261 UnmarshallCMClientConfig(afs_uint32 serverVersion, afs_uint32 * ptr,
2262 afs_ClientConfigUnion_p config)
2265 * We currently only support version 1.
2267 config->config_v1.nChunkFiles = *(ptr++);
2268 config->config_v1.nStatCaches = *(ptr++);
2269 config->config_v1.nDataCaches = *(ptr++);
2270 config->config_v1.nVolumeCaches = *(ptr++);
2271 config->config_v1.firstChunkSize = *(ptr++);
2272 config->config_v1.otherChunkSize = *(ptr++);
2273 config->config_v1.cacheSize = *(ptr++);
2274 config->config_v1.setTime = *(ptr++);
2275 config->config_v1.memCache = *(ptr++);
2279 * util_CMClientConfig - Get the cache manager's configuration parameters.
2283 * IN conn - an rx connection to the process to be queried
2285 * OUT config - the cache manager's configuration parameters.
2289 * No locks are obtained or released by this function
2293 * Returns != 0 upon successful completion.
2298 util_CMClientConfig(struct rx_connection *conn, afs_ClientConfig_p config,
2302 afs_status_t tst = 0;
2303 afs_uint32 allocbytes;
2304 struct cacheConfig tconfig;
2307 tst = ADMRXCONNNULL;
2308 goto fail_util_CMClientConfig;
2311 if (config == NULL) {
2312 tst = ADMCLIENTCMCELLNAMENULL;
2313 goto fail_util_CMClientConfig;
2316 config->clientVersion = AFS_CLIENT_RETRIEVAL_VERSION;
2317 tconfig.cacheConfig_val = NULL;
2318 tconfig.cacheConfig_len = 0;
2320 RXAFSCB_GetCacheConfig(conn, config->clientVersion,
2321 &config->serverVersion, &allocbytes, &tconfig);
2324 goto fail_util_CMClientConfig;
2327 UnmarshallCMClientConfig(config->serverVersion, tconfig.cacheConfig_val,
2330 free(tconfig.cacheConfig_val);
2332 fail_util_CMClientConfig:
2341 * util_RXDebugVersion - Get the rxdebug version string.
2345 * IN handle - an rxdebug handle for the process to be queried.
2347 * OUT version - the rxdebug version string.
2351 * No locks are obtained or released by this function
2355 * Returns != 0 upon successful completion.
2360 util_RXDebugVersion(rxdebugHandle_p handle, rxdebugVersion_p version,
2364 afs_status_t tst = 0;
2367 if (handle == NULL) {
2368 tst = ADMRXDEBUGHANDLENULL;
2369 goto fail_util_RXDebugVersion;
2372 if (version == NULL) {
2373 tst = ADMRXDEBUGVERSIONNULL;
2374 goto fail_util_RXDebugVersion;
2378 rx_GetServerVersion(handle->sock, handle->ipAddr, handle->udpPort,
2379 UTIL_MAX_RXDEBUG_VERSION_LEN, version);
2381 tst = ADMCLIENTRXDEBUGTIMEOUT;
2382 goto fail_util_RXDebugVersion;
2387 fail_util_RXDebugVersion:
2396 * util_RXDebugSupportedStats - Get the rxdebug statistics supported by
2401 * IN handle - an rxdebug handle for the process to be queried.
2403 * OUT supportedStats - bit mask with supported rxstats.
2407 * No locks are obtained or released by this function
2411 * Returns != 0 upon successful completion.
2416 util_RXDebugSupportedStats(rxdebugHandle_p handle,
2417 afs_uint32 * supportedStats, afs_status_p st)
2420 afs_status_t tst = 0;
2421 struct rx_debugStats tstats;
2423 if (handle == NULL) {
2424 tst = ADMRXDEBUGHANDLENULL;
2425 goto fail_util_RXDebugSupportedStats;
2428 if (supportedStats == NULL) {
2429 tst = ADMRXDEBUGSTATSNULL;
2430 goto fail_util_RXDebugSupportedStats;
2433 if (handle->firstFlag) {
2434 rc = util_RXDebugBasicStats(handle, &tstats, &tst);
2436 goto fail_util_RXDebugSupportedStats;
2440 *supportedStats = handle->supportedStats;
2443 fail_util_RXDebugSupportedStats:
2453 * util_RXDebugBasicStats - Get the basic rxdebug statistics for the process.
2457 * IN handle - an rxdebug handle for the process to be queried.
2459 * OUT stats - Basic rxdebug statistics for the process.
2463 * No locks are obtained or released by this function
2467 * Returns != 0 upon successful completion.
2472 util_RXDebugBasicStats(rxdebugHandle_p handle, struct rx_debugStats *stats,
2476 afs_status_t tst = 0;
2479 if (handle == NULL) {
2480 tst = ADMRXDEBUGHANDLENULL;
2481 goto fail_util_RXDebugBasicStats;
2484 if (stats == NULL) {
2485 tst = ADMRXDEBUGSTATSNULL;
2486 goto fail_util_RXDebugBasicStats;
2490 rx_GetServerDebug(handle->sock, handle->ipAddr, handle->udpPort,
2491 stats, &handle->supportedStats);
2493 tst = ADMCLIENTRXDEBUGTIMEOUT;
2494 goto fail_util_RXDebugBasicStats;
2497 handle->firstFlag = 0;
2500 fail_util_RXDebugBasicStats:
2510 * util_RXDebugRxStats - Get the detailed rxdebug statistics for the process.
2514 * IN handle - an rxdebug handle for the process to be queried.
2516 * OUT stats - Detailed rxdebug statistics for the process.
2520 * No locks are obtained or released by this function
2524 * Returns != 0 upon successful completion.
2529 util_RXDebugRxStats(rxdebugHandle_p handle, struct rx_statistics *stats,
2530 afs_uint32 * supportedValues, afs_status_p st)
2534 afs_status_t tst = 0;
2536 afs_uint32 tsupported;
2538 if (handle == NULL) {
2539 tst = ADMRXDEBUGHANDLENULL;
2540 goto fail_util_RXDebugRxStats;
2543 if (supportedValues == NULL) {
2544 tst = ADMRXDEBUGSTATSNULL;
2545 goto fail_util_RXDebugRxStats;
2548 if (stats == NULL) {
2549 tst = ADMRXDEBUGSTATSNULL;
2550 goto fail_util_RXDebugRxStats;
2553 if (handle->firstFlag) {
2554 trc = util_RXDebugSupportedStats(handle, &tsupported, &tst);
2557 goto fail_util_RXDebugRxStats;
2561 if (!(handle->supportedStats & RX_SERVER_DEBUG_RX_STATS)) {
2562 tst = ADMCLIENTRXDEBUGNOTSUPPORTED;
2563 goto fail_util_RXDebugRxStats;
2567 rx_GetServerStats(handle->sock, handle->ipAddr, handle->udpPort,
2568 stats, &handle->supportedStats);
2570 tst = ADMCLIENTRXDEBUGTIMEOUT;
2571 goto fail_util_RXDebugRxStats;
2576 fail_util_RXDebugRxStats:
2585 * The iterator for listing RXDebug connections
2588 typedef struct rxdebug_conn_item {
2589 struct rx_debugConn conn;
2590 afs_uint32 supportedValues;
2591 } rxdebug_conn_item_t, *rxdebug_conn_item_p;
2593 typedef struct rxdebug_conn_get {
2595 rxdebugHandle_p handle;
2597 rxdebug_conn_item_t items[CACHED_ITEMS];
2598 } rxdebug_conn_get_t, *rxdebug_conn_get_p;
2601 RXDebugConnsFromServer(void *rpc_specific, int slot, int *last_item,
2602 int *last_item_contains_data, afs_status_p st)
2606 afs_status_t tst = 0;
2607 rxdebug_conn_get_p t = (rxdebug_conn_get_p) rpc_specific;
2610 * Get the next entry the list of connections
2613 rx_GetServerConnections(t->handle->sock, t->handle->ipAddr,
2614 t->handle->udpPort, &t->index, t->allconns,
2615 t->handle->supportedStats,
2616 &t->items[slot].conn,
2617 &t->items[slot].supportedValues);
2619 tst = ADMCLIENTRXDEBUGTIMEOUT;
2620 goto fail_ListCellsRPC;
2624 * See if we've processed all the entries
2626 if (t->items[slot].conn.cid == 0xffffffff) {
2628 *last_item_contains_data = 0;
2641 RXDebugConnsFromCache(void *rpc_specific, int slot, void *dest,
2645 afs_status_t tst = 0;
2646 rxdebug_conn_get_p t = (rxdebug_conn_get_p) rpc_specific;
2648 memcpy(dest, (const void *)&t->items[slot], sizeof(rxdebug_conn_item_t));
2658 * util_RXDebugConnectionsBegin - Begin listing rxdebug connection information
2663 * IN handle - an rxdebug handle for the process to be queried
2665 * IN allcons - non-zero to list all connections. If zero, only
2666 * "interesting" connections will be listed.
2668 * OUT iterationIdP - an iteration id that can be passed to
2669 * util_RXDebugConnectionsNext.
2673 * No locks are obtained or released by this function
2677 * Returns != 0 upon successful completion.
2682 util_RXDebugConnectionsBegin(rxdebugHandle_p handle, int allconns,
2683 void **iterationIdP, afs_status_p st)
2687 afs_uint32 tsupported;
2688 afs_status_t tst = 0;
2689 afs_admin_iterator_p iter;
2690 rxdebug_conn_get_p t;
2692 if (handle == NULL) {
2693 tst = ADMRXDEBUGHANDLENULL;
2694 goto fail_util_RXDebugConnectionsBegin;
2697 iter = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2700 goto fail_util_RXDebugConnectionsBegin;
2703 if (handle->firstFlag) {
2704 trc = util_RXDebugSupportedStats(handle, &tsupported, &tst);
2707 goto fail_util_RXDebugConnectionsBegin;
2711 if (allconns && !(handle->supportedStats & RX_SERVER_DEBUG_ALL_CONN)) {
2712 tst = ADMCLIENTRXDEBUGNOTSUPPORTED;
2713 goto fail_util_RXDebugConnectionsBegin;
2716 t = (rxdebug_conn_get_p) malloc(sizeof(rxdebug_conn_get_t));
2720 goto fail_util_RXDebugConnectionsBegin;
2723 t->allconns = allconns;
2727 (iter, (void *)t, RXDebugConnsFromServer, RXDebugConnsFromCache, NULL,
2729 goto fail_util_RXDebugConnectionsBegin;
2731 *iterationIdP = (void *)iter;
2734 fail_util_RXDebugConnectionsBegin:
2744 * util_RXDebugConnectionsNext - Get rxdebug information for the next
2749 * IN iterationId - Iteration id created by util_RXDebugConnectionsNext.
2751 * OUT conn - Rxdebug information for the next connection.
2753 * OUT supportedValues - Bit mask of supported rxdebug values.
2757 * No locks are obtained or released by this function
2761 * Returns != 0 upon successful completion.
2766 util_RXDebugConnectionsNext(const void *iterationId,
2767 struct rx_debugConn *conn,
2768 afs_uint32 * supportedValues, afs_status_p st)
2771 afs_status_t tst = 0;
2772 rxdebug_conn_item_t item;
2773 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2775 if (iterationId == NULL) {
2776 tst = ADMITERATIONIDPNULL;
2777 goto fail_util_RXDebugConnectionsNext;
2781 tst = ADMRXDEBUGHANDLENULL;
2782 goto fail_util_RXDebugConnectionsNext;
2785 if (supportedValues == NULL) {
2786 tst = ADMRXDEBUGHANDLENULL;
2787 goto fail_util_RXDebugConnectionsNext;
2790 rc = IteratorNext(iter, (void *)&item, &tst);
2792 goto fail_util_RXDebugConnectionsNext;
2796 *supportedValues = item.supportedValues;
2798 fail_util_RXDebugConnectionsNext:
2808 * util_RXDebugConnectionsDone - Finish listing rxdebug connection information.
2812 * IN iterationId - Iteration id created by util_RXDebugConnectionsBegin.
2816 * No locks are obtained or released by this function
2820 * Returns != 0 upon successful completion.
2825 util_RXDebugConnectionsDone(const void *iterationId, afs_status_p st)
2828 afs_status_t tst = 0;
2829 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2832 * Validate parameters
2836 tst = ADMITERATORNULL;
2837 goto fail_util_RXDebugConnectionsDone;
2840 rc = IteratorDone(iter, &tst);
2842 fail_util_RXDebugConnectionsDone:
2852 * The iterator for listing RXDebug peer
2855 typedef struct rxdebug_peer_item {
2856 struct rx_debugPeer peer;
2857 afs_uint32 supportedValues;
2858 } rxdebug_peer_item_t, *rxdebug_peer_item_p;
2860 typedef struct rxdebug_peer_get {
2861 rxdebugHandle_p handle;
2863 rxdebug_peer_item_t items[CACHED_ITEMS];
2864 } rxdebug_peer_get_t, *rxdebug_peer_get_p;
2867 RXDebugPeersFromServer(void *rpc_specific, int slot, int *last_item,
2868 int *last_item_contains_data, afs_status_p st)
2872 afs_status_t tst = 0;
2873 rxdebug_peer_get_p t = (rxdebug_peer_get_p) rpc_specific;
2876 * Get the next entry the list of peers
2879 rx_GetServerPeers(t->handle->sock, t->handle->ipAddr,
2880 t->handle->udpPort, &t->index,
2881 t->handle->supportedStats, &t->items[slot].peer,
2882 &t->items[slot].supportedValues);
2884 tst = ADMCLIENTRXDEBUGTIMEOUT;
2885 goto fail_ListCellsRPC;
2889 * See if we've processed all the entries
2891 if (t->items[slot].peer.host == 0xffffffff) {
2893 *last_item_contains_data = 0;
2906 RXDebugPeersFromCache(void *rpc_specific, int slot, void *dest,
2910 afs_status_t tst = 0;
2911 rxdebug_peer_get_p t = (rxdebug_peer_get_p) rpc_specific;
2913 memcpy(dest, (const void *)&t->items[slot], sizeof(rxdebug_peer_item_t));
2924 * util_RXDebugPeersBegin - Begin listing rxdebug peer information for
2929 * IN handle - an rxdebug handle for the process to be queried
2931 * OUT iterationIdP - an iteration id that can be passed to
2932 * util_RXDebugPeersNext.
2936 * No locks are obtained or released by this function
2940 * Returns != 0 upon successful completion.
2945 util_RXDebugPeersBegin(rxdebugHandle_p handle, void **iterationIdP,
2950 afs_uint32 tsupported;
2951 afs_status_t tst = 0;
2952 afs_admin_iterator_p iter;
2953 rxdebug_peer_get_p t;
2955 if (handle == NULL) {
2956 tst = ADMRXDEBUGHANDLENULL;
2957 goto fail_util_RXDebugPeersBegin;
2960 iter = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2963 goto fail_util_RXDebugPeersBegin;
2966 if (handle->firstFlag) {
2967 trc = util_RXDebugSupportedStats(handle, &tsupported, &tst);
2970 goto fail_util_RXDebugPeersBegin;
2974 if (!(handle->supportedStats & RX_SERVER_DEBUG_ALL_PEER)) {
2975 tst = ADMCLIENTRXDEBUGNOTSUPPORTED;
2976 goto fail_util_RXDebugPeersBegin;
2979 t = (rxdebug_peer_get_p) malloc(sizeof(rxdebug_peer_get_t));
2983 goto fail_util_RXDebugPeersBegin;
2989 (iter, (void *)t, RXDebugPeersFromServer, RXDebugPeersFromCache, NULL,
2991 goto fail_util_RXDebugPeersBegin;
2993 *iterationIdP = (void *)iter;
2996 fail_util_RXDebugPeersBegin:
3005 * util_RXDebugPeersNext - Get rxdebug information for the next peer.
3009 * IN iterationId - Iteration id created by util_RXDebugPeersBegin.
3011 * OUT peer - Rxdebug information for the next peer.
3013 * OUT supportedValues - Bit mask of supported rxdebug values.
3017 * No locks are obtained or released by this function
3021 * Returns != 0 upon successful completion.
3025 util_RXDebugPeersNext(const void *iterationId, struct rx_debugPeer *peer,
3026 afs_uint32 * supportedValues, afs_status_p st)
3029 afs_status_t tst = 0;
3030 rxdebug_peer_item_t item;
3031 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3033 if (iterationId == NULL) {
3034 tst = ADMITERATIONIDPNULL;
3035 goto fail_util_RXDebugPeersNext;
3039 tst = ADMRXDEBUGHANDLENULL;
3040 goto fail_util_RXDebugPeersNext;
3043 if (supportedValues == NULL) {
3044 tst = ADMRXDEBUGHANDLENULL;
3045 goto fail_util_RXDebugPeersNext;
3048 rc = IteratorNext(iter, (void *)&item, &tst);
3050 goto fail_util_RXDebugPeersNext;
3054 *supportedValues = item.supportedValues;
3056 fail_util_RXDebugPeersNext:
3065 * util_RXDebugPeersDone - Finish listing rxdebug peer information.
3069 * IN iterationId - Iteration id created by util_RXDebugPeersBegin.
3073 * No locks are obtained or released by this function
3077 * Returns != 0 upon successful completion.
3082 util_RXDebugPeersDone(const void *iterationId, afs_status_p st)
3085 afs_status_t tst = 0;
3086 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3089 * Validate parameters
3093 tst = ADMITERATORNULL;
3094 goto fail_util_RXDebugPeersDone;
3097 rc = IteratorDone(iter, &tst);
3099 fail_util_RXDebugPeersDone: