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>
17 #include <rx/rxstat.h>
20 # include <afs/krb5_nt.h>
23 #include <afs/afs_Admin.h>
24 #include <afs/pthread_glock.h>
25 #include <afs/cellconfig.h>
26 #include <afs/dirpath.h>
27 #include <afs/com_err.h>
28 #include <afs/kautils.h>
30 #include <afs/vlserver.h>
31 #include <afs/pterror.h>
32 #include <afs/bnode.h>
33 #include <afs/afscbint.h>
34 #include <afs/volser.h>
36 #include "afs_AdminInternal.h"
37 #include "afs_utilAdmin.h"
40 * AIX 4.2 has PTHREAD_CREATE_UNDETACHED and not PTHREAD_CREATE_JOINABLE
42 * This fix should be done more centrally, but there's no time right now.
44 #if defined(AFS_AIX_ENV)
45 # if !defined(PTHREAD_CREATE_JOINABLE) && defined(PTHREAD_CREATE_UNDETACHED)
46 # define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED
50 #define ERRCODE_RANGE 8
51 static pthread_once_t error_init_once
= PTHREAD_ONCE_INIT
;
52 static int error_init_done
;
58 initialize_KA_error_table();
59 initialize_RXK_error_table();
60 initialize_KTC_error_table();
61 initialize_ACFG_error_table();
62 initialize_CMD_error_table();
63 initialize_VL_error_table();
64 initialize_PT_error_table();
65 initialize_BZ_error_table();
66 initialize_U_error_table();
67 initialize_AB_error_table();
68 initialize_AF_error_table();
69 initialize_AL_error_table();
70 initialize_AC_error_table();
71 initialize_AK_error_table();
72 initialize_AM_error_table();
73 initialize_AP_error_table();
74 initialize_AU_error_table();
75 initialize_AV_error_table();
76 initialize_VOLS_error_table();
77 #ifdef AFS_KRB5_ERROR_ENV
84 * (*errorTextP) will not be freed by the caller.
87 util_AdminErrorCodeTranslate(afs_status_t errorCode
, int langId
,
88 const char **errorTextP
, afs_status_p st
)
94 if (errorTextP
== NULL
) {
95 tst
= ADMUTILERRORTEXTPNULL
;
96 goto fail_util_AdminErrorCodeTranslate
;
100 * Translate the error
103 if (!error_init_done
)
104 pthread_once(&error_init_once
, init_once
);
105 code
= (afs_int32
) errorCode
;
106 *errorTextP
= afs_error_message(code
);
107 #ifdef AFS_KRB5_ERROR_ENV
108 if (strncmp(*errorTextP
, "unknown", strlen("unknown")) == 0) {
109 const char *msg
= fetch_krb5_error_message(code
);
116 fail_util_AdminErrorCodeTranslate
:
125 * The iterator functions and data for the database server retrieval functions.
128 typedef struct database_server_get
{
131 struct afsconf_dir
*conf
;
132 struct afsconf_cell cell
;
133 util_databaseServerEntry_t server
[CACHED_ITEMS
];
134 } database_server_get_t
, *database_server_get_p
;
137 GetDatabaseServerRPC(void *rpc_specific
, int slot
, int *last_item
,
138 int *last_item_contains_data
, afs_status_p st
)
141 afs_status_t tst
= 0;
142 database_server_get_p serv
= (database_server_get_p
) rpc_specific
;
144 serv
->server
[slot
].serverAddress
=
145 ntohl(serv
->cell
.hostAddr
[serv
->index
].sin_addr
.s_addr
);
146 strcpy(serv
->server
[slot
].serverName
, serv
->cell
.hostName
[serv
->index
]);
150 * See if we've processed all the entries
153 if (serv
->index
== serv
->total
) {
155 *last_item_contains_data
= 1;
166 GetDatabaseServerFromCache(void *rpc_specific
, int slot
, void *dest
,
170 afs_status_t tst
= 0;
171 database_server_get_p serv
= (database_server_get_p
) rpc_specific
;
173 memcpy(dest
, (const void *)&serv
->server
[slot
],
174 sizeof(util_databaseServerEntry_t
));
184 DestroyDatabaseServer(void *rpc_specific
, afs_status_p st
)
187 afs_status_t tst
= 0;
188 database_server_get_p serv
= (database_server_get_p
) rpc_specific
;
190 afsconf_Close(serv
->conf
);
200 * util_DatabaseServerGetBegin - begin iterating over the database
201 * server machines in a cell.
205 * IN cellName - the cell where database servers reside.
207 * OUT iterationIdP - upon successful completion contains an iterator that
208 * can be passed to util_DatabaseServerGetNext.
212 * No locks are obtained or released by this function
220 * Returns != 0 upon successful completion.
224 util_DatabaseServerGetBegin(const char *cellName
, void **iterationIdP
,
228 afs_status_t tst
= 0;
229 afs_admin_iterator_p iter
= malloc(sizeof(afs_admin_iterator_t
));
230 database_server_get_p serv
= calloc(1, sizeof(database_server_get_t
));
231 char copyCell
[MAXCELLCHARS
];
237 if ((cellName
== NULL
) || (*cellName
== 0)) {
238 tst
= ADMUTILCELLNAMENULL
;
239 goto fail_util_DatabaseServerGetBegin
;
242 if (iterationIdP
== NULL
) {
243 goto fail_util_DatabaseServerGetBegin
;
246 if ((iter
== NULL
) || (serv
== NULL
)) {
248 goto fail_util_DatabaseServerGetBegin
;
252 * Fill in the serv structure
255 serv
->conf
= afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH
);
256 if (serv
->conf
== NULL
) {
257 tst
= ADMUTILCANTOPENCELLSERVDB
;
258 goto fail_util_DatabaseServerGetBegin
;
262 * We must copy the cellname because afsconf_GetCellInfo
263 * actually writes over the cell name it is passed.
265 strncpy(copyCell
, cellName
, MAXCELLCHARS
- 1);
267 afsconf_GetCellInfo(serv
->conf
, copyCell
, AFSCONF_KAUTHSERVICE
,
270 goto fail_util_DatabaseServerGetBegin
;
273 serv
->total
= serv
->cell
.numServers
;
275 (iter
, (void *)serv
, GetDatabaseServerRPC
, GetDatabaseServerFromCache
,
276 NULL
, DestroyDatabaseServer
, &tst
)) {
277 *iterationIdP
= (void *)iter
;
279 goto fail_util_DatabaseServerGetBegin
;
283 fail_util_DatabaseServerGetBegin
:
301 * util_DatabaseServerGetNext - get the next server address.
305 * IN iterationId - an iterator returned by util_DatabaseServerGetBegin
307 * OUT serverAddressP - upon successful completion contains the next
308 * server address in the cell.
312 * This function locks the iterator for the duration of its processing.
320 * Returns != 0 upon successful completion.
325 util_DatabaseServerGetNext(const void *iterationId
,
326 util_databaseServerEntry_p serverP
,
330 afs_status_t tst
= 0;
331 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
334 tst
= ADMITERATORNULL
;
335 goto fail_util_DatabaseServerGetNext
;
338 if (serverP
== NULL
) {
339 tst
= ADMUTILSERVERADDRESSPNULL
;
340 goto fail_util_DatabaseServerGetNext
;
343 rc
= IteratorNext(iter
, (void *)serverP
, &tst
);
345 fail_util_DatabaseServerGetNext
:
354 * util_DatabaseServerGetDone - stop using a database iterator.
358 * IN iterationId - an iterator returned by util_DatabaseServerGetBegin
362 * This function locks the iterator for the duration of its processing.
363 * And then destroys it before returning.
371 * Returns != 0 upon successful completion.
375 util_DatabaseServerGetDone(const void *iterationId
, afs_status_p st
)
378 afs_status_t tst
= 0;
379 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
382 * Validate parameters
386 tst
= ADMITERATORNULL
;
387 goto fail_util_DatabaseServerGetDone
;
390 rc
= IteratorDone(iter
, &tst
);
392 fail_util_DatabaseServerGetDone
:
401 * GetServerAddressFromName - translate a character string server name
402 * to an integer representation of an IP address.
406 * IN serverName - the character string server name in either foo.com
407 * format, or 123.12.1.1 format.
409 * OUT serverAddress - an integer that is filled with the correct address
410 * in host byte order upon successful completion.
414 * No locks are obtained or released by this function
418 * On many platforms, gethostbyname is not thread safe. Since we are
419 * only working under NT for now I'll use it directly. In future UNIX
420 * ports, a wrapper function should be written to call the correct function
421 * on the particular platform.
425 * Returns != 0 upon successful completion.
429 util_AdminServerAddressGetFromName(const char *serverName
, int *serverAddress
,
433 afs_status_t tst
= 0;
434 struct hostent
*server
;
435 int part1
, part2
, part3
, part4
;
438 if ((serverName
== NULL
) || (*serverName
== 0)) {
439 tst
= ADMUTILSERVERNAMENULL
;
440 goto fail_util_AdminServerAddressGetFromName
;
443 if (serverAddress
== NULL
) {
444 tst
= ADMUTILSERVERADDRESSNULL
;
445 goto fail_util_AdminServerAddressGetFromName
;
449 sscanf(serverName
, "%d.%d.%d.%d", &part1
, &part2
, &part3
, &part4
);
450 if (num_converted
== 4) {
451 *serverAddress
= (part1
<< 24) | (part2
<< 16) | (part3
<< 8) | part4
;
454 server
= gethostbyname(serverName
);
455 if (server
!= NULL
) {
456 memcpy((void *)serverAddress
, (const void *)server
->h_addr
,
458 *serverAddress
= ntohl(*serverAddress
);
460 tst
= ADMUTILCANTGETSERVERNAME
;
462 goto fail_util_AdminServerAddressGetFromName
;
468 fail_util_AdminServerAddressGetFromName
:
478 * This file contains functions that can be used to create iterator
479 * functions within the api. I have attempted to make these functions
480 * generic so that they can be used across the admin components.
482 * The functions in this file are a generalized producer/consumer
483 * implementation. They manage access to a queue of data. The only
484 * assumption these functions make about this data is that it is
485 * stored in a queue which is implemented via an array. These functions
486 * know about the index into the array, but they know nothing about
487 * the contents of the array.
489 * The data specific functions you implement will have to create some
490 * data specific storage structure that will have an array
491 * of size CACHED_ITEMS data items. This structure will also need to
492 * store any necessary parameters/state variables you need to issue the
493 * rpc to retrieve the next item.
495 * In order to use the generic functions, you must implement four functions
496 * for each type of data you wish to retrieve. The functions are:
498 * validate_specific_data_func - this function is handed a void pointer
499 * that points to the rpc specific data you've allocated. The function
500 * should examine the data for validity and return an appropriate error.
501 * This function is called every time the iterator is validated.
503 * destroy_specific_data_func - this function is handed a void pointer
504 * that points to the rpc specific data you've allocated. It should
505 * destroy any components of the specific data as required and then
506 * return. The void pointer is free'd by the generic functions.
508 * get_cached_data_func - this function is handed a void pointer
509 * that points to the rpc specific data you've allocated, an index
510 * into the cache of the item to be copied to the caller, and a void
511 * pointer where the cache item should be copied.
513 * make_rpc_func - this function is handed a void pointer that points
514 * to the rpc specific data you've allocated, an index into the cache
515 * of the item to be filled with the next retrieved item, and an int
516 * pointer that should be set to 1 if there are no more items to be
517 * retrieved. The assumption made by the generic functions is that
518 * the last_item status requires an individual rpc - the data isn't
519 * piggybacked on the last data item.
523 * IteratorDelete - delete an iterator.
527 * IN interator - the iterator to delete.
531 * No locks are held by this function.
535 * Returns != 0 upon successful completion.
539 IteratorDelete(afs_admin_iterator_p iter
, afs_status_p st
)
542 afs_status_t tst
= 0;
544 if (pthread_mutex_destroy(&iter
->mutex
)) {
545 tst
= ADMMUTEXDESTROY
;
546 goto fail_IteratorDelete
;
548 if (pthread_cond_destroy(&iter
->add_item
)) {
549 tst
= ADMCONDDESTROY
;
550 goto fail_IteratorDelete
;
552 if (pthread_cond_destroy(&iter
->remove_item
)) {
553 tst
= ADMCONDDESTROY
;
554 goto fail_IteratorDelete
;
557 if (iter
->destroy_specific
!= NULL
) {
558 iter
->destroy_specific(iter
->rpc_specific
, &tst
);
560 free(iter
->rpc_specific
);
573 * DataGet - the background thread that is spawned for every
574 * IteratorBegin call that is successful. This thread tries
575 * to fetch the data from the server ahead of the
576 * IteratorNext calls.
580 * IN arg - the address of the iterator structure to be used for this
585 * The iterator mutex is used by this function to protect elements
586 * of the iterator structure.
590 * Returns != 0 upon successful completion.
596 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) arg
;
598 afs_status_t tst
= 0;
599 int mutex_locked
= 0;
601 int last_item_contains_data
= 0;
603 if (pthread_mutex_lock(&iter
->mutex
)) {
604 iter
->st
= ADMMUTEXLOCK
;
613 * Check to see if there's room for this datum. If not, wait
614 * on the consumer to free up another slot.
617 while (iter
->cache_slots_used
== CACHED_ITEMS
) {
618 if (pthread_cond_wait(&iter
->remove_item
, &iter
->mutex
)) {
619 iter
->st
= ADMCONDWAIT
;
625 * Check to see if someone called Done and terminated the request.
626 * We could have gone to sleep above when the buffer was full and
627 * instead of being awoken because another slot is open, we were
628 * awoken because the request was terminated.
631 if (iter
->request_terminated
) {
635 if (pthread_mutex_unlock(&iter
->mutex
)) {
636 iter
->st
= ADMMUTEXUNLOCK
;
643 * Make an rpc without holding the iter mutex
644 * We reference an item in the principal cache here without
645 * holding the mutex. This is safe because:
646 * 1. The iter structure is ref counted and won't be deleted
647 * from underneath us.
648 * 2. cache_queue_tail is always one item ahead of the consumer
649 * thread so we are the only thread accessing this member.
652 iter
->make_rpc(iter
->rpc_specific
, iter
->cache_queue_tail
, &last_item
,
653 &last_item_contains_data
, &tst
);
655 if (pthread_mutex_lock(&iter
->mutex
)) {
656 iter
->st
= ADMMUTEXLOCK
;
663 * Check to see if someone called Done and terminated the request
666 if (iter
->request_terminated
) {
671 * Check the rc of the rpc, and see if there are no more items
681 * Check to see if this is the last item produced by the rpc.
682 * If it isn't, add the item to the cache and proceed.
683 * If it is, check to see if the last item contains valid data.
684 * If it contains valid data, we need to add it to our cache.
685 * If it doesn't, we mark the iterator as complete.
688 if ((!last_item
) || ((last_item
) && (last_item_contains_data
))) {
689 iter
->cache_queue_tail
=
690 (iter
->cache_queue_tail
+ 1) % CACHED_ITEMS
;
691 iter
->cache_slots_used
++;
694 iter
->st
= ADMITERATORDONE
;
695 iter
->done_iterating
= 1;
697 * There's a small chance that the consumer emptied the
698 * cache queue while we were making the last rpc and has
699 * since gone to sleep waiting for more data. In this case
700 * there will never be more data so we signal him here.
702 pthread_cond_signal(&iter
->add_item
);
708 * If the cache was empty and we just added another item, signal
712 if (iter
->cache_slots_used
== 1) {
713 if (pthread_cond_signal(&iter
->add_item
)) {
714 iter
->st
= ADMCONDSIGNAL
;
724 * If we are exiting with an error, signal the consumer in the event
725 * they were waiting for us to produce more data
729 pthread_cond_signal(&iter
->add_item
);
733 pthread_mutex_unlock(&iter
->mutex
);
740 * IsValidIterator - verify the validity of a afs_admin_iterator_t.
744 * IN interator - the interator to be verified.
748 * We assume the iter->mutex lock is already held.
752 * Returns != 0 upon successful completion.
756 IsValidIterator(const afs_admin_iterator_p iterator
, afs_status_p st
)
759 afs_status_t tst
= 0;
762 * Validate input parameters
765 if (iterator
== NULL
) {
766 tst
= ADMITERATORNULL
;
767 goto fail_IsValidIterator
;
770 if ((iterator
->begin_magic
!= BEGIN_MAGIC
)
771 || (iterator
->end_magic
!= END_MAGIC
)) {
772 tst
= ADMITERATORBADMAGICNULL
;
773 goto fail_IsValidIterator
;
776 if (iterator
->is_valid
== 0) {
777 tst
= ADMITERATORINVALID
;
778 goto fail_IsValidIterator
;
782 * Call the iterator specific validation function
785 if (iterator
->validate_specific
!= NULL
) {
786 if (!iterator
->validate_specific(iterator
->rpc_specific
, &tst
)) {
787 goto fail_IsValidIterator
;
792 fail_IsValidIterator
:
801 * IteratorNext - return the next datum in an interator.
805 * IN interator - the iterator containing the data.
807 * IN dest - the address where the data should be copied.
811 * Lock the iterator upon entry, and hold it during the duration of this
816 * Returns != 0 upon successful completion.
820 IteratorNext(afs_admin_iterator_p iter
, void *dest
, afs_status_p st
)
823 afs_status_t tst
= 0;
827 * We have to lock the iterator before we validate it
830 if (pthread_mutex_lock(&iter
->mutex
)) {
832 goto fail_IteratorNext
;
837 if (!IsValidIterator(iter
, &tst
)) {
838 goto fail_IteratorNext
;
841 if (iter
->request_terminated
== 1) {
842 tst
= ADMITERATORTERMINATED
;
843 goto fail_IteratorNext
;
846 if ((iter
->st
!= AFS_STATUS_OK
) && (iter
->st
!= ADMITERATORDONE
)) {
848 goto fail_IteratorNext
;
852 * Check to see if there are any queue'd items. If not, wait here
853 * until signalled by the producer.
856 while (iter
->cache_slots_used
== 0) {
859 * Maybe the producer experienced an rpc failure.
862 if ((!iter
->done_iterating
) && (iter
->st
!= 0)) {
864 goto fail_IteratorNext
;
868 * Maybe there are no queue'd items because the producer is done
871 if (iter
->done_iterating
) {
873 goto fail_IteratorNext
;
876 if (pthread_cond_wait(&iter
->add_item
, &iter
->mutex
)) {
878 goto fail_IteratorNext
;
883 * Copy the next cached item and update the cached item count
884 * and the index into the cache array
888 get_cached_data(iter
->rpc_specific
, iter
->cache_queue_head
, dest
,
890 goto fail_IteratorNext
;
893 iter
->cache_queue_head
= (iter
->cache_queue_head
+ 1) % CACHED_ITEMS
;
894 iter
->cache_slots_used
--;
897 * If the cache was full before we removed the item above, the
898 * producer may have been waiting for us to remove an item.
899 * Signal the producer letting him know that we've opened a slot
903 if (iter
->cache_slots_used
== (CACHED_ITEMS
- 1)) {
904 if (pthread_cond_signal(&iter
->remove_item
)) {
906 goto fail_IteratorNext
;
914 if (locked_iter
== 1) {
915 pthread_mutex_unlock(&iter
->mutex
);
925 * IteratorDone - mark the iterator done.
929 * IN interator - the iterator to mark done.
933 * Lock the iterator upon entry, and hold it during the duration of this
938 * Returns != 0 upon successful completion.
942 IteratorDone(afs_admin_iterator_p iter
, afs_status_p st
)
945 afs_status_t tst
= 0;
946 int mutex_locked
= 1;
948 if (pthread_mutex_lock(&iter
->mutex
)) {
950 goto fail_IteratorDone
;
956 if (!IsValidIterator(iter
, &tst
)) {
957 goto fail_IteratorDone
;
962 * Depending upon the status of the background worker thread,
963 * we can either join with him immediately (if we know he has
964 * terminated), or we need to tell him the request has been
965 * terminated and then join with him.
968 if (!iter
->done_iterating
) {
969 iter
->request_terminated
= 1;
970 iter
->cache_slots_used
= 0;
971 pthread_cond_signal(&iter
->remove_item
);
975 * We have to unlock the mutex to allow the background thread to
979 if (pthread_mutex_unlock(&iter
->mutex
)) {
980 tst
= ADMMUTEXUNLOCK
;
981 goto fail_IteratorDone
;
984 if (iter
->make_rpc
!= NULL
) {
985 if (pthread_join(iter
->bg_worker
, (void **)0)) {
987 goto fail_IteratorDone
;
992 * We don't relock the mutex here since we are the only thread
993 * that has access to the iter now
996 rc
= IteratorDelete(iter
, &tst
);
1002 pthread_mutex_unlock(&iter
->mutex
);
1012 * IteratorInit - initialize an iterator.
1016 * IN interator - the iterator to initialize.
1020 * No locks are held by this function.
1024 * Returns != 0 upon successful completion.
1028 IteratorInit(afs_admin_iterator_p iter
, void *rpc_specific
,
1029 make_rpc_func make_rpc
, get_cached_data_func get_cached_data
,
1030 validate_specific_data_func validate_specific_data
,
1031 destroy_specific_data_func destroy_specific_data
,
1035 afs_status_t tst
= 0;
1036 int mutex_inited
= 0;
1037 int add_item_cond_inited
= 0;
1038 int remove_item_cond_inited
= 0;
1041 tst
= ADMITERATORNULL
;
1042 goto fail_IteratorInit
;
1045 if (rpc_specific
== NULL
) {
1046 tst
= ADMITERATORRPCSPECIFICNULL
;
1047 goto fail_IteratorInit
;
1051 * Initialize the iterator structure
1053 iter
->begin_magic
= BEGIN_MAGIC
;
1054 iter
->end_magic
= END_MAGIC
;
1056 iter
->cache_slots_used
= 0;
1057 iter
->done_iterating
= 0;
1058 iter
->request_terminated
= 0;
1059 iter
->st
= AFS_STATUS_OK
;
1060 iter
->cache_queue_head
= 0;
1061 iter
->cache_queue_tail
= 0;
1062 iter
->cache_slots_used
= 0;
1063 iter
->rpc_specific
= rpc_specific
;
1064 iter
->make_rpc
= make_rpc
;
1065 iter
->get_cached_data
= get_cached_data
;
1066 iter
->validate_specific
= validate_specific_data
;
1067 iter
->destroy_specific
= destroy_specific_data
;
1069 if (pthread_mutex_init(&iter
->mutex
, (const pthread_mutexattr_t
*)0)) {
1071 goto fail_IteratorInit
;
1076 if (pthread_cond_init(&iter
->add_item
, (const pthread_condattr_t
*)0)) {
1078 goto fail_IteratorInit
;
1080 add_item_cond_inited
= 1;
1083 if (pthread_cond_init(&iter
->remove_item
, (const pthread_condattr_t
*)0)) {
1085 goto fail_IteratorInit
;
1087 remove_item_cond_inited
= 1;
1091 * Create a worker thread that will begin to query the server
1092 * and cache responses.
1095 if (iter
->make_rpc
!= NULL
) {
1096 pthread_attr_t tattr
;
1098 if (pthread_attr_init(&tattr
)) {
1099 tst
= ADMTHREADATTRINIT
;
1100 goto fail_IteratorInit
;
1103 if (pthread_attr_setdetachstate(&tattr
, PTHREAD_CREATE_JOINABLE
)) {
1104 tst
= ADMTHREADATTRSETDETACHSTATE
;
1105 goto fail_IteratorInit
;
1108 if (pthread_create(&iter
->bg_worker
, &tattr
, DataGet
, (void *)iter
)) {
1109 tst
= ADMTHREADCREATE
;
1110 goto fail_IteratorInit
;
1119 pthread_mutex_destroy(&iter
->mutex
);
1121 if (remove_item_cond_inited
) {
1122 pthread_cond_destroy(&iter
->remove_item
);
1124 if (add_item_cond_inited
) {
1125 pthread_cond_destroy(&iter
->add_item
);
1136 CellHandleIsValid(const void *cellHandle
, afs_status_p st
)
1139 afs_status_t tst
= 0;
1140 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1143 * Validate input parameters
1146 if (c_handle
== NULL
) {
1147 tst
= ADMCLIENTCELLHANDLENULL
;
1148 goto fail_CellHandleIsValid
;
1151 if ((c_handle
->begin_magic
!= BEGIN_MAGIC
)
1152 || (c_handle
->end_magic
!= END_MAGIC
)) {
1153 tst
= ADMCLIENTCELLHANDLEBADMAGIC
;
1154 goto fail_CellHandleIsValid
;
1157 if (c_handle
->is_valid
== 0) {
1158 tst
= ADMCLIENTCELLINVALID
;
1159 goto fail_CellHandleIsValid
;
1163 fail_CellHandleIsValid
:
1172 * The iterator functions and data for the rpc statistic retrieval functions
1175 typedef struct rpc_stat_get
{
1176 afs_uint32 clock_sec
;
1177 afs_uint32 clock_usec
;
1180 afs_uint32 clientVersion
;
1181 afs_uint32 serverVersion
;
1182 struct rpcStats stat_list
;
1183 afs_RPCStats_t stats
[CACHED_ITEMS
];
1184 afs_uint32
*pointer
;
1185 } rpc_stat_get_t
, *rpc_stat_get_p
;
1188 UnmarshallRPCStats(afs_uint32 serverVersion
, afs_uint32
** ptrP
,
1192 unsigned int hi
, lo
;
1195 * Server must always match lower versions. We are version 1.
1198 s
->stats_v1
.remote_peer
= *(ptr
++);
1199 s
->stats_v1
.remote_port
= *(ptr
++);
1200 s
->stats_v1
.remote_is_server
= *(ptr
++);
1201 s
->stats_v1
.interfaceId
= *(ptr
++);
1202 s
->stats_v1
.func_total
= *(ptr
++);
1203 s
->stats_v1
.func_index
= *(ptr
++);
1206 s
->stats_v1
.invocations
= ((afs_uint64
) hi
<< 32) + lo
;
1209 s
->stats_v1
.bytes_sent
= ((afs_uint64
) hi
<< 32) + lo
;
1212 s
->stats_v1
.bytes_rcvd
= ((afs_uint64
) hi
<< 32) + lo
;
1213 s
->stats_v1
.queue_time_sum
.sec
= *(ptr
++);
1214 s
->stats_v1
.queue_time_sum
.usec
= *(ptr
++);
1215 s
->stats_v1
.queue_time_sum_sqr
.sec
= *(ptr
++);
1216 s
->stats_v1
.queue_time_sum_sqr
.usec
= *(ptr
++);
1217 s
->stats_v1
.queue_time_min
.sec
= *(ptr
++);
1218 s
->stats_v1
.queue_time_min
.usec
= *(ptr
++);
1219 s
->stats_v1
.queue_time_max
.sec
= *(ptr
++);
1220 s
->stats_v1
.queue_time_max
.usec
= *(ptr
++);
1221 s
->stats_v1
.execution_time_sum
.sec
= *(ptr
++);
1222 s
->stats_v1
.execution_time_sum
.usec
= *(ptr
++);
1223 s
->stats_v1
.execution_time_sum_sqr
.sec
= *(ptr
++);
1224 s
->stats_v1
.execution_time_sum_sqr
.usec
= *(ptr
++);
1225 s
->stats_v1
.execution_time_min
.sec
= *(ptr
++);
1226 s
->stats_v1
.execution_time_min
.usec
= *(ptr
++);
1227 s
->stats_v1
.execution_time_max
.sec
= *(ptr
++);
1228 s
->stats_v1
.execution_time_max
.usec
= *(ptr
++);
1233 GetRPCStatsRPC(void *rpc_specific
, int slot
, int *last_item
,
1234 int *last_item_contains_data
, afs_status_p st
)
1237 afs_status_t tst
= 0;
1238 rpc_stat_get_p t
= (rpc_stat_get_p
) rpc_specific
;
1240 t
->stats
[slot
].clientVersion
= t
->clientVersion
;
1241 t
->stats
[slot
].serverVersion
= t
->serverVersion
;
1242 t
->stats
[slot
].statCount
= t
->total
;
1245 * If the server stat version is greater than or equal to my version
1246 * number, it is required to return the values in the client's current
1250 UnmarshallRPCStats(t
->serverVersion
, &t
->pointer
, &t
->stats
[slot
].s
);
1255 * See if we've processed all the entries
1258 if (t
->index
== t
->total
) {
1260 *last_item_contains_data
= 1;
1271 GetRPCStatsFromCache(void *rpc_specific
, int slot
, void *dest
,
1275 afs_status_t tst
= 0;
1276 rpc_stat_get_p stat
= (rpc_stat_get_p
) rpc_specific
;
1278 memcpy(dest
, (const void *)&stat
->stats
[slot
], sizeof(afs_RPCStats_t
));
1288 DestroyRPCStats(void *rpc_specific
, afs_status_p st
)
1291 afs_status_t tst
= 0;
1292 rpc_stat_get_p stat
= (rpc_stat_get_p
) rpc_specific
;
1294 if (stat
->stat_list
.rpcStats_val
!= NULL
) {
1295 free(stat
->stat_list
.rpcStats_val
);
1306 * util_RPCStatsGetBegin - begin retrieving rpc stats for a process
1310 * IN conn - an rx connection to the process to be queried
1312 * IN rpc - the function to call to make the actual rpc
1314 * OUT iterationIdP - an iteration id that can be passed to
1315 * util_RPCStatsGetNext to get the next rpc stat
1319 * No locks are obtained or released by this function
1323 * Returns != 0 upon successful completion.
1328 util_RPCStatsGetBegin(struct rx_connection
*conn
,
1329 int (*rpc
) (struct rx_connection
*,
1330 afs_uint32
, afs_uint32
*,
1331 afs_uint32
*, afs_uint32
*,
1332 afs_uint32
*, struct rpcStats
*),
1333 void **iterationIdP
, afs_status_p st
)
1336 afs_status_t tst
= 0;
1337 afs_admin_iterator_p iter
= malloc(sizeof(afs_admin_iterator_t
));
1338 rpc_stat_get_p stat
= malloc(sizeof(rpc_stat_get_t
));
1341 tst
= ADMRXCONNNULL
;
1342 goto fail_util_RPCStatsGetBegin
;
1346 tst
= ADMRPCPTRNULL
;
1347 goto fail_util_RPCStatsGetBegin
;
1350 if (iterationIdP
== NULL
) {
1351 tst
= ADMITERATIONIDPNULL
;
1352 goto fail_util_RPCStatsGetBegin
;
1355 if ((iter
== NULL
) || (stat
== NULL
)) {
1357 goto fail_util_RPCStatsGetBegin
;
1360 stat
->stat_list
.rpcStats_len
= 0;
1361 stat
->stat_list
.rpcStats_val
= 0;
1363 stat
->clientVersion
= RX_STATS_RETRIEVAL_VERSION
;
1366 (*rpc
) (conn
, stat
->clientVersion
, &stat
->serverVersion
,
1367 &stat
->clock_sec
, &stat
->clock_usec
, &stat
->total
,
1371 goto fail_util_RPCStatsGetBegin
;
1375 * If there are no statistics, just mark the iterator done and
1379 if (stat
->stat_list
.rpcStats_len
== 0) {
1380 stat
->pointer
= NULL
;
1381 if (!IteratorInit(iter
, (void *)stat
, NULL
, NULL
, NULL
, NULL
, &tst
)) {
1382 goto fail_util_RPCStatsGetBegin
;
1384 iter
->done_iterating
= 1;
1385 iter
->st
= ADMITERATORDONE
;
1387 stat
->pointer
= stat
->stat_list
.rpcStats_val
;
1389 (iter
, (void *)stat
, GetRPCStatsRPC
, GetRPCStatsFromCache
, NULL
,
1390 DestroyRPCStats
, &tst
)) {
1391 goto fail_util_RPCStatsGetBegin
;
1394 *iterationIdP
= (void *)iter
;
1397 fail_util_RPCStatsGetBegin
:
1415 * util_RPCStatsGetNext - retrieve the next rpc stat from the server
1419 * IN iterationId - an iterator previously returned by
1420 * util_RPCStatsGetBegin.
1422 * OUT stats - upon successful completion contains the next set of stats
1427 * No locks are obtained or released by this function
1431 * Returns != 0 upon successful completion.
1436 util_RPCStatsGetNext(const void *iterationId
, afs_RPCStats_p stats
,
1440 afs_status_t tst
= 0;
1441 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
1443 if (iterationId
== NULL
) {
1444 tst
= ADMITERATIONIDPNULL
;
1445 goto fail_util_RPCStatsGetNext
;
1448 if (stats
== NULL
) {
1449 tst
= ADMUTILRPCSTATSNULL
;
1450 goto fail_util_RPCStatsGetNext
;
1453 rc
= IteratorNext(iter
, (void *)stats
, &tst
);
1455 fail_util_RPCStatsGetNext
:
1464 * util_RPCStatsGetDone - finish using a stats iterator
1468 * IN iterationId - an iterator previously returned by
1469 * util_RPCStatsGetBegin.
1473 * No locks are obtained or released by this function
1477 * Returns != 0 upon successful completion.
1482 util_RPCStatsGetDone(const void *iterationId
, afs_status_p st
)
1485 afs_status_t tst
= 0;
1486 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
1488 if (iterationId
== NULL
) {
1489 tst
= ADMITERATIONIDPNULL
;
1490 goto fail_util_RPCStatsGetDone
;
1493 rc
= IteratorDone(iter
, &tst
);
1495 fail_util_RPCStatsGetDone
:
1504 * util_RPCStatsStateGet - get the current state of rpc stat collection
1508 * IN conn - an rx connection to the process to be queried
1510 * IN rpc - the function to call to make the actual rpc
1512 * OUT state - the rpc stat collection state.
1516 * No locks are obtained or released by this function
1520 * Returns != 0 upon successful completion.
1525 util_RPCStatsStateGet(struct rx_connection
*conn
,
1526 int (*rpc
) (struct rx_connection
*,
1527 afs_RPCStatsState_p
),
1528 afs_RPCStatsState_p state
, afs_status_p st
)
1531 afs_status_t tst
= 0;
1534 tst
= ADMRXCONNNULL
;
1535 goto fail_util_RPCStatsStateGet
;
1539 tst
= ADMRPCPTRNULL
;
1540 goto fail_util_RPCStatsStateGet
;
1543 if (state
== NULL
) {
1544 tst
= ADMRPCSTATENULL
;
1545 goto fail_util_RPCStatsStateGet
;
1548 tst
= (*rpc
) (conn
, state
);
1554 fail_util_RPCStatsStateGet
:
1563 * util_RPCStatsStateEnable - enable rpc stat collection
1568 * IN conn - an rx connection to the process to be modified
1570 * IN rpc - the function to call to make the actual rpc
1574 * No locks are obtained or released by this function
1578 * Returns != 0 upon successful completion.
1583 util_RPCStatsStateEnable(struct rx_connection
*conn
,
1584 int (*rpc
) (struct rx_connection
*),
1588 afs_status_t tst
= 0;
1591 tst
= ADMRXCONNNULL
;
1592 goto fail_util_RPCStatsStateEnable
;
1596 tst
= ADMRPCPTRNULL
;
1597 goto fail_util_RPCStatsStateEnable
;
1600 tst
= (*rpc
) (conn
);
1606 fail_util_RPCStatsStateEnable
:
1615 * util_RPCStatsStateDisable - set the current state of rpc stat collection
1620 * IN conn - an rx connection to the process to be modified
1622 * IN rpc - the function to call to make the actual rpc
1626 * No locks are obtained or released by this function
1630 * Returns != 0 upon successful completion.
1635 util_RPCStatsStateDisable(struct rx_connection
*conn
,
1636 int (*rpc
) (struct rx_connection
*),
1640 afs_status_t tst
= 0;
1643 tst
= ADMRXCONNNULL
;
1644 goto fail_util_RPCStatsStateDisable
;
1648 tst
= ADMRPCPTRNULL
;
1649 goto fail_util_RPCStatsStateDisable
;
1652 tst
= (*rpc
) (conn
);
1658 fail_util_RPCStatsStateDisable
:
1667 * util_RPCStatsClear - clear some or all of the fields in the rpc stat
1668 * collection at a server
1672 * IN conn - an rx connection to the process to be modified
1674 * IN rpc - the function to call to make the actual rpc
1676 * IN flag - a flag containing the fields to be cleared
1681 * No locks are obtained or released by this function
1685 * Returns != 0 upon successful completion.
1690 util_RPCStatsClear(struct rx_connection
*conn
,
1691 int (*rpc
) (struct rx_connection
*,
1692 afs_RPCStatsClearFlag_t
),
1693 afs_RPCStatsClearFlag_t flag
, afs_status_p st
)
1696 afs_status_t tst
= 0;
1699 tst
= ADMRXCONNNULL
;
1700 goto fail_util_RPCStatsClear
;
1704 tst
= ADMRPCPTRNULL
;
1705 goto fail_util_RPCStatsClear
;
1708 tst
= (*rpc
) (conn
, flag
);
1714 fail_util_RPCStatsClear
:
1723 * util_RPCStatsVersionGet - get the current version of rpc stat collection
1727 * IN conn - an rx connection to the process to be modified
1729 * OUT version - the version of rpc stat collection at the remote process
1733 * No locks are obtained or released by this function
1737 * Returns != 0 upon successful completion.
1742 util_RPCStatsVersionGet(struct rx_connection
*conn
,
1743 afs_RPCStatsVersion_p version
, afs_status_p st
)
1746 afs_status_t tst
= 0;
1749 tst
= ADMRXCONNNULL
;
1750 goto fail_util_RPCStatsVersionGet
;
1753 if (version
== NULL
) {
1754 tst
= ADMRPCVERSIONNULL
;
1755 goto fail_util_RPCStatsVersionGet
;
1758 tst
= RXSTATS_QueryRPCStatsVersion(conn
, version
);
1764 fail_util_RPCStatsVersionGet
:
1773 * The iterator for listing CM server preferences
1776 typedef struct cm_srvr_pref_get
{
1777 struct rx_connection
*conn
;
1779 afs_CMServerPref_t srvrPrefs
[CACHED_ITEMS
];
1780 } cm_srvr_pref_get_t
, *cm_srvr_pref_get_p
;
1783 GetServerPrefsRPC(void *rpc_specific
, int slot
, int *last_item
,
1784 int *last_item_contains_data
, afs_status_p st
)
1787 afs_status_t tst
= 0;
1788 cm_srvr_pref_get_p t
= (cm_srvr_pref_get_p
) rpc_specific
;
1791 * Get the next entry in the list of server preferences.
1794 RXAFSCB_GetServerPrefs(t
->conn
, t
->index
, &t
->srvrPrefs
[slot
].ipAddr
,
1795 &t
->srvrPrefs
[slot
].ipRank
);
1797 goto fail_GetServerPrefsRPC
;
1801 * See if we've processed all the entries
1803 if (t
->srvrPrefs
[slot
].ipAddr
== 0xffffffff) {
1805 *last_item_contains_data
= 0;
1811 fail_GetServerPrefsRPC
:
1820 GetServerPrefsFromCache(void *rpc_specific
, int slot
, void *dest
,
1824 afs_status_t tst
= 0;
1825 cm_srvr_pref_get_p prefs
= (cm_srvr_pref_get_p
) rpc_specific
;
1827 memcpy(dest
, (const void *)&prefs
->srvrPrefs
[slot
],
1828 sizeof(afs_CMServerPref_t
));
1838 * util_CMGetServerPrefsBegin - Begin listing cache manager server preferences
1842 * IN conn - an rx connection to the process to be queried
1844 * OUT iterationIdP - an iteration id that can be passed to
1845 * util_CMGetServerPrefsNext to get the next server preference
1849 * No locks are obtained or released by this function
1853 * Returns != 0 upon successful completion.
1858 util_CMGetServerPrefsBegin(struct rx_connection
*conn
, void **iterationIdP
,
1862 afs_status_t tst
= 0;
1863 afs_admin_iterator_p iter
;
1864 cm_srvr_pref_get_p pref
;
1867 tst
= ADMRXCONNNULL
;
1868 goto fail_util_CMGetServerPrefsBegin
;
1871 iter
= malloc(sizeof(afs_admin_iterator_t
));
1874 goto fail_util_CMGetServerPrefsBegin
;
1877 pref
= malloc(sizeof(cm_srvr_pref_get_t
));
1881 goto fail_util_CMGetServerPrefsBegin
;
1887 (iter
, (void *)pref
, GetServerPrefsRPC
, GetServerPrefsFromCache
, NULL
,
1891 goto fail_util_CMGetServerPrefsBegin
;
1893 *iterationIdP
= (void *)iter
;
1896 fail_util_CMGetServerPrefsBegin
:
1905 * util_CMGetServerPrefsNext - Get next entry in cache manager server
1910 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
1912 * OUT prefs - Next entry in cache manager server preferences.
1916 * No locks are obtained or released by this function
1920 * Returns != 0 upon successful completion.
1925 util_CMGetServerPrefsNext(const void *iterationId
, afs_CMServerPref_p prefs
,
1929 afs_status_t tst
= 0;
1930 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
1932 if (iterationId
== NULL
) {
1933 tst
= ADMITERATIONIDPNULL
;
1934 goto fail_util_CMGetServerPrefsNext
;
1937 rc
= IteratorNext(iter
, (void *)prefs
, &tst
);
1939 fail_util_CMGetServerPrefsNext
:
1948 * util_CMGetServerPrefsDone - Finish listing cache manager server
1953 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
1957 * No locks are obtained or released by this function
1961 * Returns != 0 upon successful completion.
1966 util_CMGetServerPrefsDone(const void *iterationId
, afs_status_p st
)
1969 afs_status_t tst
= 0;
1970 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
1972 if (iterationId
== NULL
) {
1973 tst
= ADMITERATIONIDPNULL
;
1974 goto fail_util_CMGetServerPrefsDone
;
1977 rc
= IteratorDone(iter
, &tst
);
1980 fail_util_CMGetServerPrefsDone
:
1989 * The iterator for listing CM CellServDB
1992 typedef struct cm_list_cell_get
{
1993 struct rx_connection
*conn
;
1995 afs_CMListCell_t cell
[CACHED_ITEMS
];
1996 } cm_list_cell_get_t
, *cm_list_cell_get_p
;
1999 ListCellsRPC(void *rpc_specific
, int slot
, int *last_item
,
2000 int *last_item_contains_data
, afs_status_p st
)
2003 afs_status_t tst
= 0;
2004 cm_list_cell_get_p t
= (cm_list_cell_get_p
) rpc_specific
;
2010 * Get the next entry in the CellServDB.
2012 name
= t
->cell
[slot
].cellname
;
2013 sl
.serverList_len
= 0;
2014 sl
.serverList_val
= NULL
;
2015 memset(t
->cell
[slot
].serverAddr
, 0, sizeof(afs_int32
)*UTIL_MAX_CELL_HOSTS
);
2017 RXAFSCB_GetCellServDB(t
->conn
, t
->index
, &name
, &sl
);
2019 goto fail_ListCellsRPC
;
2021 strcpy(t
->cell
[slot
].cellname
, name
);
2022 if (sl
.serverList_val
) {
2023 for (n
=0; n
<sl
.serverList_len
&& n
<UTIL_MAX_CELL_HOSTS
; n
++) {
2024 t
->cell
[slot
].serverAddr
[n
] = sl
.serverList_val
[n
];
2026 xdr_free((xdrproc_t
) xdr_serverList
, &sl
);
2030 * See if we've processed all the entries
2032 if (strlen(t
->cell
[slot
].cellname
) == 0) {
2034 *last_item_contains_data
= 0;
2049 ListCellsFromCache(void *rpc_specific
, int slot
, void *dest
, afs_status_p st
)
2052 afs_status_t tst
= 0;
2053 cm_list_cell_get_p cell
= (cm_list_cell_get_p
) rpc_specific
;
2055 memcpy(dest
, (const void *)&cell
->cell
[slot
], sizeof(afs_CMListCell_t
));
2065 * util_CMListCellsBegin - Begin listing cache manager CellServDB
2069 * IN conn - an rx connection to the process to be queried
2071 * OUT iterationIdP - an iteration id that can be passed to
2072 * util_CMListCellsNext to get the next cell
2076 * No locks are obtained or released by this function
2080 * Returns != 0 upon successful completion.
2085 util_CMListCellsBegin(struct rx_connection
*conn
, void **iterationIdP
,
2089 afs_status_t tst
= 0;
2090 afs_admin_iterator_p iter
;
2091 cm_list_cell_get_p cell
;
2094 tst
= ADMRXCONNNULL
;
2095 goto fail_util_CMListCellsBegin
;
2098 iter
= malloc(sizeof(afs_admin_iterator_t
));
2101 goto fail_util_CMListCellsBegin
;
2104 cell
= malloc(sizeof(cm_list_cell_get_t
));
2108 goto fail_util_CMListCellsBegin
;
2114 (iter
, (void *)cell
, ListCellsRPC
, ListCellsFromCache
, NULL
, NULL
,
2118 goto fail_util_CMListCellsBegin
;
2120 *iterationIdP
= (void *)iter
;
2123 fail_util_CMListCellsBegin
:
2132 * util_CMListCellsNext - Get next entry in cache manager cells
2136 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
2138 * OUT cell - Next entry in cache manager cells.
2142 * No locks are obtained or released by this function
2146 * Returns != 0 upon successful completion.
2151 util_CMListCellsNext(const void *iterationId
, afs_CMListCell_p cell
,
2155 afs_status_t tst
= 0;
2156 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
2158 if (iterationId
== NULL
) {
2159 tst
= ADMITERATIONIDPNULL
;
2160 goto fail_util_CMListCellsNext
;
2163 rc
= IteratorNext(iter
, (void *)cell
, &tst
);
2165 fail_util_CMListCellsNext
:
2174 * util_CMListCellsDone - Finish listing cache manager cells
2178 * IN iterationId - Iteration id created by util_CMGetServerPrefsBegin.
2182 * No locks are obtained or released by this function
2186 * Returns != 0 upon successful completion.
2191 util_CMListCellsDone(const void *iterationId
, afs_status_p st
)
2194 afs_status_t tst
= 0;
2195 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
2197 if (iterationId
== NULL
) {
2198 tst
= ADMITERATIONIDPNULL
;
2199 goto fail_util_CMListCellsDone
;
2202 rc
= IteratorDone(iter
, &tst
);
2205 fail_util_CMListCellsDone
:
2214 * util_CMLocalCell - Get the name of the cache manager's local cell.
2218 * IN conn - an rx connection to the process to be queried
2220 * OUT cellName - the name of the cache manager's local cell.
2224 * No locks are obtained or released by this function
2228 * Returns != 0 upon successful completion.
2233 util_CMLocalCell(struct rx_connection
*conn
, afs_CMCellName_p cellName
,
2237 afs_status_t tst
= 0;
2238 afs_CMCellName_p name
;
2241 tst
= ADMRXCONNNULL
;
2242 goto fail_util_CMLocalCell
;
2245 if (cellName
== NULL
) {
2246 tst
= ADMCLIENTCMCELLNAMENULL
;
2247 goto fail_util_CMLocalCell
;
2251 tst
= RXAFSCB_GetLocalCell(conn
, &name
);
2257 fail_util_CMLocalCell
:
2266 UnmarshallCMClientConfig(afs_uint32 serverVersion
, afs_uint32
* ptr
,
2267 afs_ClientConfigUnion_p config
)
2270 * We currently only support version 1.
2272 config
->config_v1
.nChunkFiles
= *(ptr
++);
2273 config
->config_v1
.nStatCaches
= *(ptr
++);
2274 config
->config_v1
.nDataCaches
= *(ptr
++);
2275 config
->config_v1
.nVolumeCaches
= *(ptr
++);
2276 config
->config_v1
.firstChunkSize
= *(ptr
++);
2277 config
->config_v1
.otherChunkSize
= *(ptr
++);
2278 config
->config_v1
.cacheSize
= *(ptr
++);
2279 config
->config_v1
.setTime
= *(ptr
++);
2280 config
->config_v1
.memCache
= *(ptr
++);
2284 * util_CMClientConfig - Get the cache manager's configuration parameters.
2288 * IN conn - an rx connection to the process to be queried
2290 * OUT config - the cache manager's configuration parameters.
2294 * No locks are obtained or released by this function
2298 * Returns != 0 upon successful completion.
2303 util_CMClientConfig(struct rx_connection
*conn
, afs_ClientConfig_p config
,
2307 afs_status_t tst
= 0;
2308 afs_uint32 allocbytes
;
2309 struct cacheConfig tconfig
;
2312 tst
= ADMRXCONNNULL
;
2313 goto fail_util_CMClientConfig
;
2316 if (config
== NULL
) {
2317 tst
= ADMCLIENTCMCELLNAMENULL
;
2318 goto fail_util_CMClientConfig
;
2321 config
->clientVersion
= AFS_CLIENT_RETRIEVAL_VERSION
;
2322 tconfig
.cacheConfig_val
= NULL
;
2323 tconfig
.cacheConfig_len
= 0;
2325 RXAFSCB_GetCacheConfig(conn
, config
->clientVersion
,
2326 &config
->serverVersion
, &allocbytes
, &tconfig
);
2329 goto fail_util_CMClientConfig
;
2332 UnmarshallCMClientConfig(config
->serverVersion
, tconfig
.cacheConfig_val
,
2335 free(tconfig
.cacheConfig_val
);
2337 fail_util_CMClientConfig
:
2346 * util_RXDebugVersion - Get the rxdebug version string.
2350 * IN handle - an rxdebug handle for the process to be queried.
2352 * OUT version - the rxdebug version string.
2356 * No locks are obtained or released by this function
2360 * Returns != 0 upon successful completion.
2365 util_RXDebugVersion(rxdebugHandle_p handle
, rxdebugVersion_p version
,
2369 afs_status_t tst
= 0;
2372 if (handle
== NULL
) {
2373 tst
= ADMRXDEBUGHANDLENULL
;
2374 goto fail_util_RXDebugVersion
;
2377 if (version
== NULL
) {
2378 tst
= ADMRXDEBUGVERSIONNULL
;
2379 goto fail_util_RXDebugVersion
;
2383 rx_GetServerVersion(handle
->sock
, handle
->ipAddr
, handle
->udpPort
,
2384 UTIL_MAX_RXDEBUG_VERSION_LEN
, version
);
2386 tst
= ADMCLIENTRXDEBUGTIMEOUT
;
2387 goto fail_util_RXDebugVersion
;
2392 fail_util_RXDebugVersion
:
2401 * util_RXDebugSupportedStats - Get the rxdebug statistics supported by
2406 * IN handle - an rxdebug handle for the process to be queried.
2408 * OUT supportedStats - bit mask with supported rxstats.
2412 * No locks are obtained or released by this function
2416 * Returns != 0 upon successful completion.
2421 util_RXDebugSupportedStats(rxdebugHandle_p handle
,
2422 afs_uint32
* supportedStats
, afs_status_p st
)
2425 afs_status_t tst
= 0;
2426 struct rx_debugStats tstats
;
2428 if (handle
== NULL
) {
2429 tst
= ADMRXDEBUGHANDLENULL
;
2430 goto fail_util_RXDebugSupportedStats
;
2433 if (supportedStats
== NULL
) {
2434 tst
= ADMRXDEBUGSTATSNULL
;
2435 goto fail_util_RXDebugSupportedStats
;
2438 if (handle
->firstFlag
) {
2439 rc
= util_RXDebugBasicStats(handle
, &tstats
, &tst
);
2441 goto fail_util_RXDebugSupportedStats
;
2445 *supportedStats
= handle
->supportedStats
;
2448 fail_util_RXDebugSupportedStats
:
2458 * util_RXDebugBasicStats - Get the basic rxdebug statistics for the process.
2462 * IN handle - an rxdebug handle for the process to be queried.
2464 * OUT stats - Basic rxdebug statistics for the process.
2468 * No locks are obtained or released by this function
2472 * Returns != 0 upon successful completion.
2477 util_RXDebugBasicStats(rxdebugHandle_p handle
, struct rx_debugStats
*stats
,
2481 afs_status_t tst
= 0;
2484 if (handle
== NULL
) {
2485 tst
= ADMRXDEBUGHANDLENULL
;
2486 goto fail_util_RXDebugBasicStats
;
2489 if (stats
== NULL
) {
2490 tst
= ADMRXDEBUGSTATSNULL
;
2491 goto fail_util_RXDebugBasicStats
;
2495 rx_GetServerDebug(handle
->sock
, handle
->ipAddr
, handle
->udpPort
,
2496 stats
, &handle
->supportedStats
);
2498 tst
= ADMCLIENTRXDEBUGTIMEOUT
;
2499 goto fail_util_RXDebugBasicStats
;
2502 handle
->firstFlag
= 0;
2505 fail_util_RXDebugBasicStats
:
2515 * util_RXDebugRxStats - Get the detailed rxdebug statistics for the process.
2519 * IN handle - an rxdebug handle for the process to be queried.
2521 * OUT stats - Detailed rxdebug statistics for the process.
2525 * No locks are obtained or released by this function
2529 * Returns != 0 upon successful completion.
2534 util_RXDebugRxStats(rxdebugHandle_p handle
, struct rx_statistics
*stats
,
2535 afs_uint32
* supportedValues
, afs_status_p st
)
2539 afs_status_t tst
= 0;
2541 afs_uint32 tsupported
;
2543 if (handle
== NULL
) {
2544 tst
= ADMRXDEBUGHANDLENULL
;
2545 goto fail_util_RXDebugRxStats
;
2548 if (supportedValues
== NULL
) {
2549 tst
= ADMRXDEBUGSTATSNULL
;
2550 goto fail_util_RXDebugRxStats
;
2553 if (stats
== NULL
) {
2554 tst
= ADMRXDEBUGSTATSNULL
;
2555 goto fail_util_RXDebugRxStats
;
2558 if (handle
->firstFlag
) {
2559 trc
= util_RXDebugSupportedStats(handle
, &tsupported
, &tst
);
2562 goto fail_util_RXDebugRxStats
;
2566 if (!(handle
->supportedStats
& RX_SERVER_DEBUG_RX_STATS
)) {
2567 tst
= ADMCLIENTRXDEBUGNOTSUPPORTED
;
2568 goto fail_util_RXDebugRxStats
;
2572 rx_GetServerStats(handle
->sock
, handle
->ipAddr
, handle
->udpPort
,
2573 stats
, &handle
->supportedStats
);
2575 tst
= ADMCLIENTRXDEBUGTIMEOUT
;
2576 goto fail_util_RXDebugRxStats
;
2581 fail_util_RXDebugRxStats
:
2590 * The iterator for listing RXDebug connections
2593 typedef struct rxdebug_conn_item
{
2594 struct rx_debugConn conn
;
2595 afs_uint32 supportedValues
;
2596 } rxdebug_conn_item_t
, *rxdebug_conn_item_p
;
2598 typedef struct rxdebug_conn_get
{
2600 rxdebugHandle_p handle
;
2602 rxdebug_conn_item_t items
[CACHED_ITEMS
];
2603 } rxdebug_conn_get_t
, *rxdebug_conn_get_p
;
2606 RXDebugConnsFromServer(void *rpc_specific
, int slot
, int *last_item
,
2607 int *last_item_contains_data
, afs_status_p st
)
2611 afs_status_t tst
= 0;
2612 rxdebug_conn_get_p t
= (rxdebug_conn_get_p
) rpc_specific
;
2615 * Get the next entry the list of connections
2618 rx_GetServerConnections(t
->handle
->sock
, t
->handle
->ipAddr
,
2619 t
->handle
->udpPort
, &t
->index
, t
->allconns
,
2620 t
->handle
->supportedStats
,
2621 &t
->items
[slot
].conn
,
2622 &t
->items
[slot
].supportedValues
);
2624 tst
= ADMCLIENTRXDEBUGTIMEOUT
;
2625 goto fail_ListCellsRPC
;
2629 * See if we've processed all the entries
2631 if (t
->items
[slot
].conn
.cid
== 0xffffffff) {
2633 *last_item_contains_data
= 0;
2646 RXDebugConnsFromCache(void *rpc_specific
, int slot
, void *dest
,
2650 afs_status_t tst
= 0;
2651 rxdebug_conn_get_p t
= (rxdebug_conn_get_p
) rpc_specific
;
2653 memcpy(dest
, (const void *)&t
->items
[slot
], sizeof(rxdebug_conn_item_t
));
2663 * util_RXDebugConnectionsBegin - Begin listing rxdebug connection information
2668 * IN handle - an rxdebug handle for the process to be queried
2670 * IN allcons - non-zero to list all connections. If zero, only
2671 * "interesting" connections will be listed.
2673 * OUT iterationIdP - an iteration id that can be passed to
2674 * util_RXDebugConnectionsNext.
2678 * No locks are obtained or released by this function
2682 * Returns != 0 upon successful completion.
2687 util_RXDebugConnectionsBegin(rxdebugHandle_p handle
, int allconns
,
2688 void **iterationIdP
, afs_status_p st
)
2692 afs_uint32 tsupported
;
2693 afs_status_t tst
= 0;
2694 afs_admin_iterator_p iter
;
2695 rxdebug_conn_get_p t
;
2697 if (handle
== NULL
) {
2698 tst
= ADMRXDEBUGHANDLENULL
;
2699 goto fail_util_RXDebugConnectionsBegin
;
2702 iter
= malloc(sizeof(afs_admin_iterator_t
));
2705 goto fail_util_RXDebugConnectionsBegin
;
2708 if (handle
->firstFlag
) {
2709 trc
= util_RXDebugSupportedStats(handle
, &tsupported
, &tst
);
2712 goto fail_util_RXDebugConnectionsBegin
;
2716 if (allconns
&& !(handle
->supportedStats
& RX_SERVER_DEBUG_ALL_CONN
)) {
2717 tst
= ADMCLIENTRXDEBUGNOTSUPPORTED
;
2718 goto fail_util_RXDebugConnectionsBegin
;
2721 t
= malloc(sizeof(rxdebug_conn_get_t
));
2725 goto fail_util_RXDebugConnectionsBegin
;
2728 t
->allconns
= allconns
;
2732 (iter
, (void *)t
, RXDebugConnsFromServer
, RXDebugConnsFromCache
, NULL
,
2734 goto fail_util_RXDebugConnectionsBegin
;
2736 *iterationIdP
= (void *)iter
;
2739 fail_util_RXDebugConnectionsBegin
:
2749 * util_RXDebugConnectionsNext - Get rxdebug information for the next
2754 * IN iterationId - Iteration id created by util_RXDebugConnectionsNext.
2756 * OUT conn - Rxdebug information for the next connection.
2758 * OUT supportedValues - Bit mask of supported rxdebug values.
2762 * No locks are obtained or released by this function
2766 * Returns != 0 upon successful completion.
2771 util_RXDebugConnectionsNext(const void *iterationId
,
2772 struct rx_debugConn
*conn
,
2773 afs_uint32
* supportedValues
, afs_status_p st
)
2776 afs_status_t tst
= 0;
2777 rxdebug_conn_item_t item
;
2778 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
2780 if (iterationId
== NULL
) {
2781 tst
= ADMITERATIONIDPNULL
;
2782 goto fail_util_RXDebugConnectionsNext
;
2786 tst
= ADMRXDEBUGHANDLENULL
;
2787 goto fail_util_RXDebugConnectionsNext
;
2790 if (supportedValues
== NULL
) {
2791 tst
= ADMRXDEBUGHANDLENULL
;
2792 goto fail_util_RXDebugConnectionsNext
;
2795 rc
= IteratorNext(iter
, (void *)&item
, &tst
);
2797 goto fail_util_RXDebugConnectionsNext
;
2801 *supportedValues
= item
.supportedValues
;
2803 fail_util_RXDebugConnectionsNext
:
2813 * util_RXDebugConnectionsDone - Finish listing rxdebug connection information.
2817 * IN iterationId - Iteration id created by util_RXDebugConnectionsBegin.
2821 * No locks are obtained or released by this function
2825 * Returns != 0 upon successful completion.
2830 util_RXDebugConnectionsDone(const void *iterationId
, afs_status_p st
)
2833 afs_status_t tst
= 0;
2834 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
2837 * Validate parameters
2841 tst
= ADMITERATORNULL
;
2842 goto fail_util_RXDebugConnectionsDone
;
2845 rc
= IteratorDone(iter
, &tst
);
2847 fail_util_RXDebugConnectionsDone
:
2857 * The iterator for listing RXDebug peer
2860 typedef struct rxdebug_peer_item
{
2861 struct rx_debugPeer peer
;
2862 afs_uint32 supportedValues
;
2863 } rxdebug_peer_item_t
, *rxdebug_peer_item_p
;
2865 typedef struct rxdebug_peer_get
{
2866 rxdebugHandle_p handle
;
2868 rxdebug_peer_item_t items
[CACHED_ITEMS
];
2869 } rxdebug_peer_get_t
, *rxdebug_peer_get_p
;
2872 RXDebugPeersFromServer(void *rpc_specific
, int slot
, int *last_item
,
2873 int *last_item_contains_data
, afs_status_p st
)
2877 afs_status_t tst
= 0;
2878 rxdebug_peer_get_p t
= (rxdebug_peer_get_p
) rpc_specific
;
2881 * Get the next entry the list of peers
2884 rx_GetServerPeers(t
->handle
->sock
, t
->handle
->ipAddr
,
2885 t
->handle
->udpPort
, &t
->index
,
2886 t
->handle
->supportedStats
, &t
->items
[slot
].peer
,
2887 &t
->items
[slot
].supportedValues
);
2889 tst
= ADMCLIENTRXDEBUGTIMEOUT
;
2890 goto fail_ListCellsRPC
;
2894 * See if we've processed all the entries
2896 if (t
->items
[slot
].peer
.host
== 0xffffffff) {
2898 *last_item_contains_data
= 0;
2911 RXDebugPeersFromCache(void *rpc_specific
, int slot
, void *dest
,
2915 afs_status_t tst
= 0;
2916 rxdebug_peer_get_p t
= (rxdebug_peer_get_p
) rpc_specific
;
2918 memcpy(dest
, (const void *)&t
->items
[slot
], sizeof(rxdebug_peer_item_t
));
2929 * util_RXDebugPeersBegin - Begin listing rxdebug peer information for
2934 * IN handle - an rxdebug handle for the process to be queried
2936 * OUT iterationIdP - an iteration id that can be passed to
2937 * util_RXDebugPeersNext.
2941 * No locks are obtained or released by this function
2945 * Returns != 0 upon successful completion.
2950 util_RXDebugPeersBegin(rxdebugHandle_p handle
, void **iterationIdP
,
2955 afs_uint32 tsupported
;
2956 afs_status_t tst
= 0;
2957 afs_admin_iterator_p iter
;
2958 rxdebug_peer_get_p t
;
2960 if (handle
== NULL
) {
2961 tst
= ADMRXDEBUGHANDLENULL
;
2962 goto fail_util_RXDebugPeersBegin
;
2965 iter
= malloc(sizeof(afs_admin_iterator_t
));
2968 goto fail_util_RXDebugPeersBegin
;
2971 if (handle
->firstFlag
) {
2972 trc
= util_RXDebugSupportedStats(handle
, &tsupported
, &tst
);
2975 goto fail_util_RXDebugPeersBegin
;
2979 if (!(handle
->supportedStats
& RX_SERVER_DEBUG_ALL_PEER
)) {
2980 tst
= ADMCLIENTRXDEBUGNOTSUPPORTED
;
2981 goto fail_util_RXDebugPeersBegin
;
2984 t
= malloc(sizeof(rxdebug_peer_get_t
));
2988 goto fail_util_RXDebugPeersBegin
;
2994 (iter
, (void *)t
, RXDebugPeersFromServer
, RXDebugPeersFromCache
, NULL
,
2996 goto fail_util_RXDebugPeersBegin
;
2998 *iterationIdP
= (void *)iter
;
3001 fail_util_RXDebugPeersBegin
:
3010 * util_RXDebugPeersNext - Get rxdebug information for the next peer.
3014 * IN iterationId - Iteration id created by util_RXDebugPeersBegin.
3016 * OUT peer - Rxdebug information for the next peer.
3018 * OUT supportedValues - Bit mask of supported rxdebug values.
3022 * No locks are obtained or released by this function
3026 * Returns != 0 upon successful completion.
3030 util_RXDebugPeersNext(const void *iterationId
, struct rx_debugPeer
*peer
,
3031 afs_uint32
* supportedValues
, afs_status_p st
)
3034 afs_status_t tst
= 0;
3035 rxdebug_peer_item_t item
;
3036 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
3038 if (iterationId
== NULL
) {
3039 tst
= ADMITERATIONIDPNULL
;
3040 goto fail_util_RXDebugPeersNext
;
3044 tst
= ADMRXDEBUGHANDLENULL
;
3045 goto fail_util_RXDebugPeersNext
;
3048 if (supportedValues
== NULL
) {
3049 tst
= ADMRXDEBUGHANDLENULL
;
3050 goto fail_util_RXDebugPeersNext
;
3053 rc
= IteratorNext(iter
, (void *)&item
, &tst
);
3055 goto fail_util_RXDebugPeersNext
;
3059 *supportedValues
= item
.supportedValues
;
3061 fail_util_RXDebugPeersNext
:
3070 * util_RXDebugPeersDone - Finish listing rxdebug peer information.
3074 * IN iterationId - Iteration id created by util_RXDebugPeersBegin.
3078 * No locks are obtained or released by this function
3082 * Returns != 0 upon successful completion.
3087 util_RXDebugPeersDone(const void *iterationId
, afs_status_p st
)
3090 afs_status_t tst
= 0;
3091 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
3094 * Validate parameters
3098 tst
= ADMITERATORNULL
;
3099 goto fail_util_RXDebugPeersDone
;
3102 rc
= IteratorDone(iter
, &tst
);
3104 fail_util_RXDebugPeersDone
: