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_main.h" 30 #include "libzfs_jni_util.h" 31 #include "libzfs_jni_dataset.h" 32 #include "libzfs_jni_property.h" 33 #include "libzfs_jni_pool.h" 34 #include "libzfs_jni_diskmgt.h" 35 #include "libzfs_jni_disk.h" 36 37 /* 38 * Function prototypes 39 */ 40 41 static void handle_error(const char *, va_list); 42 static void init(); 43 44 /* 45 * Static functions 46 */ 47 48 char libzfs_err[1024]; 49 static void 50 handle_error(const char *fmt, va_list ap) 51 { 52 /* Save the error message in case it's needed */ 53 (void) vsnprintf(libzfs_err, sizeof (libzfs_err), fmt, ap); 54 #ifdef DEBUG 55 (void) fprintf(stderr, "caught error: %s\n", libzfs_err); 56 #endif 57 } 58 59 /* 60 * Initialize the library. Sets the error handler. 61 */ 62 #pragma init(init) 63 static void 64 init() 65 { 66 libzfs_err[0] = '\0'; 67 68 /* libzfs error handler */ 69 zfs_set_error_handler(handle_error); 70 71 /* diskmgt.o error handler */ 72 dmgt_set_error_handler(handle_error); 73 } 74 75 /* 76 * JNI functions 77 */ 78 79 /* 80 * Class: com_sun_zfs_common_model_SystemDataModel 81 * Method: getPools 82 * Signature: ()[Lcom/sun/zfs/common/model/Pool; 83 */ 84 /* ARGSUSED */ 85 JNIEXPORT jobjectArray JNICALL 86 Java_com_sun_zfs_common_model_SystemDataModel_getPools(JNIEnv *env, jobject obj) 87 { 88 zjni_DatasetArrayCallbackData_t data = {0}; 89 int result; 90 91 /* Create an array list */ 92 zjni_ArrayList_t list_obj = {0}; 93 zjni_ArrayList_t *list = &list_obj; 94 zjni_new_ArrayList(env, list); 95 96 data.data.env = env; 97 data.data.list = (zjni_Collection_t *)list; 98 data.typemask = ZFS_TYPE_FILESYSTEM; 99 100 result = zfs_iter_root(zjni_create_add_Dataset, &data); 101 if (result && (*env)->ExceptionOccurred(env) != NULL) { 102 /* Must not call any more Java methods to preserve exception */ 103 return (NULL); 104 } 105 106 return (zjni_Collection_to_array(env, (zjni_Collection_t *)list, 107 ZFSJNI_PACKAGE_DATA "Pool")); 108 } 109 110 /* 111 * Class: com_sun_zfs_common_model_SystemDataModel 112 * Method: getPool 113 * Signature: (Ljava/lang/String;) 114 * Lcom/sun/zfs/common/model/Pool; 115 */ 116 /* ARGSUSED */ 117 JNIEXPORT jobject JNICALL 118 Java_com_sun_zfs_common_model_SystemDataModel_getPool(JNIEnv *env, 119 jobject obj, jstring poolUTF) 120 { 121 return (zjni_get_Dataset(env, poolUTF, ZFS_TYPE_FILESYSTEM)); 122 } 123 124 /* 125 * Class: com_sun_zfs_common_model_SystemDataModel 126 * Method: getFileSystems 127 * Signature: (Ljava/lang/String;) 128 * [Lcom/sun/zfs/common/model/FileSystem; 129 */ 130 /* ARGSUSED */ 131 JNIEXPORT jobjectArray JNICALL 132 Java_com_sun_zfs_common_model_SystemDataModel_getFileSystems(JNIEnv *env, 133 jobject obj, jstring containerUTF) 134 { 135 return (zjni_get_Datasets_below(env, containerUTF, 136 ZFS_TYPE_FILESYSTEM, ZFS_TYPE_FILESYSTEM, 137 ZFSJNI_PACKAGE_DATA "FileSystem")); 138 } 139 140 /* 141 * Class: com_sun_zfs_common_model_SystemDataModel 142 * Method: getFileSystem 143 * Signature: (Ljava/lang/String;) 144 * Lcom/sun/zfs/common/model/FileSystem; 145 */ 146 /* ARGSUSED */ 147 JNIEXPORT jobject JNICALL 148 Java_com_sun_zfs_common_model_SystemDataModel_getFileSystem(JNIEnv *env, 149 jobject obj, jstring nameUTF) 150 { 151 return (zjni_get_Dataset(env, nameUTF, ZFS_TYPE_FILESYSTEM)); 152 } 153 154 /* 155 * Class: com_sun_zfs_common_model_SystemDataModel 156 * Method: getVolumes 157 * Signature: (Ljava/lang/String;) 158 * [Lcom/sun/zfs/common/model/Volume; 159 */ 160 /* ARGSUSED */ 161 JNIEXPORT jobjectArray JNICALL 162 Java_com_sun_zfs_common_model_SystemDataModel_getVolumes(JNIEnv *env, 163 jobject obj, jstring containerUTF) 164 { 165 return (zjni_get_Datasets_below(env, containerUTF, 166 ZFS_TYPE_FILESYSTEM, ZFS_TYPE_VOLUME, 167 ZFSJNI_PACKAGE_DATA "Volume")); 168 } 169 170 /* 171 * Class: com_sun_zfs_common_model_SystemDataModel 172 * Method: getVolume 173 * Signature: (Ljava/lang/String;) 174 * Lcom/sun/zfs/common/model/Volume; 175 */ 176 /* ARGSUSED */ 177 JNIEXPORT jobject JNICALL 178 Java_com_sun_zfs_common_model_SystemDataModel_getVolume(JNIEnv *env, 179 jobject obj, jstring nameUTF) 180 { 181 return (zjni_get_Dataset(env, nameUTF, ZFS_TYPE_VOLUME)); 182 } 183 184 /* 185 * Class: com_sun_zfs_common_model_SystemDataModel 186 * Method: getSnapshots 187 * Signature: (Ljava/lang/String;) 188 * [Lcom/sun/zfs/common/model/Snapshot; 189 */ 190 /* ARGSUSED */ 191 JNIEXPORT jobjectArray JNICALL 192 Java_com_sun_zfs_common_model_SystemDataModel_getSnapshots(JNIEnv *env, 193 jobject obj, jstring datasetUTF) 194 { 195 return (zjni_get_Datasets_below(env, datasetUTF, 196 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, ZFS_TYPE_SNAPSHOT, 197 ZFSJNI_PACKAGE_DATA "Snapshot")); 198 } 199 200 /* 201 * Class: com_sun_zfs_common_model_SystemDataModel 202 * Method: getSnapshot 203 * Signature: (Ljava/lang/String;) 204 * Lcom/sun/zfs/common/model/Snapshot; 205 */ 206 /* ARGSUSED */ 207 JNIEXPORT jobject JNICALL 208 Java_com_sun_zfs_common_model_SystemDataModel_getSnapshot(JNIEnv *env, 209 jobject obj, jstring nameUTF) 210 { 211 return (zjni_get_Dataset(env, nameUTF, ZFS_TYPE_SNAPSHOT)); 212 } 213 214 /* 215 * Class: com_sun_zfs_common_model_SystemDataModel 216 * Method: getDatasets 217 * Signature: (Ljava/lang/String;) 218 * [Lcom/sun/zfs/common/model/Dataset; 219 */ 220 /* ARGSUSED */ 221 JNIEXPORT jobjectArray JNICALL 222 Java_com_sun_zfs_common_model_SystemDataModel_getDatasets(JNIEnv *env, 223 jobject obj, jstring containerUTF) 224 { 225 if (containerUTF == NULL) { 226 return (Java_com_sun_zfs_common_model_SystemDataModel_getPools( 227 env, obj)); 228 } 229 230 return (zjni_get_Datasets_below(env, containerUTF, 231 ZFS_TYPE_FILESYSTEM, ZFS_TYPE_ANY, 232 ZFSJNI_PACKAGE_DATA "Dataset")); 233 } 234 235 /* 236 * Class: com_sun_zfs_common_model_SystemDataModel 237 * Method: getDataset 238 * Signature: (Ljava/lang/String;) 239 * Lcom/sun/zfs/common/model/Dataset; 240 */ 241 /* ARGSUSED */ 242 JNIEXPORT jobject JNICALL 243 Java_com_sun_zfs_common_model_SystemDataModel_getDataset(JNIEnv *env, 244 jobject obj, jstring nameUTF) 245 { 246 return (zjni_get_Dataset(env, nameUTF, ZFS_TYPE_ANY)); 247 } 248 249 /* 250 * Class: com_sun_zfs_common_model_SystemDataModel 251 * Method: getVirtualDevice 252 * Signature: (Ljava/lang/String;J)Lcom/sun/zfs/common/model/VirtualDevice; 253 */ 254 /* ARGSUSED */ 255 JNIEXPORT jobject JNICALL 256 Java_com_sun_zfs_common_model_SystemDataModel_getVirtualDevice(JNIEnv *env, 257 jobject obj, jstring poolUTF, jlong index) 258 { 259 jobject vdev = NULL; 260 261 if (poolUTF != NULL) { 262 const char *pool = (*env)->GetStringUTFChars(env, poolUTF, 263 NULL); 264 zpool_handle_t *zhp = zpool_open(pool); 265 (*env)->ReleaseStringUTFChars(env, poolUTF, pool); 266 267 if (zhp != NULL) { 268 nvlist_t *vdev_cfg = zjni_get_vdev(zhp, NULL, index); 269 if (vdev_cfg != NULL) { 270 vdev = zjni_get_VirtualDevice_from_vdev(env, 271 zhp, vdev_cfg); 272 } 273 zpool_close(zhp); 274 } 275 } 276 277 return (vdev); 278 } 279 280 /* 281 * Class: com_sun_zfs_common_model_SystemDataModel 282 * Method: getVirtualDevices 283 * Signature: (Ljava/lang/String;J) 284 * [Lcom/sun/zfs/common/model/VirtualDevice; 285 */ 286 /* ARGSUSED */ 287 JNIEXPORT jobjectArray JNICALL 288 /* CSTYLED */ 289 Java_com_sun_zfs_common_model_SystemDataModel_getVirtualDevices__Ljava_lang_String_2J( 290 JNIEnv *env, jobject obj, jstring poolUTF, jlong index) 291 { 292 jobjectArray vdevs = NULL; 293 294 if (poolUTF != NULL) { 295 const char *pool = (*env)->GetStringUTFChars(env, poolUTF, 296 NULL); 297 zpool_handle_t *zhp = zpool_open(pool); 298 (*env)->ReleaseStringUTFChars(env, poolUTF, pool); 299 300 /* Is the pool valid? */ 301 if (zhp != NULL) { 302 nvlist_t *vdev_cfg = zjni_get_vdev(zhp, NULL, index); 303 if (vdev_cfg != NULL) { 304 vdevs = zjni_get_VirtualDevices_from_vdev( 305 env, zhp, vdev_cfg); 306 } 307 zpool_close(zhp); 308 } 309 } 310 311 return (vdevs); 312 } 313 314 /* 315 * Class: com_sun_zfs_common_model_SystemDataModel 316 * Method: getVirtualDevices 317 * Signature: (Ljava/lang/String;) 318 * [Lcom/sun/zfs/common/model/VirtualDevice; 319 */ 320 /* ARGSUSED */ 321 JNIEXPORT jobjectArray JNICALL 322 /* CSTYLED */ 323 Java_com_sun_zfs_common_model_SystemDataModel_getVirtualDevices__Ljava_lang_String_2( 324 JNIEnv *env, jobject obj, jstring poolUTF) 325 { 326 jobjectArray vdevs = NULL; 327 328 if (poolUTF != NULL) { 329 const char *pool = (*env)->GetStringUTFChars(env, 330 poolUTF, NULL); 331 zpool_handle_t *zhp = zpool_open(pool); 332 (*env)->ReleaseStringUTFChars(env, poolUTF, pool); 333 334 /* Is the pool valid? */ 335 if (zhp != NULL) { 336 vdevs = zjni_get_VirtualDevices_from_vdev(env, 337 zhp, NULL); 338 zpool_close(zhp); 339 } 340 } 341 342 return (vdevs); 343 } 344 345 /* 346 * Class: com_sun_zfs_common_model_SystemDataModel 347 * Method: getAvailableDisks 348 * Signature: ()[Lcom/sun/zfs/common/model/DiskDevice; 349 */ 350 /* ARGSUSED */ 351 JNIEXPORT jobjectArray JNICALL 352 Java_com_sun_zfs_common_model_SystemDataModel_getAvailableDisks(JNIEnv *env, 353 jobject obj) 354 { 355 int error; 356 zjni_ArrayCallbackData_t data = {0}; 357 jobjectArray array = NULL; 358 359 /* Create an array list */ 360 zjni_ArrayList_t list_obj = {0}; 361 zjni_ArrayList_t *list = &list_obj; 362 zjni_new_ArrayList(env, list); 363 364 data.env = env; 365 data.list = (zjni_Collection_t *)list; 366 error = dmgt_avail_disk_iter(zjni_create_add_DiskDevice, &data); 367 368 if (error) { 369 zjni_throw_exception(env, "%s", libzfs_err); 370 } else { 371 array = zjni_Collection_to_array( 372 env, (zjni_Collection_t *)list, 373 ZFSJNI_PACKAGE_DATA "DiskDevice"); 374 } 375 376 return (array); 377 } 378 379 /* 380 * Class: com_sun_zfs_common_model_SystemDataModel 381 * Method: getDependents 382 * Signature: ([Ljava/lang/String;) 383 * [Lcom/sun/zfs/common/model/Dataset; 384 */ 385 /* ARGSUSED */ 386 JNIEXPORT jobjectArray JNICALL 387 Java_com_sun_zfs_common_model_SystemDataModel_getDependents(JNIEnv *env, 388 jobject obj, jobjectArray paths) 389 { 390 return (zjni_get_Datasets_dependents(env, paths)); 391 } 392 393 /* 394 * Class: com_sun_zfs_common_model_SystemDataModel 395 * Method: getPropertyDefault 396 * Signature: (Ljava/lang/String;) 397 * Lcom/sun/zfs/common/model/Property; 398 */ 399 /* ARGSUSED */ 400 JNIEXPORT jobject JNICALL 401 Java_com_sun_zfs_common_model_SystemDataModel_getPropertyDefault(JNIEnv *env, 402 jobject obj, jstring nameUTF) 403 { 404 jobject defProperty = NULL; 405 406 const char *name = (*env)->GetStringUTFChars(env, nameUTF, NULL); 407 zfs_prop_t prop = zjni_get_property_from_name(name); 408 (*env)->ReleaseStringUTFChars(env, nameUTF, name); 409 410 if (prop != ZFS_PROP_INVAL) { 411 defProperty = zjni_get_default_property(env, prop); 412 } 413 414 return (defProperty); 415 } 416 417 typedef struct zjni_class_type_map { 418 char *class; 419 zfs_type_t type; 420 } zjni_class_type_map_t; 421 422 /* 423 * Class: com_sun_zfs_common_model_SystemDataModel 424 * Method: getValidPropertyNames 425 * Signature: (Ljava/lang/Class;) 426 * [Ljava/lang/String; 427 */ 428 /* ARGSUSED */ 429 JNIEXPORT jobjectArray JNICALL 430 Java_com_sun_zfs_common_model_SystemDataModel_getValidPropertyNames(JNIEnv *env, 431 jobject obj, jclass class) 432 { 433 int i; 434 435 /* Mappings of class names to zfs_type_t */ 436 static zjni_class_type_map_t mappings[] = { 437 { ZFSJNI_PACKAGE_DATA "FileSystem", ZFS_TYPE_FILESYSTEM }, 438 { ZFSJNI_PACKAGE_DATA "Volume", ZFS_TYPE_VOLUME }, 439 { ZFSJNI_PACKAGE_DATA "Snapshot", ZFS_TYPE_SNAPSHOT }, 440 }; 441 int nmappings = sizeof (mappings) / sizeof (zjni_class_type_map_t); 442 443 jclass class_Class = (*env)->FindClass(env, "java/lang/Class"); 444 445 jmethodID isAssignableFrom = (*env)->GetMethodID( 446 env, class_Class, "isAssignableFrom", "(Ljava/lang/Class;)Z"); 447 448 /* Create an array list for the property names */ 449 zjni_ArrayList_t list_obj = {0}; 450 zjni_ArrayList_t *list = &list_obj; 451 zjni_new_ArrayList(env, list); 452 453 /* For each mapping... */ 454 for (i = 0; i < nmappings; i++) { 455 /* 456 * Is the given class an instance of the class in the mapping? 457 */ 458 jclass typeClass = (*env)->FindClass(env, mappings[i].class); 459 460 jboolean isInstance = (*env)->CallBooleanMethod( 461 env, typeClass, isAssignableFrom, class); 462 463 if (isInstance == JNI_TRUE) { 464 zfs_prop_t prop; 465 for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) { 466 if (zfs_prop_valid_for_type(prop, 467 mappings[i].type)) { 468 /* Add name of property to list */ 469 jstring propName = 470 (*env)->NewStringUTF(env, 471 zfs_prop_to_name(prop)); 472 (*env)->CallBooleanMethod( 473 env, 474 ((zjni_Object_t *)list)->object, 475 ((zjni_Collection_t *)list)-> 476 method_add, propName); 477 } 478 } 479 break; 480 } 481 } 482 483 return (zjni_Collection_to_array( 484 env, (zjni_Collection_t *)list, "java/lang/String")); 485 } 486