1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "libzfs_jni_pool.h" 30 #include "libzfs_jni_util.h" 31 #include <strings.h> 32 33 /* 34 * Types 35 */ 36 37 typedef struct ImportablePoolBean { 38 zjni_Object_t super; 39 40 jmethodID method_setName; 41 jmethodID method_setId; 42 jmethodID method_setState; 43 jmethodID method_setHealth; 44 } ImportablePoolBean_t; 45 46 typedef struct VirtualDeviceBean { 47 zjni_Object_t super; 48 49 jmethodID method_setPoolName; 50 jmethodID method_setIndex; 51 jmethodID method_setSize; 52 jmethodID method_setUsed; 53 } VirtualDeviceBean_t; 54 55 typedef struct DiskVirtualDeviceBean { 56 VirtualDeviceBean_t super; 57 58 jmethodID method_setDiskName; 59 } DiskVirtualDeviceBean_t; 60 61 typedef struct FileVirtualDeviceBean { 62 VirtualDeviceBean_t super; 63 64 jmethodID method_setFileName; 65 } FileVirtualDeviceBean_t; 66 67 typedef struct RAIDVirtualDeviceBean { 68 VirtualDeviceBean_t super; 69 } RAIDVirtualDeviceBean_t; 70 71 typedef struct MirrorVirtualDeviceBean { 72 VirtualDeviceBean_t super; 73 } MirrorVirtualDeviceBean_t; 74 75 /* 76 * Function prototypes 77 */ 78 79 static void new_ImportablePoolBean(JNIEnv *, ImportablePoolBean_t *); 80 static void new_VirtualDevice(JNIEnv *, VirtualDeviceBean_t *); 81 static void new_DiskVirtualDeviceBean(JNIEnv *, DiskVirtualDeviceBean_t *); 82 static void new_FileVirtualDeviceBean(JNIEnv *, FileVirtualDeviceBean_t *); 83 static void new_RAIDVirtualDeviceBean(JNIEnv *, RAIDVirtualDeviceBean_t *); 84 static void new_MirrorVirtualDeviceBean(JNIEnv *, MirrorVirtualDeviceBean_t *); 85 static jobject uint64_to_state(JNIEnv *, uint64_t); 86 static int populate_ImportablePoolBean( 87 JNIEnv *, ImportablePoolBean_t *, char *, uint64_t, uint64_t, char *); 88 static int populate_VirtualDeviceBean( 89 JNIEnv *, zpool_handle_t *, nvlist_t *, VirtualDeviceBean_t *); 90 static int populate_DiskVirtualDeviceBean( 91 JNIEnv *, zpool_handle_t *, nvlist_t *, DiskVirtualDeviceBean_t *); 92 static int populate_FileVirtualDeviceBean( 93 JNIEnv *, zpool_handle_t *, nvlist_t *, FileVirtualDeviceBean_t *); 94 static int populate_RAIDVirtualDeviceBean( 95 JNIEnv *, zpool_handle_t *, nvlist_t *, RAIDVirtualDeviceBean_t *); 96 static int populate_MirrorVirtualDeviceBean( 97 JNIEnv *, zpool_handle_t *, nvlist_t *, MirrorVirtualDeviceBean_t *); 98 static jobject create_ImportablePoolBean( 99 JNIEnv *, char *, uint64_t, uint64_t, char *); 100 static jobject create_DiskVirtualDeviceBean( 101 JNIEnv *, zpool_handle_t *, nvlist_t *); 102 static jobject create_FileVirtualDeviceBean( 103 JNIEnv *, zpool_handle_t *, nvlist_t *); 104 static jobject create_RAIDVirtualDeviceBean( 105 JNIEnv *, zpool_handle_t *, nvlist_t *); 106 static jobject create_MirrorVirtualDeviceBean( 107 JNIEnv *, zpool_handle_t *, nvlist_t *); 108 109 /* 110 * Static functions 111 */ 112 113 /* Create a ImportablePoolBean */ 114 static void 115 new_ImportablePoolBean(JNIEnv *env, ImportablePoolBean_t *bean) 116 { 117 zjni_Object_t *object = (zjni_Object_t *)bean; 118 119 if (object->object == NULL) { 120 object->class = 121 (*env)->FindClass(env, 122 ZFSJNI_PACKAGE_DATA "ImportablePoolBean"); 123 124 object->constructor = 125 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 126 127 object->object = 128 (*env)->NewObject(env, object->class, object->constructor); 129 } 130 131 bean->method_setName = (*env)->GetMethodID( 132 env, object->class, "setName", "(Ljava/lang/String;)V"); 133 134 bean->method_setId = (*env)->GetMethodID( 135 env, object->class, "setId", "(J)V"); 136 137 bean->method_setState = (*env)->GetMethodID( 138 env, object->class, "setState", 139 "(L" ZFSJNI_PACKAGE_DATA "ImportablePool$State;)V"); 140 141 bean->method_setHealth = (*env)->GetMethodID( 142 env, object->class, "setHealth", "(Ljava/lang/String;)V"); 143 } 144 145 /* Create a VirtualDeviceBean */ 146 static void 147 new_VirtualDevice(JNIEnv *env, VirtualDeviceBean_t *bean) 148 { 149 zjni_Object_t *object = (zjni_Object_t *)bean; 150 151 if (object->object == NULL) { 152 object->class = 153 (*env)->FindClass(env, 154 ZFSJNI_PACKAGE_DATA "VirtualDeviceBean"); 155 156 object->constructor = 157 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 158 159 object->object = 160 (*env)->NewObject(env, object->class, object->constructor); 161 } 162 163 bean->method_setPoolName = (*env)->GetMethodID( 164 env, object->class, "setPoolName", "(Ljava/lang/String;)V"); 165 166 bean->method_setIndex = (*env)->GetMethodID( 167 env, object->class, "setIndex", "(J)V"); 168 169 bean->method_setSize = (*env)->GetMethodID( 170 env, object->class, "setSize", "(J)V"); 171 172 bean->method_setUsed = (*env)->GetMethodID( 173 env, object->class, "setUsed", "(J)V"); 174 } 175 176 /* Create a DiskVirtualDeviceBean */ 177 static void 178 new_DiskVirtualDeviceBean(JNIEnv *env, DiskVirtualDeviceBean_t *bean) 179 { 180 zjni_Object_t *object = (zjni_Object_t *)bean; 181 182 if (object->object == NULL) { 183 object->class = (*env)->FindClass( 184 env, ZFSJNI_PACKAGE_DATA "DiskVirtualDeviceBean"); 185 186 object->constructor = 187 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 188 189 object->object = 190 (*env)->NewObject(env, object->class, object->constructor); 191 } 192 193 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean); 194 195 bean->method_setDiskName = (*env)->GetMethodID( 196 env, object->class, "setDiskName", "(Ljava/lang/String;)V"); 197 198 } 199 200 /* Create a FileVirtualDeviceBean */ 201 static void 202 new_FileVirtualDeviceBean(JNIEnv *env, FileVirtualDeviceBean_t *bean) 203 { 204 zjni_Object_t *object = (zjni_Object_t *)bean; 205 206 if (object->object == NULL) { 207 object->class = (*env)->FindClass( 208 env, ZFSJNI_PACKAGE_DATA "FileVirtualDeviceBean"); 209 210 object->constructor = 211 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 212 213 object->object = 214 (*env)->NewObject(env, object->class, object->constructor); 215 } 216 217 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean); 218 219 bean->method_setFileName = (*env)->GetMethodID( 220 env, object->class, "setFileName", "(Ljava/lang/String;)V"); 221 } 222 223 /* Create a RAIDVirtualDeviceBean */ 224 static void 225 new_RAIDVirtualDeviceBean(JNIEnv *env, RAIDVirtualDeviceBean_t *bean) 226 { 227 zjni_Object_t *object = (zjni_Object_t *)bean; 228 229 if (object->object == NULL) { 230 231 object->class = (*env)->FindClass( 232 env, ZFSJNI_PACKAGE_DATA "RAIDVirtualDeviceBean"); 233 234 object->constructor = 235 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 236 237 object->object = 238 (*env)->NewObject(env, object->class, object->constructor); 239 } 240 241 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean); 242 } 243 244 /* Create a MirrorVirtualDeviceBean */ 245 static void 246 new_MirrorVirtualDeviceBean(JNIEnv *env, MirrorVirtualDeviceBean_t *bean) 247 { 248 zjni_Object_t *object = (zjni_Object_t *)bean; 249 250 if (object->object == NULL) { 251 object->class = (*env)->FindClass( 252 env, ZFSJNI_PACKAGE_DATA "MirrorVirtualDeviceBean"); 253 254 object->constructor = 255 (*env)->GetMethodID(env, object->class, "<init>", "()V"); 256 257 object->object = 258 (*env)->NewObject(env, object->class, object->constructor); 259 } 260 261 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean); 262 } 263 264 static jobject 265 uint64_to_state(JNIEnv *env, uint64_t pool_state) 266 { 267 jobject state_obj; 268 269 jclass class_State = (*env)->FindClass( 270 env, ZFSJNI_PACKAGE_DATA "ImportablePool$State"); 271 272 jmethodID method_valueOf = (*env)->GetStaticMethodID( 273 env, class_State, "valueOf", 274 "(Ljava/lang/String;)L" 275 ZFSJNI_PACKAGE_DATA "ImportablePool$State;"); 276 277 char *str = zjni_get_state_str(pool_state); 278 if (str != NULL) { 279 jstring utf = (*env)->NewStringUTF(env, str); 280 281 state_obj = (*env)->CallStaticObjectMethod( 282 env, class_State, method_valueOf, utf); 283 } 284 285 return (state_obj); 286 } 287 288 static int 289 populate_ImportablePoolBean(JNIEnv *env, ImportablePoolBean_t *bean, 290 char *name, uint64_t guid, uint64_t pool_state, char *health) 291 { 292 zjni_Object_t *object = (zjni_Object_t *)bean; 293 294 /* Set name */ 295 (*env)->CallVoidMethod(env, object->object, bean->method_setName, 296 (*env)->NewStringUTF(env, name)); 297 298 /* Set state */ 299 (*env)->CallVoidMethod( 300 env, object->object, bean->method_setState, 301 uint64_to_state(env, pool_state)); 302 303 /* Set guid */ 304 (*env)->CallVoidMethod( 305 env, object->object, bean->method_setId, (jlong)guid); 306 307 /* Set health */ 308 (*env)->CallVoidMethod(env, object->object, bean->method_setHealth, 309 (*env)->NewStringUTF(env, health)); 310 311 return (0); 312 } 313 314 static int 315 populate_VirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, 316 nvlist_t *vdev, VirtualDeviceBean_t *bean) 317 { 318 int result; 319 uint64_t vdev_id; 320 zjni_Object_t *object = (zjni_Object_t *)bean; 321 322 /* Set pool name */ 323 jstring poolUTF = (*env)->NewStringUTF(env, zpool_get_name(zhp)); 324 (*env)->CallVoidMethod( 325 env, object->object, bean->method_setPoolName, poolUTF); 326 327 /* Get index */ 328 result = nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &vdev_id); 329 if (result != 0) { 330 zjni_throw_exception(env, 331 "could not retrieve virtual device ID (pool %s)", 332 zpool_get_name(zhp)); 333 } else { 334 335 uint64_t used; 336 uint64_t total; 337 338 (*env)->CallVoidMethod( 339 env, object->object, bean->method_setIndex, (jlong)vdev_id); 340 341 /* Set used space */ 342 used = zpool_get_space_used(zhp); 343 344 (*env)->CallVoidMethod( 345 env, object->object, bean->method_setUsed, (jlong)used); 346 347 /* Set available space */ 348 total = zpool_get_space_total(zhp); 349 350 (*env)->CallVoidMethod( 351 env, object->object, bean->method_setSize, (jlong)total); 352 } 353 354 return (result != 0); 355 } 356 357 static int 358 populate_DiskVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, 359 nvlist_t *vdev, DiskVirtualDeviceBean_t *bean) 360 { 361 char *path; 362 int result = populate_VirtualDeviceBean( 363 env, zhp, vdev, (VirtualDeviceBean_t *)bean); 364 365 if (result) { 366 /* Must not call any more Java methods to preserve exception */ 367 return (-1); 368 } 369 370 /* Set path */ 371 result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path); 372 if (result != 0) { 373 zjni_throw_exception(env, 374 "could not retrive path from disk virtual device (pool %s)", 375 zpool_get_name(zhp)); 376 } else { 377 378 jstring pathUTF = (*env)->NewStringUTF(env, path); 379 (*env)->CallVoidMethod(env, ((zjni_Object_t *)bean)->object, 380 bean->method_setDiskName, pathUTF); 381 } 382 383 return (result != 0); 384 } 385 386 static int 387 populate_FileVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, 388 nvlist_t *vdev, FileVirtualDeviceBean_t *bean) 389 { 390 char *path; 391 int result = populate_VirtualDeviceBean( 392 env, zhp, vdev, (VirtualDeviceBean_t *)bean); 393 394 if (result) { 395 /* Must not call any more Java methods to preserve exception */ 396 return (-1); 397 } 398 399 /* Set path */ 400 result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path); 401 if (result != 0) { 402 zjni_throw_exception(env, 403 "could not retrive path from disk virtual device (pool %s)", 404 zpool_get_name(zhp)); 405 } else { 406 407 jstring pathUTF = (*env)->NewStringUTF(env, path); 408 (*env)->CallVoidMethod(env, ((zjni_Object_t *)bean)->object, 409 bean->method_setFileName, pathUTF); 410 } 411 412 return (result != 0); 413 } 414 415 static int 416 populate_RAIDVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, 417 nvlist_t *vdev, RAIDVirtualDeviceBean_t *bean) 418 { 419 return (populate_VirtualDeviceBean(env, zhp, vdev, 420 (VirtualDeviceBean_t *)bean)); 421 } 422 423 static int 424 populate_MirrorVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, 425 nvlist_t *vdev, MirrorVirtualDeviceBean_t *bean) 426 { 427 return (populate_VirtualDeviceBean(env, zhp, vdev, 428 (VirtualDeviceBean_t *)bean)); 429 } 430 431 static jobject 432 create_ImportablePoolBean(JNIEnv *env, char *name, 433 uint64_t guid, uint64_t pool_state, char *health) 434 { 435 int result; 436 ImportablePoolBean_t bean_obj = {0}; 437 ImportablePoolBean_t *bean = &bean_obj; 438 439 /* Construct ImportablePoolBean */ 440 new_ImportablePoolBean(env, bean); 441 442 result = populate_ImportablePoolBean( 443 env, bean, name, guid, pool_state, health); 444 if (result) { 445 /* Must not call any more Java methods to preserve exception */ 446 return (NULL); 447 } 448 449 return (((zjni_Object_t *)bean)->object); 450 } 451 452 static jobject 453 create_DiskVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, nvlist_t *vdev) 454 { 455 int result; 456 DiskVirtualDeviceBean_t bean_obj = {0}; 457 DiskVirtualDeviceBean_t *bean = &bean_obj; 458 459 /* Construct DiskVirtualDeviceBean */ 460 new_DiskVirtualDeviceBean(env, bean); 461 462 result = populate_DiskVirtualDeviceBean(env, zhp, vdev, bean); 463 if (result) { 464 /* Must not call any more Java methods to preserve exception */ 465 return (NULL); 466 } 467 468 return (((zjni_Object_t *)bean)->object); 469 } 470 471 static jobject 472 create_FileVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, nvlist_t *vdev) 473 { 474 int result; 475 FileVirtualDeviceBean_t bean_obj = {0}; 476 FileVirtualDeviceBean_t *bean = &bean_obj; 477 478 /* Construct FileVirtualDeviceBean */ 479 new_FileVirtualDeviceBean(env, bean); 480 481 result = populate_FileVirtualDeviceBean(env, zhp, vdev, bean); 482 if (result) { 483 /* Must not call any more Java methods to preserve exception */ 484 return (NULL); 485 } 486 487 return (((zjni_Object_t *)bean)->object); 488 } 489 490 static jobject 491 create_RAIDVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, nvlist_t *vdev) 492 { 493 int result; 494 RAIDVirtualDeviceBean_t bean_obj = {0}; 495 RAIDVirtualDeviceBean_t *bean = &bean_obj; 496 497 ((zjni_Object_t *)bean)->object = NULL; 498 499 /* Construct RAIDVirtualDeviceBean */ 500 new_RAIDVirtualDeviceBean(env, bean); 501 502 result = populate_RAIDVirtualDeviceBean(env, zhp, vdev, bean); 503 if (result) { 504 /* Must not call any more Java methods to preserve exception */ 505 return (NULL); 506 } 507 508 return (((zjni_Object_t *)bean)->object); 509 } 510 511 static jobject 512 create_MirrorVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp, nvlist_t *vdev) 513 { 514 int result; 515 MirrorVirtualDeviceBean_t bean_obj = {0}; 516 MirrorVirtualDeviceBean_t *bean = &bean_obj; 517 518 /* Construct MirrorVirtualDeviceBean */ 519 new_MirrorVirtualDeviceBean(env, bean); 520 521 result = populate_MirrorVirtualDeviceBean(env, zhp, vdev, bean); 522 if (result) { 523 /* Must not call any more Java methods to preserve exception */ 524 return (NULL); 525 } 526 527 return (((zjni_Object_t *)bean)->object); 528 } 529 530 /* 531 * Package-private functions 532 */ 533 534 /* 535 * Gets the root vdev (an nvlist_t *) for the given pool. 536 */ 537 nvlist_t * 538 zjni_get_root_vdev(zpool_handle_t *zhp) 539 { 540 nvlist_t *root = NULL; 541 542 if (zhp != NULL) { 543 nvlist_t *attrs = zpool_get_config(zhp, NULL); 544 545 if (attrs != NULL) { 546 int result = nvlist_lookup_nvlist( 547 attrs, ZPOOL_CONFIG_VDEV_TREE, &root); 548 if (result != 0) { 549 root = NULL; 550 } 551 } 552 } 553 554 return (root); 555 } 556 557 /* 558 * Gets the vdev (an nvlist_t *) with the given vdev_id, below the 559 * given vdev. If the given vdev is NULL, all vdevs within the given 560 * pool are searched. 561 */ 562 nvlist_t * 563 zjni_get_vdev(zpool_handle_t *zhp, nvlist_t *vdev_parent, 564 uint64_t vdev_id_to_find) 565 { 566 int result; 567 568 /* Was a vdev specified? */ 569 if (vdev_parent == NULL) { 570 /* No -- retrieve the top-level pool vdev */ 571 vdev_parent = zjni_get_root_vdev(zhp); 572 } else { 573 /* Get index of this vdev and compare with vdev_id_to_find */ 574 uint64_t id; 575 result = nvlist_lookup_uint64( 576 vdev_parent, ZPOOL_CONFIG_GUID, &id); 577 if (result == 0 && id == vdev_id_to_find) { 578 return (vdev_parent); 579 } 580 } 581 582 if (vdev_parent != NULL) { 583 584 nvlist_t **children; 585 uint_t nelem = 0; 586 587 /* Get the vdevs under this vdev */ 588 result = nvlist_lookup_nvlist_array( 589 vdev_parent, ZPOOL_CONFIG_CHILDREN, &children, &nelem); 590 591 if (result == 0) { 592 593 int i; 594 nvlist_t *child; 595 596 /* For each vdev child... */ 597 for (i = 0; i < nelem; i++) { 598 child = zjni_get_vdev(zhp, children[i], 599 vdev_id_to_find); 600 if (child != NULL) { 601 return (child); 602 } 603 } 604 } 605 } 606 607 return (NULL); 608 } 609 610 jobject 611 zjni_get_VirtualDevice_from_vdev(JNIEnv *env, zpool_handle_t *zhp, 612 nvlist_t *vdev) 613 { 614 jobject obj = NULL; 615 char *type = NULL; 616 int result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE, &type); 617 618 if (result == 0) { 619 if (strcmp(type, VDEV_TYPE_DISK) == 0) { 620 obj = create_DiskVirtualDeviceBean(env, zhp, vdev); 621 } else if (strcmp(type, VDEV_TYPE_FILE) == 0) { 622 obj = create_FileVirtualDeviceBean(env, zhp, vdev); 623 } else if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) { 624 obj = create_RAIDVirtualDeviceBean(env, zhp, vdev); 625 } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) { 626 obj = create_MirrorVirtualDeviceBean(env, zhp, vdev); 627 } else if (strcmp(type, VDEV_TYPE_REPLACING) == 0) { 628 629 /* Get the vdevs under this vdev */ 630 nvlist_t **children; 631 uint_t nelem = 0; 632 int result = nvlist_lookup_nvlist_array( 633 vdev, ZPOOL_CONFIG_CHILDREN, &children, &nelem); 634 635 if (result == 0 && nelem > 0) { 636 637 /* Get last vdev child (replacement device) */ 638 nvlist_t *child = children[nelem - 1]; 639 640 obj = zjni_get_VirtualDevice_from_vdev(env, 641 zhp, child); 642 } 643 } 644 } 645 646 return (obj); 647 } 648 649 jobject 650 zjni_get_VirtualDevices_from_vdev(JNIEnv *env, zpool_handle_t *zhp, 651 nvlist_t *vdev_parent) 652 { 653 /* Create an array list for the vdevs */ 654 zjni_ArrayList_t list_class = {0}; 655 zjni_ArrayList_t *list_class_p = &list_class; 656 zjni_new_ArrayList(env, list_class_p); 657 658 /* Was a vdev specified? */ 659 if (vdev_parent == NULL) { 660 /* No -- retrieve the top-level pool vdev */ 661 vdev_parent = zjni_get_root_vdev(zhp); 662 } 663 664 if (vdev_parent != NULL) { 665 666 /* Get the vdevs under this vdev */ 667 nvlist_t **children; 668 uint_t nelem = 0; 669 int result = nvlist_lookup_nvlist_array( 670 vdev_parent, ZPOOL_CONFIG_CHILDREN, &children, &nelem); 671 672 if (result == 0) { 673 674 /* For each vdev child... */ 675 int i; 676 for (i = 0; i < nelem; i++) { 677 nvlist_t *child = children[i]; 678 679 /* Create a Java object from this vdev */ 680 jobject obj = 681 zjni_get_VirtualDevice_from_vdev(env, 682 zhp, child); 683 684 if ((*env)->ExceptionOccurred(env) != NULL) { 685 /* 686 * Must not call any more Java methods 687 * to preserve exception 688 */ 689 return (NULL); 690 } 691 692 if (obj != NULL) { 693 /* Add child to child vdev list */ 694 (*env)->CallBooleanMethod(env, 695 ((zjni_Object_t *)list_class_p)->object, 696 ((zjni_Collection_t *)list_class_p)-> 697 method_add, obj); 698 } 699 } 700 } 701 } 702 703 return (zjni_Collection_to_array( 704 env, (zjni_Collection_t *)list_class_p, 705 ZFSJNI_PACKAGE_DATA "VirtualDevice")); 706 } 707 708 int 709 zjni_create_add_ImportablePool(char *name, 710 uint64_t guid, uint64_t pool_state, char *health, void *data) { 711 712 JNIEnv *env = ((zjni_ArrayCallbackData_t *)data)->env; 713 zjni_Collection_t *list = ((zjni_ArrayCallbackData_t *)data)->list; 714 715 /* Construct ImportablePool object */ 716 jobject bean = create_ImportablePoolBean( 717 env, name, guid, pool_state, health); 718 if (bean == NULL) { 719 return (-1); 720 } 721 722 /* Add bean to list */ 723 (*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object, 724 ((zjni_Collection_t *)list)->method_add, bean); 725 726 return (0); 727 } 728 729 /* 730 * Extern functions 731 */ 732 733 /* 734 * Iterates through each importable pool on the system. For each 735 * importable pool, runs the given function with the given void as the 736 * last arg. 737 */ 738 int 739 zjni_ipool_iter(int argc, char **argv, zjni_ipool_iter_f func, void *data) 740 { 741 nvlist_t *pools = zpool_find_import(argc, argv); 742 743 if (pools != NULL) { 744 745 nvpair_t *elem = NULL; 746 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) { 747 nvlist_t *config; 748 char *name; 749 uint64_t guid; 750 uint64_t pool_state; 751 char *health; 752 753 if (nvpair_value_nvlist(elem, &config) != 0 || 754 nvlist_lookup_string(config, 755 ZPOOL_CONFIG_POOL_NAME, &name) != 0 || 756 nvlist_lookup_uint64(config, 757 ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || 758 nvlist_lookup_uint64(config, 759 ZPOOL_CONFIG_POOL_STATE, &pool_state) != 0 || 760 nvlist_lookup_string(config, 761 ZPOOL_CONFIG_POOL_HEALTH, &health) != 0) { 762 763 return (-1); 764 } 765 766 /* Run the given function */ 767 if (func(name, guid, pool_state, health, data)) { 768 return (-1); 769 } 770 } 771 } 772 773 return (0); 774 } 775 776 char * 777 zjni_get_state_str(uint64_t pool_state) 778 { 779 char *str = NULL; 780 switch (pool_state) { 781 case POOL_STATE_ACTIVE: 782 str = "POOL_STATE_ACTIVE"; 783 break; 784 785 case POOL_STATE_EXPORTED: 786 str = "POOL_STATE_EXPORTED"; 787 break; 788 789 case POOL_STATE_DESTROYED: 790 str = "POOL_STATE_DESTROYED"; 791 break; 792 793 case POOL_STATE_UNINITIALIZED: 794 str = "POOL_STATE_UNINITIALIZED"; 795 break; 796 797 case POOL_STATE_UNAVAIL: 798 str = "POOL_STATE_UNAVAIL"; 799 break; 800 } 801 802 return (str); 803 } 804