4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2015 by Delphix. All rights reserved.
31 #include "libzfs_jni_util.h"
32 #include "libzfs_jni_dataset.h"
33 #include "libzfs_jni_property.h"
34 #include "libzfs_jni_pool.h"
37 #define REGEX_ZFS_NAME "^((([^/]*)(/.+)?)[/@])?([^/]+)/*"
38 #define REGEX_ZFS_NAME_NGROUPS 6
39 #define REGEX_ZFS_NAME_POOL_GROUP 3
40 #define REGEX_ZFS_NAME_PARENT_GROUP 2
41 #define REGEX_ZFS_NAME_BASE_GROUP 5
47 typedef struct DatasetBean
{
50 jmethodID method_setPoolName
;
51 jmethodID method_setParentName
;
52 jmethodID method_setBaseName
;
53 jmethodID method_setProperties
;
54 jmethodID method_addProperty
;
57 typedef struct FileSystemBean
{
61 typedef struct PoolBean
{
62 FileSystemBean_t super
;
63 PoolStatsBean_t interface_PoolStats
;
66 typedef struct VolumeBean
{
70 typedef struct SnapshotBean
{
74 typedef struct FileSystemSnapshotBean
{
76 } FileSystemSnapshotBean_t
;
78 typedef struct VolumeSnapshotBean
{
80 } VolumeSnapshotBean_t
;
86 static void new_DatasetBean(JNIEnv
*, DatasetBean_t
*);
87 static void new_PoolBean(JNIEnv
*, PoolBean_t
*);
88 static void new_FileSystemBean(JNIEnv
*, FileSystemBean_t
*);
89 static void new_VolumeBean(JNIEnv
*, VolumeBean_t
*);
90 static void new_SnapshotBean(JNIEnv
*, SnapshotBean_t
*);
91 static void new_FileSystemSnapshotBean(JNIEnv
*, FileSystemSnapshotBean_t
*);
92 static void new_VolumeSnapshotBean(JNIEnv
*, VolumeSnapshotBean_t
*);
93 static int set_name_in_DatasetBean(JNIEnv
*, char *, DatasetBean_t
*);
94 static int populate_DatasetBean(JNIEnv
*, zfs_handle_t
*, DatasetBean_t
*);
95 static int populate_PoolBean(
96 JNIEnv
*, zpool_handle_t
*, zfs_handle_t
*, PoolBean_t
*);
97 static int populate_FileSystemBean(
98 JNIEnv
*, zfs_handle_t
*, FileSystemBean_t
*);
99 static int populate_VolumeBean(
100 JNIEnv
*, zfs_handle_t
*, VolumeBean_t
*);
101 static int populate_SnapshotBean(JNIEnv
*, zfs_handle_t
*, SnapshotBean_t
*);
102 static int populate_FileSystemSnapshotBean(
103 JNIEnv
*, zfs_handle_t
*, FileSystemSnapshotBean_t
*);
104 static int populate_VolumeSnapshotBean(
105 JNIEnv
*, zfs_handle_t
*, VolumeSnapshotBean_t
*);
106 static jobject
create_PoolBean(JNIEnv
*, zpool_handle_t
*, zfs_handle_t
*);
107 static jobject
create_FileSystemBean(JNIEnv
*, zfs_handle_t
*);
108 static jobject
create_VolumeBean(JNIEnv
*, zfs_handle_t
*);
109 static jobject
create_FileSystemSnapshotBean(JNIEnv
*, zfs_handle_t
*);
110 static jobject
create_VolumeSnapshotBean(JNIEnv
*, zfs_handle_t
*);
111 static jobject
create_DatasetBean(JNIEnv
*, zfs_handle_t
*);
112 static int is_fs_snapshot(zfs_handle_t
*);
113 static int is_pool_name(const char *);
119 /* Create a DatasetBean */
121 new_DatasetBean(JNIEnv
*env
, DatasetBean_t
*bean
)
123 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
125 if (object
->object
== NULL
) {
127 (*env
)->FindClass(env
, ZFSJNI_PACKAGE_DATA
"DatasetBean");
129 object
->constructor
=
130 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
133 (*env
)->NewObject(env
, object
->class, object
->constructor
);
136 bean
->method_setPoolName
= (*env
)->GetMethodID(
137 env
, object
->class, "setPoolName", "(Ljava/lang/String;)V");
139 bean
->method_setParentName
= (*env
)->GetMethodID(
140 env
, object
->class, "setParentName", "(Ljava/lang/String;)V");
142 bean
->method_setBaseName
= (*env
)->GetMethodID(
143 env
, object
->class, "setBaseName", "(Ljava/lang/String;)V");
145 bean
->method_setProperties
= (*env
)->GetMethodID(
146 env
, object
->class, "setProperties",
147 "([L" ZFSJNI_PACKAGE_DATA
"Property;)V");
149 bean
->method_addProperty
= (*env
)->GetMethodID(
150 env
, object
->class, "addProperty",
151 "(L" ZFSJNI_PACKAGE_DATA
"Property;)V");
154 /* Create a PoolBean */
156 new_PoolBean(JNIEnv
*env
, PoolBean_t
*bean
)
158 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
160 if (object
->object
== NULL
) {
163 (*env
)->FindClass(env
, ZFSJNI_PACKAGE_DATA
"PoolBean");
165 object
->constructor
=
166 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
169 (*env
)->NewObject(env
, object
->class, object
->constructor
);
172 new_FileSystemBean(env
, (FileSystemBean_t
*)bean
);
173 new_PoolStats(env
, &(bean
->interface_PoolStats
), object
);
176 /* Create a FileSystemBean */
178 new_FileSystemBean(JNIEnv
*env
, FileSystemBean_t
*bean
)
180 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
182 if (object
->object
== NULL
) {
184 (*env
)->FindClass(env
,
185 ZFSJNI_PACKAGE_DATA
"FileSystemBean");
187 object
->constructor
=
188 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
191 (*env
)->NewObject(env
, object
->class, object
->constructor
);
194 new_DatasetBean(env
, (DatasetBean_t
*)bean
);
197 /* Create a VolumeBean */
199 new_VolumeBean(JNIEnv
*env
, VolumeBean_t
*bean
)
201 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
203 if (object
->object
== NULL
) {
205 (*env
)->FindClass(env
,
206 ZFSJNI_PACKAGE_DATA
"VolumeBean");
208 object
->constructor
=
209 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
212 (*env
)->NewObject(env
, object
->class, object
->constructor
);
215 new_DatasetBean(env
, (DatasetBean_t
*)bean
);
218 /* Create a SnapshotBean */
220 new_SnapshotBean(JNIEnv
*env
, SnapshotBean_t
*bean
)
222 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
224 if (object
->object
== NULL
) {
226 (*env
)->FindClass(env
,
227 ZFSJNI_PACKAGE_DATA
"SnapshotBean");
229 object
->constructor
=
230 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
233 (*env
)->NewObject(env
, object
->class, object
->constructor
);
236 new_DatasetBean(env
, (DatasetBean_t
*)bean
);
239 /* Create a FileSystemSnapshotBean */
241 new_FileSystemSnapshotBean(JNIEnv
*env
, FileSystemSnapshotBean_t
*bean
)
243 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
245 if (object
->object
== NULL
) {
247 (*env
)->FindClass(env
,
248 ZFSJNI_PACKAGE_DATA
"FileSystemSnapshotBean");
250 object
->constructor
=
251 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
254 (*env
)->NewObject(env
, object
->class, object
->constructor
);
257 new_SnapshotBean(env
, (SnapshotBean_t
*)bean
);
260 /* Create a VolumeSnapshotBean */
262 new_VolumeSnapshotBean(JNIEnv
*env
, VolumeSnapshotBean_t
*bean
)
264 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
266 if (object
->object
== NULL
) {
268 (*env
)->FindClass(env
,
269 ZFSJNI_PACKAGE_DATA
"VolumeSnapshotBean");
271 object
->constructor
=
272 (*env
)->GetMethodID(env
, object
->class, "<init>", "()V");
275 (*env
)->NewObject(env
, object
->class, object
->constructor
);
278 new_SnapshotBean(env
, (SnapshotBean_t
*)bean
);
282 set_name_in_DatasetBean(JNIEnv
*env
, char *name
, DatasetBean_t
*bean
)
287 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
290 * zhp->zfs_name has the format
291 * <pool>[[/<container...>]/<dataset>[@<snapshot>]]
295 regmatch_t matches
[REGEX_ZFS_NAME_NGROUPS
];
297 if (regcomp(&re
, REGEX_ZFS_NAME
, REG_EXTENDED
) != 0 ||
298 regexec(&re
, name
, REGEX_ZFS_NAME_NGROUPS
, matches
, 0) != 0) {
300 zjni_throw_exception(env
, "invalid name: %s", name
);
307 poolUTF
= zjni_get_matched_string(
308 env
, name
, matches
+ REGEX_ZFS_NAME_POOL_GROUP
);
309 parentUTF
= zjni_get_matched_string(
310 env
, name
, matches
+ REGEX_ZFS_NAME_PARENT_GROUP
);
311 baseUTF
= zjni_get_matched_string(
312 env
, name
, matches
+ REGEX_ZFS_NAME_BASE_GROUP
);
314 if (poolUTF
== NULL
) {
318 (*env
)->CallVoidMethod(
319 env
, object
->object
, bean
->method_setPoolName
, poolUTF
);
320 (*env
)->CallVoidMethod(
321 env
, object
->object
, bean
->method_setBaseName
, baseUTF
);
323 if (parentUTF
!= NULL
) {
324 (*env
)->CallVoidMethod(
325 env
, object
->object
, bean
->method_setParentName
, parentUTF
);
332 populate_DatasetBean(JNIEnv
*env
, zfs_handle_t
*zhp
, DatasetBean_t
*bean
)
334 jobjectArray properties
;
335 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
337 int result
= set_name_in_DatasetBean(
338 env
, (char *)zfs_get_name(zhp
), bean
);
340 /* Must not call any more Java methods to preserve exception */
344 properties
= zjni_get_Dataset_properties(env
, zhp
);
345 if (properties
== NULL
) {
346 /* Must not call any more Java methods to preserve exception */
350 (*env
)->CallVoidMethod(
351 env
, object
->object
, bean
->method_setProperties
, properties
);
357 populate_PoolBean(JNIEnv
*env
, zpool_handle_t
*zphp
, zfs_handle_t
*zhp
,
361 zjni_Object_t
*object
= (zjni_Object_t
*)bean
;
362 PoolStatsBean_t
*pool_stats
= &(bean
->interface_PoolStats
);
363 DeviceStatsBean_t
*dev_stats
= (DeviceStatsBean_t
*)pool_stats
;
364 nvlist_t
*devices
= zjni_get_root_vdev(zphp
);
366 if (devices
== NULL
||
367 populate_DeviceStatsBean(env
, devices
, dev_stats
, object
)) {
372 /* Override value set in populate_DeviceStatsBean */
373 (*env
)->CallVoidMethod(env
, object
->object
,
374 dev_stats
->method_setSize
,
375 zpool_get_prop_int(zphp
, ZPOOL_PROP_SIZE
, NULL
));
377 (*env
)->CallVoidMethod(env
, object
->object
,
378 pool_stats
->method_setPoolState
,
379 zjni_pool_state_to_obj(
380 env
, zpool_get_state(zphp
)));
382 (*env
)->CallVoidMethod(env
, object
->object
,
383 pool_stats
->method_setPoolStatus
,
384 zjni_pool_status_to_obj(env
,
385 zpool_get_status(zphp
, &msgid
)));
387 (*env
)->CallVoidMethod(env
, object
->object
,
388 pool_stats
->method_setPoolVersion
,
389 zpool_get_prop_int(zphp
, ZPOOL_PROP_VERSION
, NULL
));
392 * If a root file system does not exist for this pool, the pool
393 * is likely faulted, so just set its name in the Java object.
394 * Otherwise, populate all fields of the Java object.
397 result
= set_name_in_DatasetBean(env
,
398 (char *)zpool_get_name(zphp
),
399 (DatasetBean_t
*)bean
);
401 result
= populate_FileSystemBean(
402 env
, zhp
, (FileSystemBean_t
*)bean
);
406 return (result
!= 0);
410 populate_FileSystemBean(JNIEnv
*env
, zfs_handle_t
*zhp
, FileSystemBean_t
*bean
)
412 return (populate_DatasetBean(env
, zhp
, (DatasetBean_t
*)bean
));
416 populate_VolumeBean(JNIEnv
*env
, zfs_handle_t
*zhp
, VolumeBean_t
*bean
)
418 return (populate_DatasetBean(env
, zhp
, (DatasetBean_t
*)bean
));
422 populate_SnapshotBean(JNIEnv
*env
, zfs_handle_t
*zhp
, SnapshotBean_t
*bean
)
424 return (populate_DatasetBean(env
, zhp
, (DatasetBean_t
*)bean
));
428 populate_FileSystemSnapshotBean(JNIEnv
*env
, zfs_handle_t
*zhp
,
429 FileSystemSnapshotBean_t
*bean
)
431 return (populate_SnapshotBean(env
, zhp
, (SnapshotBean_t
*)bean
));
435 populate_VolumeSnapshotBean(JNIEnv
*env
, zfs_handle_t
*zhp
,
436 VolumeSnapshotBean_t
*bean
)
438 return (populate_SnapshotBean(env
, zhp
, (SnapshotBean_t
*)bean
));
442 create_PoolBean(JNIEnv
*env
, zpool_handle_t
*zphp
, zfs_handle_t
*zhp
)
445 PoolBean_t bean_obj
= {0};
446 PoolBean_t
*bean
= &bean_obj
;
448 /* Construct PoolBean */
449 new_PoolBean(env
, bean
);
451 result
= populate_PoolBean(env
, zphp
, zhp
, bean
);
453 /* Must not call any more Java methods to preserve exception */
457 return (((zjni_Object_t
*)bean
)->object
);
461 create_FileSystemBean(JNIEnv
*env
, zfs_handle_t
*zhp
)
464 FileSystemBean_t bean_obj
= {0};
465 FileSystemBean_t
*bean
= &bean_obj
;
467 /* Construct FileSystemBean */
468 new_FileSystemBean(env
, bean
);
470 result
= populate_FileSystemBean(env
, zhp
, bean
);
472 /* Must not call any more Java methods to preserve exception */
476 return (((zjni_Object_t
*)bean
)->object
);
480 create_VolumeBean(JNIEnv
*env
, zfs_handle_t
*zhp
)
483 VolumeBean_t bean_obj
= {0};
484 VolumeBean_t
*bean
= &bean_obj
;
486 /* Construct VolumeBean */
487 new_VolumeBean(env
, bean
);
489 result
= populate_VolumeBean(env
, zhp
, bean
);
491 /* Must not call any more Java methods to preserve exception */
495 return (((zjni_Object_t
*)bean
)->object
);
499 create_FileSystemSnapshotBean(JNIEnv
*env
, zfs_handle_t
*zhp
)
502 FileSystemSnapshotBean_t bean_obj
= {0};
503 FileSystemSnapshotBean_t
*bean
= &bean_obj
;
505 /* Construct FileSystemSnapshotBean */
506 new_FileSystemSnapshotBean(env
, bean
);
508 result
= populate_FileSystemSnapshotBean(env
, zhp
, bean
);
510 /* Must not call any more Java methods to preserve exception */
514 return (((zjni_Object_t
*)bean
)->object
);
518 create_VolumeSnapshotBean(JNIEnv
*env
, zfs_handle_t
*zhp
)
521 VolumeSnapshotBean_t bean_obj
= {0};
522 VolumeSnapshotBean_t
*bean
= &bean_obj
;
524 /* Construct VolumeSnapshotBean */
525 new_VolumeSnapshotBean(env
, bean
);
527 result
= populate_VolumeSnapshotBean(env
, zhp
, bean
);
529 /* Must not call any more Java methods to preserve exception */
533 return (((zjni_Object_t
*)bean
)->object
);
537 create_DatasetBean(JNIEnv
*env
, zfs_handle_t
*zhp
)
539 jobject object
= NULL
;
541 switch (zfs_get_type(zhp
)) {
542 case ZFS_TYPE_FILESYSTEM
:
543 object
= create_FileSystemBean(env
, zhp
);
546 case ZFS_TYPE_VOLUME
:
547 object
= create_VolumeBean(env
, zhp
);
550 case ZFS_TYPE_SNAPSHOT
:
551 object
= is_fs_snapshot(zhp
) ?
552 create_FileSystemSnapshotBean(env
, zhp
) :
553 create_VolumeSnapshotBean(env
, zhp
);
561 * Determines whether the given snapshot is a snapshot of a file
562 * system or of a volume.
566 * 0 if it is a volume snapshot
567 * 1 if it is a file system snapshot
571 is_fs_snapshot(zfs_handle_t
*zhp
)
573 char parent
[ZFS_MAX_DATASET_NAME_LEN
];
574 zfs_handle_t
*parent_zhp
;
577 if (zfs_get_type(zhp
) != ZFS_TYPE_SNAPSHOT
) {
581 zjni_get_dataset_from_snapshot(
582 zfs_get_name(zhp
), parent
, sizeof (parent
));
584 parent_zhp
= zfs_open(g_zfs
, parent
, ZFS_TYPE_DATASET
);
585 if (parent_zhp
== NULL
) {
589 isfs
= zfs_get_type(parent_zhp
) == ZFS_TYPE_FILESYSTEM
;
590 zfs_close(parent_zhp
);
596 is_pool_name(const char *name
)
598 return (strchr(name
, '/') == NULL
&& strchr(name
, '@') == NULL
);
602 * Package-private functions
606 * Callback function for zpool_iter(). Creates a Pool and adds it to
607 * the given zjni_ArrayList.
610 zjni_create_add_Pool(zpool_handle_t
*zphp
, void *data
)
612 JNIEnv
*env
= ((zjni_ArrayCallbackData_t
*)data
)->env
;
613 zjni_Collection_t
*list
= ((zjni_ArrayCallbackData_t
*)data
)->list
;
615 /* Get root fs for this pool -- may be NULL if pool is faulted */
616 zfs_handle_t
*zhp
= zfs_open(g_zfs
, zpool_get_name(zphp
),
617 ZFS_TYPE_FILESYSTEM
);
619 jobject bean
= create_PoolBean(env
, zphp
, zhp
);
627 /* Must not call any more Java methods to preserve exception */
631 /* Add pool to zjni_ArrayList */
632 (*env
)->CallBooleanMethod(env
, ((zjni_Object_t
*)list
)->object
,
633 ((zjni_Collection_t
*)list
)->method_add
, bean
);
639 * Callback function for zfs_iter_children(). Creates the appropriate
640 * Dataset and adds it to the given zjni_ArrayList. Per the contract
641 * with zfs_iter_children(), calls zfs_close() on the given
645 zjni_create_add_Dataset(zfs_handle_t
*zhp
, void *data
)
647 JNIEnv
*env
= ((zjni_ArrayCallbackData_t
*)data
)->env
;
648 zjni_Collection_t
*list
= ((zjni_ArrayCallbackData_t
*)data
)->list
;
649 zfs_type_t typemask
=
650 ((zjni_DatasetArrayCallbackData_t
*)data
)->typemask
;
652 /* Only add allowed types */
653 if (zfs_get_type(zhp
) & typemask
) {
655 jobject bean
= create_DatasetBean(env
, zhp
);
660 * Must not call any more Java methods to preserve
666 /* Add Dataset to zjni_ArrayList */
667 (*env
)->CallBooleanMethod(env
, ((zjni_Object_t
*)list
)->object
,
668 ((zjni_Collection_t
*)list
)->method_add
, bean
);
677 zjni_get_Datasets_below(JNIEnv
*env
, jstring parentUTF
,
678 zfs_type_t parent_typemask
, zfs_type_t child_typemask
, char *arrayClass
)
680 jobjectArray array
= NULL
;
682 if (parentUTF
!= NULL
) {
686 (*env
)->GetStringUTFChars(env
, parentUTF
, NULL
);
688 /* Create an array list to hold the children */
689 zjni_DatasetSet_t list_obj
= {0};
690 zjni_DatasetSet_t
*list
= &list_obj
;
691 zjni_new_DatasetSet(env
, list
);
693 /* Retrieve parent dataset */
694 zhp
= zfs_open(g_zfs
, name
, parent_typemask
);
697 zjni_DatasetArrayCallbackData_t data
= {0};
699 data
.data
.list
= (zjni_Collection_t
*)list
;
700 data
.typemask
= child_typemask
;
702 (void) zfs_iter_children(zhp
, zjni_create_add_Dataset
,
707 if ((*env
)->ExceptionOccurred(env
) == NULL
) {
712 /* Parent is not a dataset -- see if it's a faulted pool */
713 if ((parent_typemask
& ZFS_TYPE_FILESYSTEM
) &&
714 is_pool_name(name
)) {
715 zpool_handle_t
*zphp
= zpool_open_canfail(g_zfs
, name
);
718 /* A faulted pool has no datasets */
724 (*env
)->ReleaseStringUTFChars(env
, parentUTF
, name
);
727 array
= zjni_Collection_to_array(
728 env
, (zjni_Collection_t
*)list
, arrayClass
);
736 zjni_get_Datasets_dependents(JNIEnv
*env
, jobjectArray paths
)
740 zjni_DatasetArrayCallbackData_t data
= {0};
741 jobjectArray array
= NULL
;
743 /* Create a list to hold the children */
744 zjni_DatasetSet_t list_obj
= {0};
745 zjni_DatasetSet_t
*list
= &list_obj
;
746 zjni_new_DatasetSet(env
, list
);
749 data
.data
.list
= (zjni_Collection_t
*)list
;
750 data
.typemask
= ZFS_TYPE_DATASET
;
752 npaths
= (*env
)->GetArrayLength(env
, paths
);
753 for (i
= 0; i
< npaths
; i
++) {
755 jstring pathUTF
= (jstring
)
756 ((*env
)->GetObjectArrayElement(env
, paths
, i
));
758 if (pathUTF
!= NULL
) {
760 (*env
)->GetStringUTFChars(env
, pathUTF
, NULL
);
762 zfs_handle_t
*zhp
= zfs_open(g_zfs
, path
,
765 /* Add all dependents of this Dataset to list */
766 (void) zfs_iter_dependents(zhp
, B_FALSE
,
767 zjni_create_add_Dataset
, &data
);
769 /* Add this Dataset to list (and close zhp) */
770 (void) zjni_create_add_Dataset(zhp
, &data
);
771 } else if (is_pool_name(path
)) {
773 * Path is not a dataset -
774 * see if it's a faulted pool
776 zpool_handle_t
*zphp
= zpool_open_canfail(g_zfs
,
781 * Add this Pool to list (and
784 (void) zjni_create_add_Pool(zphp
,
789 (*env
)->ReleaseStringUTFChars(env
, pathUTF
, path
);
793 if ((*env
)->ExceptionOccurred(env
) == NULL
) {
794 array
= zjni_Collection_to_array(env
, (zjni_Collection_t
*)list
,
795 ZFSJNI_PACKAGE_DATA
"Dataset");
802 * Gets a Dataset of the given name and type, or NULL if no such
806 zjni_get_Dataset(JNIEnv
*env
, jstring nameUTF
, zfs_type_t typemask
)
808 jobject device
= NULL
;
809 const char *name
= (*env
)->GetStringUTFChars(env
, nameUTF
, NULL
);
810 zfs_handle_t
*zhp
= zfs_open(g_zfs
, name
, typemask
);
812 if ((typemask
& ZFS_TYPE_FILESYSTEM
) && is_pool_name(name
)) {
813 zpool_handle_t
*zphp
= zpool_open_canfail(g_zfs
, name
);
816 device
= create_PoolBean(env
, zphp
, zhp
);
819 } else if (zhp
!= NULL
) {
820 /* Creates a Dataset object of the appropriate class */
821 device
= create_DatasetBean(env
, zhp
);
828 (*env
)->ReleaseStringUTFChars(env
, nameUTF
, name
);