Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / JAVA / libjafs / Server.c
1 /*
2 * Copyright (c) 2001-2002 International Business Machines Corp.
3 * All rights reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 *
9 * 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.
20 */
21
22 #include "Internal.h"
23 #include "org_openafs_jafs_Server.h"
24
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>
31
32 //// definitions in Internal.c //////////////////
33
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;
42
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;
50
51 extern jclass partitionCls;
52 extern jfieldID partition_cachedInfoField;
53
54 extern jclass keyCls;
55 extern jfieldID key_cachedInfoField;
56
57 extern jclass processCls;
58 extern jfieldID process_cachedInfoField;
59 extern jfieldID process_nameField;
60 //extern jfieldID process_serverHandleField;
61
62 extern jclass userCls;
63 extern jfieldID user_nameField;
64 extern jfieldID user_cachedInfoField;
65 //////////////////////////////////////////////////////////
66
67 ///// definition in jafs_Partition.c /////////////////
68
69 extern void fillPartitionInfo( JNIEnv *env, jobject partition,
70 vos_partitionEntry_t partEntry );
71
72 ///////////////////////////////////////////////////
73
74 ///// definition in jafs_Key.c /////////////////
75
76 extern void fillKeyInfo( JNIEnv *env, jobject key, bos_KeyInfo_t keyEntry );
77
78 ///////////////////////////////////////////////////
79
80 ///// definition in jafs_Process.c /////////////////
81
82 extern void getProcessInfoChar( JNIEnv *env, void *serverHandle,
83 const char *processName, jobject process );
84
85 ///////////////////////////////////////////////////
86
87
88 void IntIPAddressToString(int iIPAddress, char *strIPAddress)
89 {
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)
95 );
96 } //IntIPAddressToString
97
98 /**
99 * Extract the information from the given server entry and populate the
100 * given object
101 *
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
106 */
107 void fillServerInfo
108 ( JNIEnv *env, void *cellHandle, jobject server, afs_serverEntry_t servEntry )
109 {
110 jstring jip;
111 jobjectArray jaddresses;
112 jstring jserver;
113 int i = 0;
114 char szServerAddr[AFS_MAX_SERVER_NAME_LEN];
115
116 // get the class fields if need be
117 if( serverCls == 0 ) {
118 internal_getServerClass( env, server );
119 }
120
121 // in case it's blank
122 jserver = (*env)->NewStringUTF(env, servEntry.serverName);
123 (*env)->SetObjectField(env, server, server_nameField, jserver);
124
125 // let's convert just the addresses in the address array into an IP
126 jaddresses = (jobjectArray) (*env)->GetObjectField( env, server,
127 server_IPAddressField );
128
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;
136 }
137 }
138
139 // let's check if this is really a database server
140 (*env)->SetBooleanField(env, server, server_databaseField,
141 servEntry.serverType & DATABASE_SERVER);
142
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);
150 }
151
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);
158
159 if( servEntry.serverType & FILE_SERVER ) {
160
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";
168
169 // set the file server to true (it thinks it's a file server)
170 (*env)->SetBooleanField(env, server, server_fileServerField, TRUE);
171
172 if( !bos_ServerOpen( cellHandle, servEntry.serverName,
173 &bosHandle, &ast ) ) {
174 throwAFSException( env, ast );
175 return;
176 }
177
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;
189 }
190 } else {
191 // it's good
192 (*env)->SetBooleanField(env, server, server_badFileServerField, FALSE);
193 }
194 if (!bos_ServerClose( bosHandle, &ast )) {
195 throwAFSException( env, ast );
196 return;
197 }
198 } else {
199 (*env)->SetBooleanField(env, server, server_badFileServerField, FALSE);
200 }
201 }
202
203 /**
204 * Fills in the information fields of the provided Server.
205 *
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
212 */
213 JNIEXPORT void JNICALL
214 Java_org_openafs_jafs_Server_getServerInfo (JNIEnv *env, jclass cls,
215 jlong cellHandle, jstring jname,
216 jobject server) {
217
218 const char *name;
219 afs_status_t ast;
220 afs_serverEntry_t servEntry;
221
222 if( jname != NULL ) {
223 name = (*env)->GetStringUTFChars(env, jname, 0);
224 if( !name ) {
225 throwAFSException( env, JAFSADMNOMEM );
226 return;
227 }
228 } else {
229 name = NULL;
230 }
231
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);
237 }
238 throwAFSException( env, ast );
239 return;
240 }
241
242 fillServerInfo( env, cellHandle, server, servEntry );
243
244 if( name != NULL ) {
245 (*env)->ReleaseStringUTFChars(env, jname, name);
246 }
247
248 }
249
250 /**
251 * Returns the total number of partitions hosted by the server denoted by
252 * serverHandle, if the server is a fileserver.
253 *
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
260 */
261 JNIEXPORT jint JNICALL
262 Java_org_openafs_jafs_Server_getPartitionCount (JNIEnv *env, jclass cls,
263 jlong cellHandle,
264 jlong serverHandle) {
265
266 afs_status_t ast;
267 void *iterationId;
268 vos_partitionEntry_t partEntry;
269 int i = 0;
270
271 if( !vos_PartitionGetBegin( (void *) cellHandle, (void *) serverHandle,
272 NULL, &iterationId, &ast ) ) {
273 throwAFSException( env, ast );
274 return -1;
275 }
276
277 while ( vos_PartitionGetNext( (void *) iterationId, &partEntry, &ast ) ) i++;
278
279 if( ast != ADMITERATORDONE ) {
280 throwAFSException( env, ast );
281 return -1;
282 }
283
284 return i;
285 }
286
287 /**
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.
291 *
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
298 */
299 JNIEXPORT jlong JNICALL
300 Java_org_openafs_jafs_Server_getPartitionsBegin (JNIEnv *env, jclass cls,
301 jlong cellHandle,
302 jlong serverHandle) {
303
304 afs_status_t ast;
305 void *iterationId;
306
307 if( !vos_PartitionGetBegin( (void *) cellHandle, (void *) serverHandle,
308 NULL, &iterationId, &ast ) ) {
309 throwAFSException( env, ast );
310 return;
311 }
312
313 return (jlong) iterationId;
314
315 }
316
317 /**
318 * Returns the next partition of the server. Returns null
319 * if there are no more partitions.
320 *
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
325 */
326 JNIEXPORT jstring JNICALL
327 Java_org_openafs_jafs_Server_getPartitionsNextString (JNIEnv *env,
328 jclass cls,
329 jlong iterationId) {
330
331 afs_status_t ast;
332 jstring jpartition;
333 vos_partitionEntry_t partEntry;
334
335 if( !vos_PartitionGetNext( (void *) iterationId, &partEntry, &ast ) ) {
336 if( ast == ADMITERATORDONE ) {
337 return NULL;
338 } else {
339 throwAFSException( env, ast );
340 return;
341 }
342 }
343
344 jpartition = (*env)->NewStringUTF(env, partEntry.name);
345 return jpartition;
346
347 }
348
349 /**
350 * Fills the next partition object of the server. Returns 0 if there
351 * are no more partitions, != 0 otherwise
352 *
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
359 */
360 JNIEXPORT jint JNICALL
361 Java_org_openafs_jafs_Server_getPartitionsNext (JNIEnv *env, jclass cls,
362 jlong iterationId,
363 jobject jpartitionObject) {
364
365 afs_status_t ast;
366 vos_partitionEntry_t partEntry;
367
368 if( !vos_PartitionGetNext( (void *) iterationId, &partEntry, &ast ) ) {
369 if( ast == ADMITERATORDONE ) {
370 return 0;
371 } else {
372 throwAFSException( env, ast );
373 return 0;
374 }
375 }
376
377 fillPartitionInfo( env, jpartitionObject, partEntry );
378
379 // get the class fields if need be
380 if( partitionCls == 0 ) {
381 internal_getPartitionClass( env, jpartitionObject );
382 }
383 (*env)->SetBooleanField( env, jpartitionObject, partition_cachedInfoField,
384 TRUE );
385
386
387 return 1;
388
389 }
390
391 /**
392 * Signals that the iteration is complete and will not be accessed anymore.
393 *
394 * env the Java environment
395 * cls the current Java class
396 * iterationId the iteration ID of this iteration
397 */
398 JNIEXPORT void JNICALL
399 Java_org_openafs_jafs_Server_getPartitionsDone (JNIEnv *env, jclass cls,
400 jlong iterationId) {
401
402 afs_status_t ast;
403
404 if( !vos_PartitionGetDone( (void *) iterationId, &ast ) ) {
405 throwAFSException( env, ast );
406 return;
407 }
408
409 }
410
411 /**
412 * Adds the given to name to the list of bos administrators on that server.
413 *
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
419 */
420 JNIEXPORT void JNICALL
421 Java_org_openafs_jafs_Server_addBosAdmin (JNIEnv *env, jclass cls,
422 jlong serverHandle,
423 jstring jnewAdmin) {
424
425 afs_status_t ast;
426 const char *newAdmin;
427
428 if( jnewAdmin != NULL ) {
429 newAdmin = (*env)->GetStringUTFChars(env, jnewAdmin, 0);
430 if( !newAdmin ) {
431 throwAFSException( env, JAFSADMNOMEM );
432 return;
433 }
434 } else {
435 newAdmin = NULL;
436 }
437
438 if( !bos_AdminCreate( (void *) serverHandle, newAdmin, &ast ) ) {
439 if( newAdmin != NULL ) {
440 (*env)->ReleaseStringUTFChars(env, jnewAdmin, newAdmin);
441 }
442 throwAFSException( env, ast );
443 return;
444 }
445
446 if( newAdmin != NULL ) {
447 (*env)->ReleaseStringUTFChars(env, jnewAdmin, newAdmin);
448 }
449
450 }
451
452 /**
453 * Removes the given to name from the list of bos administrators on
454 * that server.
455 *
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
461 */
462 JNIEXPORT void JNICALL
463 Java_org_openafs_jafs_Server_removeBosAdmin (JNIEnv *env, jclass cls,
464 jlong serverHandle,
465 jstring joldAdmin) {
466
467 afs_status_t ast;
468 const char *oldAdmin;
469
470 if( joldAdmin != NULL ) {
471 oldAdmin = (*env)->GetStringUTFChars(env, joldAdmin, 0);
472 if( !oldAdmin ) {
473 throwAFSException( env, JAFSADMNOMEM );
474 return;
475 }
476 } else {
477 oldAdmin = NULL;
478 }
479
480 if( !bos_AdminDelete( (void *) serverHandle, oldAdmin, &ast ) ) {
481 if( oldAdmin != NULL ) {
482 (*env)->ReleaseStringUTFChars(env, joldAdmin, oldAdmin);
483 }
484 throwAFSException( env, ast );
485 return;
486 }
487
488 if( oldAdmin != NULL ) {
489 (*env)->ReleaseStringUTFChars(env, joldAdmin, oldAdmin);
490 }
491
492 }
493
494 /**
495 * Returns the total number of BOS administrators associated with the server
496 * denoted by serverHandle.
497 *
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
503 */
504 JNIEXPORT jint JNICALL
505 Java_org_openafs_jafs_Server_getBosAdminCount (JNIEnv *env, jclass cls,
506 jlong serverHandle) {
507
508 afs_status_t ast;
509 void *iterationId;
510 char *admin;
511 jstring jadmin;
512 int i = 0;
513
514 if( !bos_AdminGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
515 throwAFSException( env, ast );
516 return -1;
517 }
518
519 admin = malloc( sizeof(char)*BOS_MAX_NAME_LEN);
520
521 if( !admin ) {
522 throwAFSException( env, JAFSADMNOMEM );
523 return -1;
524 }
525
526 while ( bos_AdminGetNext( (void *) iterationId, admin, &ast ) ) i++;
527
528 free(admin);
529
530 if( ast != ADMITERATORDONE ) {
531 throwAFSException( env, ast );
532 return -1;
533 }
534
535 return i;
536 }
537
538 /**
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.
542 *
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
548 */
549 JNIEXPORT jlong JNICALL
550 Java_org_openafs_jafs_Server_getBosAdminsBegin (JNIEnv *env, jclass cls,
551 jlong serverHandle) {
552
553 afs_status_t ast;
554 void *iterationId;
555
556 if( !bos_AdminGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
557 throwAFSException( env, ast );
558 return;
559 }
560
561 return (jlong) iterationId;
562
563 }
564
565 /**
566 * Returns the next bos admin of the server. Returns null
567 * if there are no more admins.
568 *
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
573 */
574 JNIEXPORT jstring JNICALL
575 Java_org_openafs_jafs_Server_getBosAdminsNextString (JNIEnv *env,
576 jclass cls,
577 jlong iterationId) {
578
579 afs_status_t ast;
580 jstring jadmin;
581 char *admin = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
582
583 if( !admin ) {
584 throwAFSException( env, JAFSADMNOMEM );
585 return;
586 }
587
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;
595 }
596 }
597
598 jadmin = (*env)->NewStringUTF(env, admin);
599 free(admin);
600 return jadmin;
601
602 }
603
604 /**
605 * Returns the next bos admin of the server. Returns 0 if there
606 * are no more admins, != 0 otherwise.
607 *
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
614 */
615 JNIEXPORT jint JNICALL
616 Java_org_openafs_jafs_Server_getBosAdminsNext (JNIEnv *env, jclass cls,
617 jlong cellHandle,
618 jlong iterationId,
619 jobject juserObject ) {
620
621 afs_status_t ast;
622 char *admin;
623 jstring jadmin;
624
625 admin = malloc( sizeof(char)*BOS_MAX_NAME_LEN);
626
627 if( !admin ) {
628 throwAFSException( env, JAFSADMNOMEM );
629 return;
630 }
631
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;
639 }
640 }
641
642 jadmin = (*env)->NewStringUTF(env, admin);
643
644 if( userCls == 0 ) {
645 internal_getUserClass( env, juserObject );
646 }
647
648 (*env)->SetObjectField(env, juserObject, user_nameField, jadmin);
649
650 getUserInfoChar( env, cellHandle, admin, juserObject );
651 (*env)->SetBooleanField( env, juserObject, user_cachedInfoField, TRUE );
652
653 free( admin );
654 return 1;
655
656 }
657
658 /**
659 * Signals that the iteration is complete and will not be accessed anymore.
660 *
661 * env the Java environment
662 * cls the current Java class
663 * iterationId the iteration ID of this iteration
664 */
665 JNIEXPORT void JNICALL
666 Java_org_openafs_jafs_Server_getBosAdminsDone (JNIEnv *env, jclass cls,
667 jlong iterationId) {
668
669 afs_status_t ast;
670
671 if( !bos_AdminGetDone( (void *) iterationId, &ast ) ) {
672 throwAFSException( env, ast );
673 return;
674 }
675
676 }
677
678 /**
679 * Returns the total number of keys hosted by the server denoted by
680 * serverHandle.
681 *
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
687 */
688 JNIEXPORT jint JNICALL
689 Java_org_openafs_jafs_Server_getKeyCount (JNIEnv *env, jclass cls,
690 jlong serverHandle) {
691
692 afs_status_t ast;
693 void *iterationId;
694 bos_KeyInfo_t keyEntry;
695 int i = 0;
696
697 if( !bos_KeyGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
698 throwAFSException( env, ast );
699 return -1;
700 }
701
702 while ( bos_KeyGetNext( (void *) iterationId, &keyEntry, &ast ) ) i++;
703
704 if( ast != ADMITERATORDONE ) {
705 throwAFSException( env, ast );
706 return -1;
707 }
708
709 return i;
710 }
711
712 /**
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.
716 *
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
721 */
722 JNIEXPORT jlong JNICALL
723 Java_org_openafs_jafs_Server_getKeysBegin (JNIEnv *env, jclass cls,
724 jlong serverHandle) {
725
726 afs_status_t ast;
727 void *iterationId;
728
729 if( !bos_KeyGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
730 throwAFSException( env, ast );
731 return;
732 }
733
734 return (jlong) iterationId;
735
736 }
737
738 /**
739 * Returns the next key of the server. Returns 0 if there
740 * are no more keys, != 0 otherwise.
741 *
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
748 */
749 JNIEXPORT jint JNICALL
750 Java_org_openafs_jafs_Server_getKeysNext (JNIEnv *env, jclass cls,
751 jlong iterationId,
752 jobject jkeyObject) {
753
754 afs_status_t ast;
755 bos_KeyInfo_t keyEntry;
756
757 if( !bos_KeyGetNext( (void *) iterationId, &keyEntry, &ast ) ) {
758 if( ast == ADMITERATORDONE ) {
759 return 0;
760 } else {
761 throwAFSException( env, ast );
762 return 0;
763 }
764 }
765
766 fillKeyInfo( env, jkeyObject, keyEntry );
767
768 // get the class fields if need be
769 if( keyCls == 0 ) {
770 internal_getKeyClass( env, jkeyObject );
771 }
772
773 (*env)->SetBooleanField( env, jkeyObject, key_cachedInfoField, TRUE );
774
775 return 1;
776
777 }
778
779 /**
780 * Signals that the iteration is complete and will not be accessed anymore.
781 *
782 * env the Java environment
783 * cls the current Java class
784 * iterationId the iteration ID of this iteration
785 */
786 JNIEXPORT void JNICALL
787 Java_org_openafs_jafs_Server_getKeysDone (JNIEnv *env, jclass cls,
788 jlong iterationId) {
789
790 afs_status_t ast;
791
792 if( !bos_KeyGetDone( (void *) iterationId, &ast ) ) {
793 throwAFSException( env, ast );
794 return;
795 }
796
797 }
798
799 /**
800 * Returns the total number of processes hosted by the server denoted by
801 * serverHandle.
802 *
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
808 */
809 JNIEXPORT jint JNICALL
810 Java_org_openafs_jafs_Server_getProcessCount (JNIEnv *env, jclass cls,
811 jlong serverHandle) {
812
813 afs_status_t ast;
814 void *iterationId;
815 char *process;
816 jstring jprocess;
817 int i = 0;
818
819 if( !bos_ProcessNameGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
820 throwAFSException( env, ast );
821 return -1;
822 }
823
824 process = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
825
826 if( !process ) {
827 throwAFSException( env, JAFSADMNOMEM );
828 return -1;
829 }
830
831 while ( bos_ProcessNameGetNext( (void *) iterationId, process, &ast ) ) i++;
832
833 free( process );
834
835 if( ast != ADMITERATORDONE ) {
836 throwAFSException( env, ast );
837 return -1;
838 }
839
840 return i;
841 }
842
843 /**
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.
847 *
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
853 */
854 JNIEXPORT jlong JNICALL
855 Java_org_openafs_jafs_Server_getProcessesBegin (JNIEnv *env, jclass cls,
856 jlong serverHandle) {
857
858 afs_status_t ast;
859 void *iterationId;
860
861 if( !bos_ProcessNameGetBegin( (void *) serverHandle, &iterationId, &ast ) ) {
862 throwAFSException( env, ast );
863 return;
864 }
865
866 return (jlong) iterationId;
867
868 }
869
870 /**
871 * Returns the next process of the server. Returns null
872 * if there are no more processes.
873 *
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
878 */
879 JNIEXPORT jstring JNICALL
880 Java_org_openafs_jafs_Server_getProcessesNextString (JNIEnv *env,
881 jclass cls,
882 jlong iterationId) {
883
884 afs_status_t ast;
885 jstring jprocess;
886 char *process = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
887
888 if( !process ) {
889 throwAFSException( env, JAFSADMNOMEM );
890 return;
891 }
892
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;
900 }
901 }
902
903 jprocess = (*env)->NewStringUTF(env, process);
904 free( process );
905 return jprocess;
906
907 }
908
909 /**
910 * Fills the next process object of the server. Returns 0 if there
911 * are no more processes, != 0 otherwise.
912 *
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
920 */
921 JNIEXPORT jint JNICALL
922 Java_org_openafs_jafs_Server_getProcessesNext (JNIEnv *env, jclass cls,
923 jlong serverHandle,
924 jlong iterationId,
925 jobject jprocessObject) {
926
927 afs_status_t ast;
928 char *process = malloc( sizeof(char)*BOS_MAX_NAME_LEN );
929 jstring jprocess;
930
931 if( !process ) {
932 throwAFSException( env, JAFSADMNOMEM );
933 return;
934 }
935
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;
943 }
944 }
945
946 // get the class fields if need be
947 if( processCls == 0 ) {
948 internal_getProcessClass( env, jprocessObject );
949 }
950
951 jprocess = (*env)->NewStringUTF(env, process);
952 (*env)->SetObjectField(env, jprocessObject, process_nameField, jprocess);
953
954 getProcessInfoChar( env, (void *) serverHandle, process, jprocessObject );
955
956 (*env)->SetBooleanField( env, jprocessObject,
957 process_cachedInfoField, TRUE );
958
959 free( process );
960 return 1;
961
962 }
963
964 /**
965 * Signals that the iteration is complete and will not be accessed anymore.
966 *
967 * env the Java environment
968 * cls the current Java class
969 * iterationId the iteration ID of this iteration
970 */
971 JNIEXPORT void JNICALL
972 Java_org_openafs_jafs_Server_getProcessesDone (JNIEnv *env, jclass cls,
973 jlong iterationId) {
974
975 afs_status_t ast;
976
977 if( !bos_ProcessNameGetDone( (void *) iterationId, &ast ) ) {
978 throwAFSException( env, ast );
979 return;
980 }
981
982 }
983
984 /**
985 * Salvages (restores consistency to) a volume, partition, or server
986 *
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
1015 */
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) {
1028
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;
1040
1041 // convert strings
1042 if( jpartName != NULL ) {
1043 partName = (*env)->GetStringUTFChars(env, jpartName, 0);
1044 if( !partName ) {
1045 throwAFSException( env, JAFSADMNOMEM );
1046 return;
1047 }
1048 } else {
1049 partName = NULL;
1050 }
1051 if( jvolName != NULL ) {
1052 volName = (*env)->GetStringUTFChars(env, jvolName, 0);
1053 if( !volName ) {
1054 if( partName != NULL ) {
1055 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1056 }
1057 throwAFSException( env, JAFSADMNOMEM );
1058 return;
1059 }
1060 } else {
1061 volName = NULL;
1062 }
1063 if( jtempDir != NULL ) {
1064 tempDir = (*env)->GetStringUTFChars(env, jtempDir, 0);
1065 if( !tempDir ) {
1066 if( partName != NULL ) {
1067 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1068 }
1069 if( volName != NULL ) {
1070 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1071 }
1072 throwAFSException( env, JAFSADMNOMEM );
1073 return;
1074 }
1075 } else {
1076 tempDir = NULL;
1077 }
1078 if( jlogFile != NULL ) {
1079 logFile = (*env)->GetStringUTFChars(env, jlogFile, 0);
1080 if( !logFile ) {
1081 if( partName != NULL ) {
1082 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1083 }
1084 if( volName != NULL ) {
1085 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1086 }
1087 if( tempDir != NULL ) {
1088 (*env)->ReleaseStringUTFChars(env, jtempDir, tempDir);
1089 }
1090 throwAFSException( env, JAFSADMNOMEM );
1091 return;
1092 }
1093 } else {
1094 logFile = NULL;
1095 }
1096
1097 // deal with booleans
1098 if( inspectAllVolumes ) {
1099 force = VOS_FORCE;
1100 } else {
1101 force = VOS_NORMAL;
1102 }
1103 if( removeBadlyDamaged ) {
1104 sdv = BOS_DONT_SALVAGE_DAMAGED_VOLUMES;
1105 } else {
1106 sdv = BOS_SALVAGE_DAMAGED_VOLUMES;
1107 }
1108 if( writeInodes ) {
1109 wi = BOS_SALVAGE_WRITE_INODES;
1110 } else {
1111 wi = BOS_SALVAGE_DONT_WRITE_INODES;
1112 }
1113 if( writeRootInodes ) {
1114 wri = BOS_SALVAGE_WRITE_ROOT_INODES;
1115 } else {
1116 wri = BOS_SALVAGE_DONT_WRITE_ROOT_INODES;
1117 }
1118 if( forceDirectory ) {
1119 forceD = BOS_SALVAGE_FORCE_DIRECTORIES;
1120 } else {
1121 forceD = BOS_SALVAGE_DONT_FORCE_DIRECTORIES;
1122 }
1123 if( forceBlockReads ) {
1124 forceBR = BOS_SALVAGE_FORCE_BLOCK_READS;
1125 } else {
1126 forceBR = BOS_SALVAGE_DONT_FORCE_BLOCK_READS;
1127 }
1128
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);
1135 }
1136 if( volName != NULL ) {
1137 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1138 }
1139 if( tempDir != NULL ) {
1140 (*env)->ReleaseStringUTFChars(env, jtempDir, tempDir);
1141 }
1142 if( logFile != NULL ) {
1143 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1144 }
1145 throwAFSException( env, ast );
1146 return;
1147 }
1148
1149 // release strings
1150 if( partName != NULL ) {
1151 (*env)->ReleaseStringUTFChars(env, jpartName, partName);
1152 }
1153 if( volName != NULL ) {
1154 (*env)->ReleaseStringUTFChars(env, jvolName, volName);
1155 }
1156 if( tempDir != NULL ) {
1157 (*env)->ReleaseStringUTFChars(env, jtempDir, tempDir);
1158 }
1159 if( logFile != NULL ) {
1160 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1161 }
1162
1163 }
1164
1165 /**
1166 * Fills in the restart time fields of the given Server
1167 * object.
1168 *
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
1178 */
1179 JNIEXPORT void JNICALL
1180 Java_org_openafs_jafs_Server_getRestartTime
1181 (JNIEnv *env, jclass cls, jlong serverHandle, jint jtype, jobject exectime)
1182 {
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;
1192
1193 // get the class fields if need be
1194 if( exectimeCls == 0 ) {
1195 internal_getExecTimeClass( env, exectime );
1196 }
1197
1198 if( jtype == org_openafs_jafs_Server_RESTART_BINARY ) {
1199 type = BOS_RESTART_DAILY;
1200 } else {
1201 type = BOS_RESTART_WEEKLY;
1202 }
1203
1204 hourField = exectime_HourField;
1205 minField = exectime_MinField;
1206 secField = exectime_SecField;
1207 dayField = exectime_DayField;
1208 neverField = exectime_NeverField;
1209 nowField = exectime_NowField;
1210
1211 if( !bos_ExecutableRestartTimeGet( (void *) serverHandle, type,
1212 &time, &ast ) ) {
1213 throwAFSException( env, ast );
1214 return;
1215 }
1216
1217 // set now
1218 (*env)->SetBooleanField(env, exectime, nowField,
1219 (time.mask & BOS_RESTART_TIME_NOW) );
1220
1221 // set never
1222 (*env)->SetBooleanField(env, exectime, neverField,
1223 (time.mask & BOS_RESTART_TIME_NEVER) );
1224
1225 // set hour
1226 (*env)->SetShortField(env, exectime, hourField, time.hour );
1227
1228 // set minute
1229 (*env)->SetShortField(env, exectime, minField, time.min );
1230
1231 // set second
1232 (*env)->SetShortField(env, exectime, secField, time.sec );
1233
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 );
1239 }
1240
1241 }
1242
1243 /**
1244 * Sets the restart time of the bos server.
1245 *
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
1255 */
1256 JNIEXPORT void JNICALL
1257 Java_org_openafs_jafs_Server_setRestartTime (JNIEnv *env, jclass cls,
1258 jlong serverHandle, jint jtype,
1259 jobject exectime ) {
1260
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;
1280
1281 // get the class fields if need be
1282 if( exectimeCls == 0 ) {
1283 internal_getExecTimeClass( env, exectime );
1284 }
1285
1286 if( jtype == org_openafs_jafs_Server_RESTART_BINARY ) {
1287 type = BOS_RESTART_DAILY;
1288 } else {
1289 type = BOS_RESTART_WEEKLY;
1290 }
1291
1292 hourField = exectime_HourField;
1293 minField = exectime_MinField;
1294 secField = exectime_SecField;
1295 dayField = exectime_DayField;
1296 neverField = exectime_NeverField;
1297 nowField = exectime_NowField;
1298
1299 hour = (*env)->GetShortField(env, exectime, hourField );
1300 if( hour != 0 ) {
1301 doHour = TRUE;
1302 } else {
1303 doHour = FALSE;
1304 }
1305 minute = (*env)->GetShortField(env, exectime, minField );
1306 if( minute != 0 ) {
1307 doMinute = TRUE;
1308 } else {
1309 doMinute = FALSE;
1310 }
1311 second = (*env)->GetShortField(env, exectime, secField );
1312 if( second != 0 ) {
1313 doSecond = TRUE;
1314 } else {
1315 doSecond = FALSE;
1316 }
1317 day = (*env)->GetShortField(env, exectime, dayField );
1318 if( day != -1 ) {
1319 doDay = TRUE;
1320 } else {
1321 doDay = FALSE;
1322 }
1323 doNever = (*env)->GetBooleanField(env, exectime, neverField );
1324 doNow = (*env)->GetBooleanField(env, exectime, nowField );
1325
1326 bzero(&time, sizeof(time));
1327
1328 if( jtype == org_openafs_jafs_Server_RESTART_BINARY ) {
1329 type = BOS_RESTART_DAILY;
1330 } else {
1331 type = BOS_RESTART_WEEKLY;
1332 }
1333
1334 if( doHour ) {
1335 time.mask |= BOS_RESTART_TIME_HOUR;
1336 }
1337 if( doMinute ) {
1338 time.mask |= BOS_RESTART_TIME_MINUTE;
1339 }
1340 if( doSecond ) {
1341 time.mask |= BOS_RESTART_TIME_SECOND;
1342 }
1343 if( doDay ) {
1344 time.mask |= BOS_RESTART_TIME_DAY;
1345 }
1346 if( doNever ) {
1347 time.mask |= BOS_RESTART_TIME_NEVER;
1348 }
1349 if( doNow ) {
1350 time.mask |= BOS_RESTART_TIME_NOW;
1351 }
1352
1353 time.hour = hour;
1354 time.min = minute;
1355 time.sec = second;
1356 time.day = day;
1357
1358 if( !bos_ExecutableRestartTimeSet( (void *) serverHandle, type,
1359 time, &ast ) ) {
1360 throwAFSException( env, ast );
1361 return;
1362 }
1363
1364 }
1365
1366 /**
1367 * Synchronizes a particular server with the volume location database.
1368 *
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
1374 */
1375 JNIEXPORT void JNICALL
1376 Java_org_openafs_jafs_Server_syncServerWithVLDB (JNIEnv *env, jclass cls,
1377 jlong cellHandle,
1378 jlong serverHandle,
1379 jint partition) {
1380
1381 afs_status_t ast;
1382 int *part;
1383
1384 if( partition == -1 ) {
1385 part = NULL;
1386 } else {
1387 part = (int *) &partition;
1388 }
1389
1390 if( !vos_ServerSync( (void *) cellHandle, (void *) serverHandle,
1391 NULL, part, &ast ) ) {
1392 throwAFSException( env, ast );
1393 return;
1394 }
1395
1396 }
1397
1398 /**
1399 * Synchronizes the volume location database with a particular server.
1400 *
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
1407 */
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) {
1414
1415 afs_status_t ast;
1416 int *part;
1417 vos_force_t force;
1418
1419 if( partition == -1 ) {
1420 part = NULL;
1421 } else {
1422 part = (int *) &partition;
1423 }
1424
1425 if( forceDeletion ) {
1426 force = VOS_FORCE;
1427 } else {
1428 force = VOS_NORMAL;
1429 }
1430
1431 if( !vos_VLDBSync( (void *) cellHandle, (void *) serverHandle, NULL, part,
1432 force, &ast ) ) {
1433 throwAFSException( env, ast );
1434 return;
1435 }
1436
1437 }
1438
1439 /**
1440 * Start all server processes.
1441 *
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
1446 */
1447 JNIEXPORT void JNICALL
1448 Java_org_openafs_jafs_Server_startAllProcesses (JNIEnv *env, jclass cls,
1449 jlong serverHandle) {
1450
1451 afs_status_t ast;
1452
1453 if( !bos_ProcessAllStart( (void *) serverHandle, &ast ) ) {
1454 throwAFSException( env, ast );
1455 return;
1456 }
1457
1458 }
1459
1460 /**
1461 * Stop all server processes.
1462 *
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
1467 */
1468 JNIEXPORT void JNICALL
1469 Java_org_openafs_jafs_Server_stopAllProcesses (JNIEnv *env, jclass cls,
1470 jlong serverHandle) {
1471
1472 afs_status_t ast;
1473
1474 if( !bos_ProcessAllStop( (void *) serverHandle, &ast ) ) {
1475 throwAFSException( env, ast );
1476 return;
1477 }
1478
1479 }
1480
1481 /**
1482 * Restart all server processes.
1483 *
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
1489 */
1490 JNIEXPORT void JNICALL
1491 Java_org_openafs_jafs_Server_restartAllProcesses (JNIEnv *env, jclass cls,
1492 jlong serverHandle,
1493 jboolean restartBosServer) {
1494
1495 afs_status_t ast;
1496 bos_RestartBosServer_t rbs;
1497
1498 if( restartBosServer ) {
1499 rbs = BOS_RESTART_BOS_SERVER;
1500 } else {
1501 rbs = BOS_DONT_RESTART_BOS_SERVER;
1502 }
1503
1504 if( !bos_ProcessAllStopAndRestart( (void *) serverHandle, rbs, &ast ) ) {
1505 throwAFSException( env, ast );
1506 return;
1507 }
1508
1509 }
1510
1511 /**
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.
1515 *
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
1520 */
1521 JNIEXPORT jstring JNICALL
1522 Java_org_openafs_jafs_Server_getLog(JNIEnv *env, jclass cls,
1523 jlong serverHandle, jstring jlogFile) {
1524
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;
1531
1532 if( jlogFile != NULL ) {
1533 logFile = (*env)->GetStringUTFChars(env, jlogFile, 0);
1534 if( !logFile ) {
1535 throwAFSException( env, JAFSADMNOMEM );
1536 return;
1537 }
1538 } else {
1539 logFile = NULL;
1540 }
1541
1542 logData = malloc( sizeof(char)*currInLogSize );
1543 if( !logData ) {
1544 throwAFSException( env, JAFSADMNOMEM );
1545 return;
1546 }
1547
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);
1556 }
1557 throwAFSException( env, ast );
1558 return NULL;
1559 }
1560 }
1561
1562 free( logData );
1563
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;
1571 }
1572
1573 if( !logData ) {
1574 // memory exception
1575 if( logFile != NULL ) {
1576 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1577 }
1578 throwAFSException( env, ast );
1579 return NULL;
1580 }
1581
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);
1588 }
1589 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1590 throwAFSException( env, ast );
1591 return NULL;
1592 }
1593
1594 logData[currOutLogSize] == '\0';
1595
1596 logOut = (*env)->NewStringUTF(env, logData);
1597
1598 free( logData );
1599 if( logFile != NULL ) {
1600 (*env)->ReleaseStringUTFChars(env, jlogFile, logFile);
1601 }
1602 return logOut;
1603
1604 }
1605
1606
1607 /**
1608 * Executes any command on the specified server.
1609 *
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
1614 */
1615 JNIEXPORT void JNICALL
1616 Java_org_openafs_jafs_Server_executeCommand (JNIEnv *env, jclass cls,
1617 jlong serverHandle,
1618 jstring jcommand) {
1619
1620 afs_status_t ast;
1621 const char *command;
1622
1623 if( jcommand != NULL ) {
1624 command = (*env)->GetStringUTFChars(env, jcommand, 0);
1625 if( !command ) {
1626 throwAFSException( env, JAFSADMNOMEM );
1627 return;
1628 }
1629 } else {
1630 command = NULL;
1631 }
1632
1633 if( !bos_CommandExecute( (void *) serverHandle, command, &ast ) ) {
1634 if( command != NULL ) {
1635 (*env)->ReleaseStringUTFChars(env, jcommand, command);
1636 }
1637 throwAFSException( env, ast );
1638 return;
1639 }
1640
1641 if( command != NULL ) {
1642 (*env)->ReleaseStringUTFChars(env, jcommand, command);
1643 }
1644
1645 }
1646
1647 // reclaim global memory being used by this portion
1648 JNIEXPORT void JNICALL
1649 Java_org_openafs_jafs_Server_reclaimServerMemory (JNIEnv *env, jclass cls) {
1650
1651 if( serverCls ) {
1652 (*env)->DeleteGlobalRef(env, serverCls);
1653 serverCls = 0;
1654 }
1655
1656 }
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676