LINUX: afs_create infinite fetchStatus loop
[pkg-k5-afs_openafs.git] / src / JAVA / libjafs / Server.c
blob00589654985084cd135dce9b946cc82b4d517e2a
1 /*
2 * Copyright (c) 2001-2002 International Business Machines Corp.
3 * All rights reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 *
9 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
13 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 #include "Internal.h"
23 #include "org_openafs_jafs_Server.h"
25 #include <afs_clientAdmin.h>
26 #include <afs_vosAdmin.h>
27 #include <afs_bosAdmin.h>
28 #include <afs_AdminCommonErrors.h>
29 #include <rx/rxkad.h>
30 #include <bnode.h>
32 //// definitions in Internal.c //////////////////
34 extern jclass serverCls;
35 extern jfieldID server_nameField;
36 extern jfieldID server_nameField;
37 extern jfieldID server_databaseField;
38 extern jfieldID server_fileServerField;
39 extern jfieldID server_badDatabaseField;
40 extern jfieldID server_badFileServerField;
41 extern jfieldID server_IPAddressField;
43 extern jclass exectimeCls;
44 extern jfieldID exectime_HourField;
45 extern jfieldID exectime_MinField;
46 extern jfieldID exectime_SecField;
47 extern jfieldID exectime_DayField;
48 extern jfieldID exectime_NowField;
49 extern jfieldID exectime_NeverField;
51 extern jclass partitionCls;
52 extern jfieldID partition_cachedInfoField;
54 extern jclass keyCls;
55 extern jfieldID key_cachedInfoField;
57 extern jclass processCls;
58 extern jfieldID process_cachedInfoField;
59 extern jfieldID process_nameField;
60 //extern jfieldID process_serverHandleField;
62 extern jclass userCls;
63 extern jfieldID user_nameField;
64 extern jfieldID user_cachedInfoField;
65 //////////////////////////////////////////////////////////
67 ///// definition in jafs_Partition.c /////////////////
69 extern void fillPartitionInfo( JNIEnv *env, jobject partition,
70 vos_partitionEntry_t partEntry );
72 ///////////////////////////////////////////////////
74 ///// definition in jafs_Key.c /////////////////
76 extern void fillKeyInfo( JNIEnv *env, jobject key, bos_KeyInfo_t keyEntry );
78 ///////////////////////////////////////////////////
80 ///// definition in jafs_Process.c /////////////////
82 extern void getProcessInfoChar( JNIEnv *env, void *serverHandle,
83 const char *processName, jobject process );
85 ///////////////////////////////////////////////////
88 void IntIPAddressToString(int iIPAddress, char *strIPAddress)
90 sprintf(strIPAddress, "%d.%d.%d.%d",
91 (int)((iIPAddress >> 24) & 0xFF),
92 (int)((iIPAddress >> 16) & 0xFF),
93 (int)((iIPAddress >> 8) & 0xFF),
94 (int)((iIPAddress ) & 0xFF)
96 } //IntIPAddressToString
98 /**
99 * Extract the information from the given server entry and populate the
100 * given object
102 * env the Java environment
103 * cellHandle the handle of the cell to which the server belongs
104 * server the Server object to populate with the info
105 * servEntry the container of the server's information
107 void fillServerInfo
108 ( JNIEnv *env, void *cellHandle, jobject server, afs_serverEntry_t servEntry )
110 jstring jip;
111 jobjectArray jaddresses;
112 jstring jserver;
113 int i = 0;
114 char szServerAddr[AFS_MAX_SERVER_NAME_LEN];
116 // get the class fields if need be
117 if( serverCls == 0 ) {
118 internal_getServerClass( env, server );
121 // in case it's blank
122 jserver = (*env)->NewStringUTF(env, servEntry.serverName);
123 (*env)->SetObjectField(env, server, server_nameField, jserver);
125 // let's convert just the addresses in the address array into an IP
126 jaddresses = (jobjectArray) (*env)->GetObjectField( env, server,
127 server_IPAddressField );
129 for (i = 0; i < AFS_MAX_SERVER_ADDRESS; i++) {
130 if (servEntry.serverAddress[i] != 0) {
131 IntIPAddressToString(servEntry.serverAddress[i], szServerAddr);
132 jip = (*env)->NewStringUTF(env, szServerAddr);
133 (*env)->SetObjectArrayElement(env, jaddresses, i, jip);
134 } else {
135 break;
139 // let's check if this is really a database server
140 (*env)->SetBooleanField(env, server, server_databaseField,
141 servEntry.serverType & DATABASE_SERVER);
143 if( servEntry.serverType & DATABASE_SERVER ) {
144 // for now, if it thinks it's a database server than it is
145 // later, add checks for database configuration, and actual
146 // on-ness of the machine
147 (*env)->SetBooleanField(env, server, server_badDatabaseField, FALSE);
148 } else {
149 (*env)->SetBooleanField(env, server, server_badDatabaseField, FALSE);
152 // we should check to see if this is truly a file server or not
153 // it could just be an old remnant, left over inside the vldb that
154 // should be removed.
155 // if it is a file server, mark it as such. If not, mark it as faulty.
156 (*env)->SetBooleanField(env, server, server_fileServerField,
157 servEntry.serverType & FILE_SERVER);
159 if( servEntry.serverType & FILE_SERVER ) {
161 // to see if it's really a file server, make sure the
162 // "fs" process is running
163 void *bosHandle;
164 afs_status_t ast, ast2;
165 bos_ProcessType_t processTypeT;
166 bos_ProcessInfo_t processInfoT;
167 char *fileServerProcessName = "fs";
169 // set the file server to true (it thinks it's a file server)
170 (*env)->SetBooleanField(env, server, server_fileServerField, TRUE);
172 if( !bos_ServerOpen( cellHandle, servEntry.serverName,
173 &bosHandle, &ast ) ) {
174 throwAFSException( env, ast );
175 return;
178 if( !bos_ProcessInfoGet( bosHandle, fileServerProcessName, &processTypeT,
179 &processInfoT, &ast ) ) {
180 // if the machine does not have a fs process or is not responding
181 // or is part of another cell
182 if( ast == BZNOENT || ast == -1 || ast == RXKADBADTICKET ) {
183 (*env)->SetBooleanField(env, server, server_badFileServerField, TRUE);
184 // otherwise
185 } else {
186 bos_ServerClose( bosHandle, &ast2 );
187 throwAFSException( env, ast );
188 return;
190 } else {
191 // it's good
192 (*env)->SetBooleanField(env, server, server_badFileServerField, FALSE);
194 if (!bos_ServerClose( bosHandle, &ast )) {
195 throwAFSException( env, ast );
196 return;
198 } else {
199 (*env)->SetBooleanField(env, server, server_badFileServerField, FALSE);
204 * Fills in the information fields of the provided Server.
206 * env the Java environment
207 * cls the current Java class
208 * cellHandle the handle of the cell to which the server belongs
209 * jname the name of the server for which to get the information
210 * server the Server object in which to fill in
211 * the information
213 JNIEXPORT void JNICALL
214 Java_org_openafs_jafs_Server_getServerInfo (JNIEnv *env, jclass cls,
215 jlong cellHandle, jstring jname,
216 jobject server) {
218 const char *name;
219 afs_status_t ast;
220 afs_serverEntry_t servEntry;
222 if( jname != NULL ) {
223 name = (*env)->GetStringUTFChars(env, jname, 0);
224 if( !name ) {
225 throwAFSException( env, JAFSADMNOMEM );
226 return;
228 } else {
229 name = NULL;
232 // get the server entry
233 if ( !afsclient_AFSServerGet( (void *) cellHandle, name,
234 &servEntry, &ast ) ) {
235 if( name != NULL ) {
236 (*env)->ReleaseStringUTFChars(env, jname, name);
238 throwAFSException( env, ast );
239 return;
242 fillServerInfo( env, cellHandle, server, servEntry );
244 if( name != NULL ) {
245 (*env)->ReleaseStringUTFChars(env, jname, name);
251 * Returns the total number of partitions hosted by the server denoted by
252 * serverHandle, if the server is a fileserver.
254 * env the Java environment
255 * cls the current Java class
256 * cellHandle the handle of the cell to which the server belongs
257 * serverHandle the vos handle of the server to which the
258 * partitions belong
259 * returns total number of partitions
261 JNIEXPORT jint JNICALL
262 Java_org_openafs_jafs_Server_getPartitionCount (JNIEnv *env, jclass cls,
263 jlong cellHandle,
264 jlong serverHandle) {
266 afs_status_t ast;
267 void *iterationId;
268 vos_partitionEntry_t partEntry;
269 int i = 0;
271 if( !vos_PartitionGetBegin( (void *) cellHandle, (void *) serverHandle,
272 NULL, &iterationId, &ast ) ) {
273 throwAFSException( env, ast );
274 return -1;
277 while ( vos_PartitionGetNext( (void *) iterationId, &partEntry, &ast ) ) i++;
279 if( ast != ADMITERATORDONE ) {
280 throwAFSException( env, ast );
281 return -1;
284 return i;
288 * Begin the process of getting the partitions on a server. Returns
289 * an iteration ID to be used by subsequent calls to
290 * getPartitionsNext and getPartitionsDone.
292 * env the Java environment
293 * cls the current Java class
294 * cellHandle the handle of the cell to which the server belongs
295 * serverHandle the vos handle of the server to which the
296 * partitions belong
297 * returns an iteration ID
299 JNIEXPORT jlong JNICALL
300 Java_org_openafs_jafs_Server_getPartitionsBegin (JNIEnv *env, jclass cls,
301 jlong cellHandle,
302 jlong serverHandle) {
304 afs_status_t ast;
305 void *iterationId;
307 if( !vos_PartitionGetBegin( (void *) cellHandle, (void *) serverHandle,
308 NULL, &iterationId, &ast ) ) {
309 throwAFSException( env, ast );
310 return;
313 return (jlong) iterationId;
318 * Returns the next partition of the server. Returns null
319 * if there are no more partitions.
321 * env the Java environment
322 * cls the current Java class
323 * iterationId the iteration ID of this iteration
324 * returns the name of the next partition of the server
326 JNIEXPORT jstring JNICALL
327 Java_org_openafs_jafs_Server_getPartitionsNextString (JNIEnv *env,
328 jclass cls,
329 jlong iterationId) {
331 afs_status_t ast;
332 jstring jpartition;
333 vos_partitionEntry_t partEntry;
335 if( !vos_PartitionGetNext( (void *) iterationId, &partEntry, &ast ) ) {
336 if( ast == ADMITERATORDONE ) {
337 return NULL;
338 } else {
339 throwAFSException( env, ast );
340 return;
344 jpartition = (*env)->NewStringUTF(env, partEntry.name);
345 return jpartition;
350 * Fills the next partition object of the server. Returns 0 if there
351 * are no more partitions, != 0 otherwise
353 * env the Java environment
354 * cls the current Java class
355 * iterationId the iteration ID of this iteration
356 * thePartition the Partition object in which to fill the
357 * values of the next partition
358 * returns 0 if there are no more servers, != 0 otherwise
360 JNIEXPORT jint JNICALL
361 Java_org_openafs_jafs_Server_getPartitionsNext (JNIEnv *env, jclass cls,
362 jlong iterationId,
363 jobject jpartitionObject) {
365 afs_status_t ast;
366 vos_partitionEntry_t partEntry;
368 if( !vos_PartitionGetNext( (void *) iterationId, &partEntry, &ast ) ) {
369 if( ast == ADMITERATORDONE ) {
370 return 0;
371 } else {
372 throwAFSException( env, ast );
373 return 0;
377 fillPartitionInfo( env, jpartitionObject, partEntry );
379 // get the class fields if need be
380 if( partitionCls == 0 ) {
381 internal_getPartitionClass( env, jpartitionObject );
383 (*env)->SetBooleanField( env, jpartitionObject, partition_cachedInfoField,
384 TRUE );
387 return 1;
392 * Signals that the iteration is complete and will not be accessed anymore.
394 * env the Java environment
395 * cls the current Java class
396 * iterationId the iteration ID of this iteration
398 JNIEXPORT void JNICALL
399 Java_org_openafs_jafs_Server_getPartitionsDone (JNIEnv *env, jclass cls,
400 jlong iterationId) {
402 afs_status_t ast;
404 if( !vos_PartitionGetDone( (void *) iterationId, &ast ) ) {
405 throwAFSException( env, ast );
406 return;
412 * Adds the given to name to the list of bos administrators on that server.
414 * env the Java environment
415 * cls the current Java class
416 * serverHandle the bos handle of the server to which the
417 * partitions belong
418 * jnewAdmin the name of the admin to add to the list
420 JNIEXPORT void JNICALL
421 Java_org_openafs_jafs_Server_addBosAdmin (JNIEnv *env, jclass cls,
422 jlong serverHandle,
423 jstring jnewAdmin) {
425 afs_status_t ast;
426 const char *newAdmin;
428 if( jnewAdmin != NULL ) {
429 newAdmin = (*env)->GetStringUTFChars(env, jnewAdmin, 0);
430 if( !newAdmin ) {
431 throwAFSException( env, JAFSADMNOMEM );
432 return;
434 } else {
435 newAdmin = NULL;
438 if( !bos_AdminCreate( (void *) serverHandle, newAdmin, &ast ) ) {
439 if( newAdmin != NULL ) {
440 (*env)->ReleaseStringUTFChars(env, jnewAdmin, newAdmin);
442 throwAFSException( env, ast );
443 return;
446 if( newAdmin != NULL ) {
447 (*env)->ReleaseStringUTFChars(env, jnewAdmin, newAdmin);
453 * Removes the given to name from the list of bos administrators on
454 * that server.
456 * env the Java environment
457 * cls the current Java class
458 * serverHandle the bos handle of the server to which the
459 * partitions belong
460 * joldAdmin the name of the admin to remove from the list
462 JNIEXPORT void JNICALL
463 Java_org_openafs_jafs_Server_removeBosAdmin (JNIEnv *env, jclass cls,
464 jlong serverHandle,
465 jstring joldAdmin) {
467 afs_status_t ast;
468 const char *oldAdmin;
470 if( joldAdmin != NULL ) {
471 oldAdmin = (*env)->GetStringUTFChars(env, joldAdmin, 0);
472 if( !oldAdmin ) {
473 throwAFSException( env, JAFSADMNOMEM );
474 return;
476 } else {
477 oldAdmin = NULL;
480 if( !bos_AdminDelete( (void *) serverHandle, oldAdmin, &ast ) ) {
481 if( oldAdmin != NULL ) {
482 (*env)->ReleaseStringUTFChars(env, joldAdmin, oldAdmin);
484 throwAFSException( env, ast );
485 return;
488 if( oldAdmin != NULL ) {
489 (*env)->ReleaseStringUTFChars(env, joldAdmin, oldAdmin);
495 * Returns the total number of BOS administrators associated with the server
496 * denoted by serverHandle.
498 * env the Java environment
499 * cls the current Java class
500 * serverHandle the vos handle of the server to which the
501 * BOS admins belong
502 * returns total number of BOS administrators
504 JNIEXPORT jint JNICALL
505 Java_org_openafs_jafs_Server_getBosAdminCount (JNIEnv *env, jclass cls,
506 jlong serverHandle) {
508 afs_status_t ast;
509 void *iterationId;
510 char *admin;
511 jstring jadmin;
512 int i = 0;
514 if( !bos_AdminGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
515 throwAFSException( env, ast );
516 return -1;
519 admin = malloc( sizeof(char)*BOS_MAX_NAME_LEN);
521 if( !admin ) {
522 throwAFSException( env, JAFSADMNOMEM );
523 return -1;
526 while ( bos_AdminGetNext( (void *) iterationId, admin, &ast ) ) i++;
528 free(admin);
530 if( ast != ADMITERATORDONE ) {
531 throwAFSException( env, ast );
532 return -1;
535 return i;
539 * Begin the process of getting the bos amdinistrators on a server. Returns
540 * an iteration ID to be used by subsequent calls to
541 * getBosAdminsNext and getBosAdminsDone.
543 * env the Java environment
544 * cls the current Java class
545 * serverHandle the bos handle of the server to which the
546 * partitions belong
547 * returns an iteration ID
549 JNIEXPORT jlong JNICALL
550 Java_org_openafs_jafs_Server_getBosAdminsBegin (JNIEnv *env, jclass cls,
551 jlong serverHandle) {
553 afs_status_t ast;
554 void *iterationId;
556 if( !bos_AdminGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
557 throwAFSException( env, ast );
558 return;
561 return (jlong) iterationId;
566 * Returns the next bos admin of the server. Returns null
567 * if there are no more admins.
569 * env the Java environment
570 * cls the current Java class
571 * iterationId the iteration ID of this iteration
572 * returns the name of the next admin of the server
574 JNIEXPORT jstring JNICALL
575 Java_org_openafs_jafs_Server_getBosAdminsNextString (JNIEnv *env,
576 jclass cls,
577 jlong iterationId) {
579 afs_status_t ast;
580 jstring jadmin;
581 char *admin = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
583 if( !admin ) {
584 throwAFSException( env, JAFSADMNOMEM );
585 return;
588 if( !bos_AdminGetNext( (void *) iterationId, admin, &ast ) ) {
589 free(admin);
590 if( ast == ADMITERATORDONE ) {
591 return NULL;
592 } else {
593 throwAFSException( env, ast );
594 return;
598 jadmin = (*env)->NewStringUTF(env, admin);
599 free(admin);
600 return jadmin;
605 * Returns the next bos admin of the server. Returns 0 if there
606 * are no more admins, != 0 otherwise.
608 * env the Java environment
609 * cls the current Java class
610 * cellHandle the handle of the cell to which these admins belong
611 * iterationId the iteration ID of this iteration
612 * juserObject the user object in which to fill the values of this admin
613 * returns 0 if no more admins, != 0 otherwise
615 JNIEXPORT jint JNICALL
616 Java_org_openafs_jafs_Server_getBosAdminsNext (JNIEnv *env, jclass cls,
617 jlong cellHandle,
618 jlong iterationId,
619 jobject juserObject ) {
621 afs_status_t ast;
622 char *admin;
623 jstring jadmin;
625 admin = malloc( sizeof(char)*BOS_MAX_NAME_LEN);
627 if( !admin ) {
628 throwAFSException( env, JAFSADMNOMEM );
629 return;
632 if( !bos_AdminGetNext( (void *) iterationId, admin, &ast ) ) {
633 free( admin );
634 if( ast == ADMITERATORDONE ) {
635 return 0;
636 } else {
637 throwAFSException( env, ast );
638 return 0;
642 jadmin = (*env)->NewStringUTF(env, admin);
644 if( userCls == 0 ) {
645 internal_getUserClass( env, juserObject );
648 (*env)->SetObjectField(env, juserObject, user_nameField, jadmin);
650 getUserInfoChar( env, cellHandle, admin, juserObject );
651 (*env)->SetBooleanField( env, juserObject, user_cachedInfoField, TRUE );
653 free( admin );
654 return 1;
659 * Signals that the iteration is complete and will not be accessed anymore.
661 * env the Java environment
662 * cls the current Java class
663 * iterationId the iteration ID of this iteration
665 JNIEXPORT void JNICALL
666 Java_org_openafs_jafs_Server_getBosAdminsDone (JNIEnv *env, jclass cls,
667 jlong iterationId) {
669 afs_status_t ast;
671 if( !bos_AdminGetDone( (void *) iterationId, &ast ) ) {
672 throwAFSException( env, ast );
673 return;
679 * Returns the total number of keys hosted by the server denoted by
680 * serverHandle.
682 * env the Java environment
683 * cls the current Java class
684 * serverHandle the vos handle of the server to which the
685 * keys belong
686 * returns total number of keys
688 JNIEXPORT jint JNICALL
689 Java_org_openafs_jafs_Server_getKeyCount (JNIEnv *env, jclass cls,
690 jlong serverHandle) {
692 afs_status_t ast;
693 void *iterationId;
694 bos_KeyInfo_t keyEntry;
695 int i = 0;
697 if( !bos_KeyGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
698 throwAFSException( env, ast );
699 return -1;
702 while ( bos_KeyGetNext( (void *) iterationId, &keyEntry, &ast ) ) i++;
704 if( ast != ADMITERATORDONE ) {
705 throwAFSException( env, ast );
706 return -1;
709 return i;
713 * Begin the process of getting the keys of a server. Returns
714 * an iteration ID to be used by subsequent calls to
715 * getKeysNext and getKeysDone.
717 * env the Java environment
718 * cls the current Java class
719 * serverHandle the bos handle of the server to which the keys belong
720 * returns an iteration ID
722 JNIEXPORT jlong JNICALL
723 Java_org_openafs_jafs_Server_getKeysBegin (JNIEnv *env, jclass cls,
724 jlong serverHandle) {
726 afs_status_t ast;
727 void *iterationId;
729 if( !bos_KeyGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
730 throwAFSException( env, ast );
731 return;
734 return (jlong) iterationId;
739 * Returns the next key of the server. Returns 0 if there
740 * are no more keys, != 0 otherwise.
742 * env the Java environment
743 * cls the current Java class
744 * iterationId the iteration ID of this iteration
745 * jkeyObject a Key object, in which to fill in the
746 * properties of the next key.
747 * returns 0 if there are no more keys, != 0 otherwise
749 JNIEXPORT jint JNICALL
750 Java_org_openafs_jafs_Server_getKeysNext (JNIEnv *env, jclass cls,
751 jlong iterationId,
752 jobject jkeyObject) {
754 afs_status_t ast;
755 bos_KeyInfo_t keyEntry;
757 if( !bos_KeyGetNext( (void *) iterationId, &keyEntry, &ast ) ) {
758 if( ast == ADMITERATORDONE ) {
759 return 0;
760 } else {
761 throwAFSException( env, ast );
762 return 0;
766 fillKeyInfo( env, jkeyObject, keyEntry );
768 // get the class fields if need be
769 if( keyCls == 0 ) {
770 internal_getKeyClass( env, jkeyObject );
773 (*env)->SetBooleanField( env, jkeyObject, key_cachedInfoField, TRUE );
775 return 1;
780 * Signals that the iteration is complete and will not be accessed anymore.
782 * env the Java environment
783 * cls the current Java class
784 * iterationId the iteration ID of this iteration
786 JNIEXPORT void JNICALL
787 Java_org_openafs_jafs_Server_getKeysDone (JNIEnv *env, jclass cls,
788 jlong iterationId) {
790 afs_status_t ast;
792 if( !bos_KeyGetDone( (void *) iterationId, &ast ) ) {
793 throwAFSException( env, ast );
794 return;
800 * Returns the total number of processes hosted by the server denoted by
801 * serverHandle.
803 * env the Java environment
804 * cls the current Java class
805 * serverHandle the vos handle of the server to which the
806 * processes belong
807 * returns total number of processes
809 JNIEXPORT jint JNICALL
810 Java_org_openafs_jafs_Server_getProcessCount (JNIEnv *env, jclass cls,
811 jlong serverHandle) {
813 afs_status_t ast;
814 void *iterationId;
815 char *process;
816 jstring jprocess;
817 int i = 0;
819 if( !bos_ProcessNameGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
820 throwAFSException( env, ast );
821 return -1;
824 process = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
826 if( !process ) {
827 throwAFSException( env, JAFSADMNOMEM );
828 return -1;
831 while ( bos_ProcessNameGetNext( (void *) iterationId, process, &ast ) ) i++;
833 free( process );
835 if( ast != ADMITERATORDONE ) {
836 throwAFSException( env, ast );
837 return -1;
840 return i;
844 * Begin the process of getting the processes on a server. Returns
845 * an iteration ID to be used by subsequent calls to
846 * getProcessesNext and getProcessesDone.
848 * env the Java environment
849 * cls the current Java class
850 * serverHandle the bos handle of the server to which the
851 * processes belong
852 * returns an iteration ID
854 JNIEXPORT jlong JNICALL
855 Java_org_openafs_jafs_Server_getProcessesBegin (JNIEnv *env, jclass cls,
856 jlong serverHandle) {
858 afs_status_t ast;
859 void *iterationId;
861 if( !bos_ProcessNameGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
862 throwAFSException( env, ast );
863 return;
866 return (jlong) iterationId;
871 * Returns the next process of the server. Returns null
872 * if there are no more processes.
874 * env the Java environment
875 * cls the current Java class
876 * iterationId the iteration ID of this iteration
877 * returns the name of the next process of the cell
879 JNIEXPORT jstring JNICALL
880 Java_org_openafs_jafs_Server_getProcessesNextString (JNIEnv *env,
881 jclass cls,
882 jlong iterationId) {
884 afs_status_t ast;
885 jstring jprocess;
886 char *process = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
888 if( !process ) {
889 throwAFSException( env, JAFSADMNOMEM );
890 return;
893 if( !bos_ProcessNameGetNext( (void *) iterationId, process, &ast ) ) {
894 free( process );
895 if( ast == ADMITERATORDONE ) {
896 return NULL;
897 } else {
898 throwAFSException( env, ast );
899 return;
903 jprocess = (*env)->NewStringUTF(env, process);
904 free( process );
905 return jprocess;
910 * Fills the next process object of the server. Returns 0 if there
911 * are no more processes, != 0 otherwise.
913 * env the Java environment
914 * cls the current Java class
915 * serverHandle the handle of the BOS server that hosts the process
916 * iterationId the iteration ID of this iteration
917 * jprocessObject the Process object in which to fill the
918 * values of the next process
919 * returns 0 if there are no more processes, != otherwise
921 JNIEXPORT jint JNICALL
922 Java_org_openafs_jafs_Server_getProcessesNext (JNIEnv *env, jclass cls,
923 jlong serverHandle,
924 jlong iterationId,
925 jobject jprocessObject) {
927 afs_status_t ast;
928 char *process = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
929 jstring jprocess;
931 if( !process ) {
932 throwAFSException( env, JAFSADMNOMEM );
933 return;
936 if( !bos_ProcessNameGetNext( (void *) iterationId, process, &ast ) ) {
937 if( ast == ADMITERATORDONE ) {
938 return 0;
939 } else {
940 free( process );
941 throwAFSException( env, ast );
942 return 0;
946 // get the class fields if need be
947 if( processCls == 0 ) {
948 internal_getProcessClass( env, jprocessObject );
951 jprocess = (*env)->NewStringUTF(env, process);
952 (*env)->SetObjectField(env, jprocessObject, process_nameField, jprocess);
954 getProcessInfoChar( env, (void *) serverHandle, process, jprocessObject );
956 (*env)->SetBooleanField( env, jprocessObject,
957 process_cachedInfoField, TRUE );
959 free( process );
960 return 1;
965 * Signals that the iteration is complete and will not be accessed anymore.
967 * env the Java environment
968 * cls the current Java class
969 * iterationId the iteration ID of this iteration
971 JNIEXPORT void JNICALL
972 Java_org_openafs_jafs_Server_getProcessesDone (JNIEnv *env, jclass cls,
973 jlong iterationId) {
975 afs_status_t ast;
977 if( !bos_ProcessNameGetDone( (void *) iterationId, &ast ) ) {
978 throwAFSException( env, ast );
979 return;
985 * Salvages (restores consistency to) a volume, partition, or server
987 * env the Java environment
988 * cls the current Java class
989 * cellHandle the handle of the cell to which the volume belongs
990 * serverHandle the bos handle of the server on which the
991 * volume resides
992 * jpartName the name of the partition to salvage,
993 * can be null only if volName is
994 * null
995 * jvolName the name of the volume to salvage,
996 * can be null
997 * numSalvagers the number of salvager processes to run in parallel
998 * jtempDir directory to place temporary files, can be
999 * null
1000 * jlogFile where salvager log will be written, can be
1001 * null
1002 * inspectAllVolumes whether or not to inspect all volumes,
1003 * not just those marked as active at crash
1004 * removeBadlyDamaged whether or not to remove a volume if it's
1005 * badly damaged
1006 * writeInodes whether or not to record a list of inodes modified
1007 * writeRootInodes whether or not to record a list of AFS
1008 * inodes owned by root
1009 * forceDirectory whether or not to salvage an entire directory
1010 * structure
1011 * forceBlockReads whether or not to force the salvager to read
1012 * the partition
1013 * one block at a time and skip badly damaged
1014 * blocks. Use if partition has disk errors
1016 JNIEXPORT void JNICALL
1017 Java_org_openafs_jafs_Server_salvage (JNIEnv *env, jclass cls,
1018 jlong cellHandle, jlong serverHandle,
1019 jstring jpartName, jstring jvolName,
1020 jint numSalvagers, jstring jtempDir,
1021 jstring jlogFile,
1022 jboolean inspectAllVolumes,
1023 jboolean removeBadlyDamaged,
1024 jboolean writeInodes,
1025 jboolean writeRootInodes,
1026 jboolean forceDirectory,
1027 jboolean forceBlockReads) {
1029 afs_status_t ast;
1030 const char *partName;
1031 const char *volName;
1032 const char *tempDir;
1033 const char *logFile;
1034 vos_force_t force;
1035 bos_SalvageDamagedVolumes_t sdv;
1036 bos_WriteInodes_t wi;
1037 bos_WriteRootInodes_t wri;
1038 bos_ForceDirectory_t forceD;
1039 bos_ForceBlockRead_t forceBR;
1041 // convert strings
1042 if( jpartName != NULL ) {
1043 partName = (*env)->GetStringUTFChars(env, jpartName, 0);
1044 if( !partName ) {
1045 throwAFSException( env, JAFSADMNOMEM );
1046 return;
1048 } else {
1049 partName = NULL;
1051 if( jvolName != NULL ) {
1052 volName = (*env)->GetStringUTFChars(env, jvolName, 0);
1053 if( !volName ) {
1054 if( partName != NULL ) {
1055 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1057 throwAFSException( env, JAFSADMNOMEM );
1058 return;
1060 } else {
1061 volName = NULL;
1063 if( jtempDir != NULL ) {
1064 tempDir = (*env)->GetStringUTFChars(env, jtempDir, 0);
1065 if( !tempDir ) {
1066 if( partName != NULL ) {
1067 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1069 if( volName != NULL ) {
1070 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1072 throwAFSException( env, JAFSADMNOMEM );
1073 return;
1075 } else {
1076 tempDir = NULL;
1078 if( jlogFile != NULL ) {
1079 logFile = (*env)->GetStringUTFChars(env, jlogFile, 0);
1080 if( !logFile ) {
1081 if( partName != NULL ) {
1082 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1084 if( volName != NULL ) {
1085 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1087 if( tempDir != NULL ) {
1088 (*env)->ReleaseStringUTFChars(env, jtempDir, tempDir);
1090 throwAFSException( env, JAFSADMNOMEM );
1091 return;
1093 } else {
1094 logFile = NULL;
1097 // deal with booleans
1098 if( inspectAllVolumes ) {
1099 force = VOS_FORCE;
1100 } else {
1101 force = VOS_NORMAL;
1103 if( removeBadlyDamaged ) {
1104 sdv = BOS_DONT_SALVAGE_DAMAGED_VOLUMES;
1105 } else {
1106 sdv = BOS_SALVAGE_DAMAGED_VOLUMES;
1108 if( writeInodes ) {
1109 wi = BOS_SALVAGE_WRITE_INODES;
1110 } else {
1111 wi = BOS_SALVAGE_DONT_WRITE_INODES;
1113 if( writeRootInodes ) {
1114 wri = BOS_SALVAGE_WRITE_ROOT_INODES;
1115 } else {
1116 wri = BOS_SALVAGE_DONT_WRITE_ROOT_INODES;
1118 if( forceDirectory ) {
1119 forceD = BOS_SALVAGE_FORCE_DIRECTORIES;
1120 } else {
1121 forceD = BOS_SALVAGE_DONT_FORCE_DIRECTORIES;
1123 if( forceBlockReads ) {
1124 forceBR = BOS_SALVAGE_FORCE_BLOCK_READS;
1125 } else {
1126 forceBR = BOS_SALVAGE_DONT_FORCE_BLOCK_READS;
1129 //salvage!
1130 if( !bos_Salvage( (void *) cellHandle, (void *) serverHandle, partName,
1131 volName, (int) numSalvagers, tempDir, logFile, force, sdv,
1132 wi, wri, forceD, forceBR, &ast ) ) {
1133 if( partName != NULL ) {
1134 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1136 if( volName != NULL ) {
1137 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1139 if( tempDir != NULL ) {
1140 (*env)->ReleaseStringUTFChars(env, jtempDir, tempDir);
1142 if( logFile != NULL ) {
1143 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1145 throwAFSException( env, ast );
1146 return;
1149 // release strings
1150 if( partName != NULL ) {
1151 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1153 if( volName != NULL ) {
1154 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1156 if( tempDir != NULL ) {
1157 (*env)->ReleaseStringUTFChars(env, jtempDir, tempDir);
1159 if( logFile != NULL ) {
1160 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1166 * Fills in the restart time fields of the given Server
1167 * object.
1169 * env the Java environment
1170 * cls the current Java class
1171 * serverHandle the bos handle of the server to which the key belongs
1172 * jtype whether to get the general or binary restart.
1173 * Acceptable values are:
1174 * org_opemafs_jafs_Server_RESTART_BINARY
1175 * org_opemafs_jafs_Server_RESTART_GENERAL
1176 * execTime the ExecutableTime object, in which
1177 * to fill the restart time fields
1179 JNIEXPORT void JNICALL
1180 Java_org_openafs_jafs_Server_getRestartTime
1181 (JNIEnv *env, jclass cls, jlong serverHandle, jint jtype, jobject exectime)
1183 afs_status_t ast;
1184 bos_Restart_t type;
1185 bos_RestartTime_t time;
1186 jfieldID hourField;
1187 jfieldID minField;
1188 jfieldID secField;
1189 jfieldID dayField;
1190 jfieldID neverField;
1191 jfieldID nowField;
1193 // get the class fields if need be
1194 if( exectimeCls == 0 ) {
1195 internal_getExecTimeClass( env, exectime );
1198 if( jtype == org_openafs_jafs_Server_RESTART_BINARY ) {
1199 type = BOS_RESTART_DAILY;
1200 } else {
1201 type = BOS_RESTART_WEEKLY;
1204 hourField = exectime_HourField;
1205 minField = exectime_MinField;
1206 secField = exectime_SecField;
1207 dayField = exectime_DayField;
1208 neverField = exectime_NeverField;
1209 nowField = exectime_NowField;
1211 if( !bos_ExecutableRestartTimeGet( (void *) serverHandle, type,
1212 &time, &ast ) ) {
1213 throwAFSException( env, ast );
1214 return;
1217 // set now
1218 (*env)->SetBooleanField(env, exectime, nowField,
1219 (time.mask & BOS_RESTART_TIME_NOW) );
1221 // set never
1222 (*env)->SetBooleanField(env, exectime, neverField,
1223 (time.mask & BOS_RESTART_TIME_NEVER) );
1225 // set hour
1226 (*env)->SetShortField(env, exectime, hourField, time.hour );
1228 // set minute
1229 (*env)->SetShortField(env, exectime, minField, time.min );
1231 // set second
1232 (*env)->SetShortField(env, exectime, secField, time.sec );
1234 // set day
1235 if( time.mask & BOS_RESTART_TIME_DAY ) {
1236 (*env)->SetShortField(env, exectime, dayField, time.day );
1237 } else {
1238 (*env)->SetShortField(env, exectime, dayField, (jshort) -1 );
1244 * Sets the restart time of the bos server.
1246 * env the Java environment
1247 * cls the current Java class
1248 * serverHandle the bos handle of the server to which the key belongs
1249 * jtype whether this is to be a general or binary restart.
1250 * Acceptable values are:
1251 * org_opemafs_jafs_Server_RESTART_BINARY
1252 * org_opemafs_jafs_Server_RESTART_GENERAL
1253 * executableTime the ExecutableTime object containing the
1254 * desired information
1256 JNIEXPORT void JNICALL
1257 Java_org_openafs_jafs_Server_setRestartTime (JNIEnv *env, jclass cls,
1258 jlong serverHandle, jint jtype,
1259 jobject exectime ) {
1261 afs_status_t ast;
1262 bos_Restart_t type;
1263 bos_RestartTime_t time;
1264 jboolean doHour;
1265 jboolean doMinute;
1266 jboolean doSecond;
1267 jboolean doDay;
1268 jboolean doNever;
1269 jboolean doNow;
1270 jshort hour;
1271 jshort minute;
1272 jshort second;
1273 jshort day;
1274 jfieldID hourField;
1275 jfieldID minField;
1276 jfieldID secField;
1277 jfieldID dayField;
1278 jfieldID neverField;
1279 jfieldID nowField;
1281 // get the class fields if need be
1282 if( exectimeCls == 0 ) {
1283 internal_getExecTimeClass( env, exectime );
1286 if( jtype == org_openafs_jafs_Server_RESTART_BINARY ) {
1287 type = BOS_RESTART_DAILY;
1288 } else {
1289 type = BOS_RESTART_WEEKLY;
1292 hourField = exectime_HourField;
1293 minField = exectime_MinField;
1294 secField = exectime_SecField;
1295 dayField = exectime_DayField;
1296 neverField = exectime_NeverField;
1297 nowField = exectime_NowField;
1299 hour = (*env)->GetShortField(env, exectime, hourField );
1300 if( hour != 0 ) {
1301 doHour = TRUE;
1302 } else {
1303 doHour = FALSE;
1305 minute = (*env)->GetShortField(env, exectime, minField );
1306 if( minute != 0 ) {
1307 doMinute = TRUE;
1308 } else {
1309 doMinute = FALSE;
1311 second = (*env)->GetShortField(env, exectime, secField );
1312 if( second != 0 ) {
1313 doSecond = TRUE;
1314 } else {
1315 doSecond = FALSE;
1317 day = (*env)->GetShortField(env, exectime, dayField );
1318 if( day != -1 ) {
1319 doDay = TRUE;
1320 } else {
1321 doDay = FALSE;
1323 doNever = (*env)->GetBooleanField(env, exectime, neverField );
1324 doNow = (*env)->GetBooleanField(env, exectime, nowField );
1326 bzero(&time, sizeof(time));
1328 if( jtype == org_openafs_jafs_Server_RESTART_BINARY ) {
1329 type = BOS_RESTART_DAILY;
1330 } else {
1331 type = BOS_RESTART_WEEKLY;
1334 if( doHour ) {
1335 time.mask |= BOS_RESTART_TIME_HOUR;
1337 if( doMinute ) {
1338 time.mask |= BOS_RESTART_TIME_MINUTE;
1340 if( doSecond ) {
1341 time.mask |= BOS_RESTART_TIME_SECOND;
1343 if( doDay ) {
1344 time.mask |= BOS_RESTART_TIME_DAY;
1346 if( doNever ) {
1347 time.mask |= BOS_RESTART_TIME_NEVER;
1349 if( doNow ) {
1350 time.mask |= BOS_RESTART_TIME_NOW;
1353 time.hour = hour;
1354 time.min = minute;
1355 time.sec = second;
1356 time.day = day;
1358 if( !bos_ExecutableRestartTimeSet( (void *) serverHandle, type,
1359 time, &ast ) ) {
1360 throwAFSException( env, ast );
1361 return;
1367 * Synchronizes a particular server with the volume location database.
1369 * env the Java environment
1370 * cls the current Java class
1371 * cellHandle the handle of the cell to which the server belongs
1372 * serverHandle the vos handle of the server
1373 * partition the id of the partition to sync, can be -1 to ignore
1375 JNIEXPORT void JNICALL
1376 Java_org_openafs_jafs_Server_syncServerWithVLDB (JNIEnv *env, jclass cls,
1377 jlong cellHandle,
1378 jlong serverHandle,
1379 jint partition) {
1381 afs_status_t ast;
1382 int *part;
1384 if( partition == -1 ) {
1385 part = NULL;
1386 } else {
1387 part = (int *) &partition;
1390 if( !vos_ServerSync( (void *) cellHandle, (void *) serverHandle,
1391 NULL, part, &ast ) ) {
1392 throwAFSException( env, ast );
1393 return;
1399 * Synchronizes the volume location database with a particular server.
1401 * env the Java environment
1402 * cls the current Java class
1403 * cellHandle the handle of the cell to which the server belongs
1404 * serverHandle the vos handle of the server
1405 * partition the id of the partition to sync, can be -1 to ignore
1406 * forceDeletion whether or not to force the deletion of bad volumes
1408 JNIEXPORT void JNICALL
1409 Java_org_openafs_jafs_Server_syncVLDBWithServer (JNIEnv *env, jclass cls,
1410 jlong cellHandle,
1411 jlong serverHandle,
1412 jint partition,
1413 jboolean forceDeletion) {
1415 afs_status_t ast;
1416 int *part;
1417 vos_force_t force;
1419 if( partition == -1 ) {
1420 part = NULL;
1421 } else {
1422 part = (int *) &partition;
1425 if( forceDeletion ) {
1426 force = VOS_FORCE;
1427 } else {
1428 force = VOS_NORMAL;
1431 if( !vos_VLDBSync( (void *) cellHandle, (void *) serverHandle, NULL, part,
1432 force, &ast ) ) {
1433 throwAFSException( env, ast );
1434 return;
1440 * Start all server processes.
1442 * env the Java environment
1443 * cls the current Java class
1444 * serverHandle the bos handle of the server to which the
1445 * processes belong
1447 JNIEXPORT void JNICALL
1448 Java_org_openafs_jafs_Server_startAllProcesses (JNIEnv *env, jclass cls,
1449 jlong serverHandle) {
1451 afs_status_t ast;
1453 if( !bos_ProcessAllStart( (void *) serverHandle, &ast ) ) {
1454 throwAFSException( env, ast );
1455 return;
1461 * Stop all server processes.
1463 * env the Java environment
1464 * cls the current Java class
1465 * serverHandle the bos handle of the server to which the
1466 * processes belong
1468 JNIEXPORT void JNICALL
1469 Java_org_openafs_jafs_Server_stopAllProcesses (JNIEnv *env, jclass cls,
1470 jlong serverHandle) {
1472 afs_status_t ast;
1474 if( !bos_ProcessAllStop( (void *) serverHandle, &ast ) ) {
1475 throwAFSException( env, ast );
1476 return;
1482 * Restart all server processes.
1484 * env the Java environment
1485 * cls the current Java class
1486 * serverHandle the bos handle of the server to which the
1487 * processes belong
1488 * restartBosServer whether or not to restart the bos server as well
1490 JNIEXPORT void JNICALL
1491 Java_org_openafs_jafs_Server_restartAllProcesses (JNIEnv *env, jclass cls,
1492 jlong serverHandle,
1493 jboolean restartBosServer) {
1495 afs_status_t ast;
1496 bos_RestartBosServer_t rbs;
1498 if( restartBosServer ) {
1499 rbs = BOS_RESTART_BOS_SERVER;
1500 } else {
1501 rbs = BOS_DONT_RESTART_BOS_SERVER;
1504 if( !bos_ProcessAllStopAndRestart( (void *) serverHandle, rbs, &ast ) ) {
1505 throwAFSException( env, ast );
1506 return;
1512 * Retrieves a specified bos log from a server. Right now this
1513 * method will simply return a huge String containing the log, but
1514 * hopefully we can devise a better way to make this work more efficiently.
1516 * env the Java environment
1517 * cls the current Java class
1518 * serverHandle the bos handle of the server to which the key belongs
1519 * jlogFile the full path and name of the desired bos log
1521 JNIEXPORT jstring JNICALL
1522 Java_org_openafs_jafs_Server_getLog(JNIEnv *env, jclass cls,
1523 jlong serverHandle, jstring jlogFile) {
1525 afs_status_t ast;
1526 const char *logFile;
1527 char *logData;
1528 unsigned long currInLogSize = 1;
1529 unsigned long currOutLogSize = 0;
1530 jstring logOut;
1532 if( jlogFile != NULL ) {
1533 logFile = (*env)->GetStringUTFChars(env, jlogFile, 0);
1534 if( !logFile ) {
1535 throwAFSException( env, JAFSADMNOMEM );
1536 return;
1538 } else {
1539 logFile = NULL;
1542 logData = malloc( sizeof(char)*currInLogSize );
1543 if( !logData ) {
1544 throwAFSException( env, JAFSADMNOMEM );
1545 return;
1548 // check how big the log is . . .
1549 if( !bos_LogGet( (void *) serverHandle, logFile,
1550 &currOutLogSize, logData, &ast ) ) {
1551 // anything but not enough room in buffer
1552 if( ast != ADMMOREDATA ) {
1553 free( logData );
1554 if( logFile != NULL ) {
1555 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1557 throwAFSException( env, ast );
1558 return NULL;
1562 free( logData );
1564 // increase log size (plus one for terminator)
1565 currInLogSize = currOutLogSize + 1;
1566 // allocate buffer
1567 logData = malloc( sizeof(char)*currInLogSize );
1568 if( !logData ) {
1569 throwAFSException( env, JAFSADMNOMEM );
1570 return;
1573 if( !logData ) {
1574 // memory exception
1575 if( logFile != NULL ) {
1576 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1578 throwAFSException( env, ast );
1579 return NULL;
1582 // get the log for real
1583 if( !bos_LogGet( (void *) serverHandle, logFile, &currOutLogSize,
1584 logData, &ast ) ) {
1585 free( logData );
1586 if( logFile != NULL ) {
1587 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1589 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1590 throwAFSException( env, ast );
1591 return NULL;
1594 logData[currOutLogSize] == '\0';
1596 logOut = (*env)->NewStringUTF(env, logData);
1598 free( logData );
1599 if( logFile != NULL ) {
1600 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1602 return logOut;
1608 * Executes any command on the specified server.
1610 * env the Java environment
1611 * cls the current Java class
1612 * serverHandle the bos handle of the server to which the key belongs
1613 * jcommand the text of the commmand to execute
1615 JNIEXPORT void JNICALL
1616 Java_org_openafs_jafs_Server_executeCommand (JNIEnv *env, jclass cls,
1617 jlong serverHandle,
1618 jstring jcommand) {
1620 afs_status_t ast;
1621 const char *command;
1623 if( jcommand != NULL ) {
1624 command = (*env)->GetStringUTFChars(env, jcommand, 0);
1625 if( !command ) {
1626 throwAFSException( env, JAFSADMNOMEM );
1627 return;
1629 } else {
1630 command = NULL;
1633 if( !bos_CommandExecute( (void *) serverHandle, command, &ast ) ) {
1634 if( command != NULL ) {
1635 (*env)->ReleaseStringUTFChars(env, jcommand, command);
1637 throwAFSException( env, ast );
1638 return;
1641 if( command != NULL ) {
1642 (*env)->ReleaseStringUTFChars(env, jcommand, command);
1647 // reclaim global memory being used by this portion
1648 JNIEXPORT void JNICALL
1649 Java_org_openafs_jafs_Server_reclaimServerMemory (JNIEnv *env, jclass cls) {
1651 if( serverCls ) {
1652 (*env)->DeleteGlobalRef(env, serverCls);
1653 serverCls = 0;