8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libzfs_jni / common / libzfs_jni_dataset.c
blob2aa11ba23bf4772f4e0650a64d8a8e4ccb056e2c
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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"
35 #include <strings.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
44 * Types
47 typedef struct DatasetBean {
48 zjni_Object_t super;
50 jmethodID method_setPoolName;
51 jmethodID method_setParentName;
52 jmethodID method_setBaseName;
53 jmethodID method_setProperties;
54 jmethodID method_addProperty;
55 } DatasetBean_t;
57 typedef struct FileSystemBean {
58 DatasetBean_t super;
59 } FileSystemBean_t;
61 typedef struct PoolBean {
62 FileSystemBean_t super;
63 PoolStatsBean_t interface_PoolStats;
64 } PoolBean_t;
66 typedef struct VolumeBean {
67 DatasetBean_t super;
68 } VolumeBean_t;
70 typedef struct SnapshotBean {
71 DatasetBean_t super;
72 } SnapshotBean_t;
74 typedef struct FileSystemSnapshotBean {
75 DatasetBean_t super;
76 } FileSystemSnapshotBean_t;
78 typedef struct VolumeSnapshotBean {
79 DatasetBean_t super;
80 } VolumeSnapshotBean_t;
83 * Function prototypes
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 *);
116 * Static functions
119 /* Create a DatasetBean */
120 static void
121 new_DatasetBean(JNIEnv *env, DatasetBean_t *bean)
123 zjni_Object_t *object = (zjni_Object_t *)bean;
125 if (object->object == NULL) {
126 object->class =
127 (*env)->FindClass(env, ZFSJNI_PACKAGE_DATA "DatasetBean");
129 object->constructor =
130 (*env)->GetMethodID(env, object->class, "<init>", "()V");
132 object->object =
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 */
155 static void
156 new_PoolBean(JNIEnv *env, PoolBean_t *bean)
158 zjni_Object_t *object = (zjni_Object_t *)bean;
160 if (object->object == NULL) {
162 object->class =
163 (*env)->FindClass(env, ZFSJNI_PACKAGE_DATA "PoolBean");
165 object->constructor =
166 (*env)->GetMethodID(env, object->class, "<init>", "()V");
168 object->object =
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 */
177 static void
178 new_FileSystemBean(JNIEnv *env, FileSystemBean_t *bean)
180 zjni_Object_t *object = (zjni_Object_t *)bean;
182 if (object->object == NULL) {
183 object->class =
184 (*env)->FindClass(env,
185 ZFSJNI_PACKAGE_DATA "FileSystemBean");
187 object->constructor =
188 (*env)->GetMethodID(env, object->class, "<init>", "()V");
190 object->object =
191 (*env)->NewObject(env, object->class, object->constructor);
194 new_DatasetBean(env, (DatasetBean_t *)bean);
197 /* Create a VolumeBean */
198 static void
199 new_VolumeBean(JNIEnv *env, VolumeBean_t *bean)
201 zjni_Object_t *object = (zjni_Object_t *)bean;
203 if (object->object == NULL) {
204 object->class =
205 (*env)->FindClass(env,
206 ZFSJNI_PACKAGE_DATA "VolumeBean");
208 object->constructor =
209 (*env)->GetMethodID(env, object->class, "<init>", "()V");
211 object->object =
212 (*env)->NewObject(env, object->class, object->constructor);
215 new_DatasetBean(env, (DatasetBean_t *)bean);
218 /* Create a SnapshotBean */
219 static void
220 new_SnapshotBean(JNIEnv *env, SnapshotBean_t *bean)
222 zjni_Object_t *object = (zjni_Object_t *)bean;
224 if (object->object == NULL) {
225 object->class =
226 (*env)->FindClass(env,
227 ZFSJNI_PACKAGE_DATA "SnapshotBean");
229 object->constructor =
230 (*env)->GetMethodID(env, object->class, "<init>", "()V");
232 object->object =
233 (*env)->NewObject(env, object->class, object->constructor);
236 new_DatasetBean(env, (DatasetBean_t *)bean);
239 /* Create a FileSystemSnapshotBean */
240 static void
241 new_FileSystemSnapshotBean(JNIEnv *env, FileSystemSnapshotBean_t *bean)
243 zjni_Object_t *object = (zjni_Object_t *)bean;
245 if (object->object == NULL) {
246 object->class =
247 (*env)->FindClass(env,
248 ZFSJNI_PACKAGE_DATA "FileSystemSnapshotBean");
250 object->constructor =
251 (*env)->GetMethodID(env, object->class, "<init>", "()V");
253 object->object =
254 (*env)->NewObject(env, object->class, object->constructor);
257 new_SnapshotBean(env, (SnapshotBean_t *)bean);
260 /* Create a VolumeSnapshotBean */
261 static void
262 new_VolumeSnapshotBean(JNIEnv *env, VolumeSnapshotBean_t *bean)
264 zjni_Object_t *object = (zjni_Object_t *)bean;
266 if (object->object == NULL) {
267 object->class =
268 (*env)->FindClass(env,
269 ZFSJNI_PACKAGE_DATA "VolumeSnapshotBean");
271 object->constructor =
272 (*env)->GetMethodID(env, object->class, "<init>", "()V");
274 object->object =
275 (*env)->NewObject(env, object->class, object->constructor);
278 new_SnapshotBean(env, (SnapshotBean_t *)bean);
281 static int
282 set_name_in_DatasetBean(JNIEnv *env, char *name, DatasetBean_t *bean)
284 jstring poolUTF;
285 jstring parentUTF;
286 jstring baseUTF;
287 zjni_Object_t *object = (zjni_Object_t *)bean;
290 * zhp->zfs_name has the format
291 * <pool>[[/<container...>]/<dataset>[@<snapshot>]]
294 regex_t re;
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) {
299 regfree(&re);
300 zjni_throw_exception(env, "invalid name: %s", name);
301 return (-1);
304 regfree(&re);
306 /* Set names */
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) {
315 poolUTF = baseUTF;
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);
328 return (0);
331 static int
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);
339 if (result != 0) {
340 /* Must not call any more Java methods to preserve exception */
341 return (-1);
344 properties = zjni_get_Dataset_properties(env, zhp);
345 if (properties == NULL) {
346 /* Must not call any more Java methods to preserve exception */
347 return (-1);
350 (*env)->CallVoidMethod(
351 env, object->object, bean->method_setProperties, properties);
353 return (0);
356 static int
357 populate_PoolBean(JNIEnv *env, zpool_handle_t *zphp, zfs_handle_t *zhp,
358 PoolBean_t *bean)
360 int result = 0;
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)) {
368 result = -1;
369 } else {
370 char *msgid;
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.
396 if (zhp == NULL) {
397 result = set_name_in_DatasetBean(env,
398 (char *)zpool_get_name(zphp),
399 (DatasetBean_t *)bean);
400 } else {
401 result = populate_FileSystemBean(
402 env, zhp, (FileSystemBean_t *)bean);
406 return (result != 0);
409 static int
410 populate_FileSystemBean(JNIEnv *env, zfs_handle_t *zhp, FileSystemBean_t *bean)
412 return (populate_DatasetBean(env, zhp, (DatasetBean_t *)bean));
415 static int
416 populate_VolumeBean(JNIEnv *env, zfs_handle_t *zhp, VolumeBean_t *bean)
418 return (populate_DatasetBean(env, zhp, (DatasetBean_t *)bean));
421 static int
422 populate_SnapshotBean(JNIEnv *env, zfs_handle_t *zhp, SnapshotBean_t *bean)
424 return (populate_DatasetBean(env, zhp, (DatasetBean_t *)bean));
427 static int
428 populate_FileSystemSnapshotBean(JNIEnv *env, zfs_handle_t *zhp,
429 FileSystemSnapshotBean_t *bean)
431 return (populate_SnapshotBean(env, zhp, (SnapshotBean_t *)bean));
434 static int
435 populate_VolumeSnapshotBean(JNIEnv *env, zfs_handle_t *zhp,
436 VolumeSnapshotBean_t *bean)
438 return (populate_SnapshotBean(env, zhp, (SnapshotBean_t *)bean));
441 static jobject
442 create_PoolBean(JNIEnv *env, zpool_handle_t *zphp, zfs_handle_t *zhp)
444 int result;
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);
452 if (result) {
453 /* Must not call any more Java methods to preserve exception */
454 return (NULL);
457 return (((zjni_Object_t *)bean)->object);
460 static jobject
461 create_FileSystemBean(JNIEnv *env, zfs_handle_t *zhp)
463 int result;
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);
471 if (result) {
472 /* Must not call any more Java methods to preserve exception */
473 return (NULL);
476 return (((zjni_Object_t *)bean)->object);
479 static jobject
480 create_VolumeBean(JNIEnv *env, zfs_handle_t *zhp)
482 int result;
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);
490 if (result) {
491 /* Must not call any more Java methods to preserve exception */
492 return (NULL);
495 return (((zjni_Object_t *)bean)->object);
498 static jobject
499 create_FileSystemSnapshotBean(JNIEnv *env, zfs_handle_t *zhp)
501 int result;
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);
509 if (result) {
510 /* Must not call any more Java methods to preserve exception */
511 return (NULL);
514 return (((zjni_Object_t *)bean)->object);
517 static jobject
518 create_VolumeSnapshotBean(JNIEnv *env, zfs_handle_t *zhp)
520 int result;
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);
528 if (result) {
529 /* Must not call any more Java methods to preserve exception */
530 return (NULL);
533 return (((zjni_Object_t *)bean)->object);
536 static jobject
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);
544 break;
546 case ZFS_TYPE_VOLUME:
547 object = create_VolumeBean(env, zhp);
548 break;
550 case ZFS_TYPE_SNAPSHOT:
551 object = is_fs_snapshot(zhp) ?
552 create_FileSystemSnapshotBean(env, zhp) :
553 create_VolumeSnapshotBean(env, zhp);
554 break;
557 return (object);
561 * Determines whether the given snapshot is a snapshot of a file
562 * system or of a volume.
564 * Returns:
566 * 0 if it is a volume snapshot
567 * 1 if it is a file system snapshot
568 * -1 on error
570 static int
571 is_fs_snapshot(zfs_handle_t *zhp)
573 char parent[ZFS_MAX_DATASET_NAME_LEN];
574 zfs_handle_t *parent_zhp;
575 int isfs;
577 if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) {
578 return (-1);
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) {
586 return (-1);
589 isfs = zfs_get_type(parent_zhp) == ZFS_TYPE_FILESYSTEM;
590 zfs_close(parent_zhp);
592 return (isfs);
595 static int
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);
621 if (zhp != NULL)
622 zfs_close(zhp);
624 zpool_close(zphp);
626 if (bean == NULL) {
627 /* Must not call any more Java methods to preserve exception */
628 return (-1);
631 /* Add pool to zjni_ArrayList */
632 (*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
633 ((zjni_Collection_t *)list)->method_add, bean);
635 return (0);
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
642 * zfs_handle_t.
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);
656 zfs_close(zhp);
658 if (bean == NULL) {
660 * Must not call any more Java methods to preserve
661 * exception
663 return (-1);
666 /* Add Dataset to zjni_ArrayList */
667 (*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
668 ((zjni_Collection_t *)list)->method_add, bean);
669 } else {
670 zfs_close(zhp);
673 return (0);
676 jobjectArray
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) {
683 zfs_handle_t *zhp;
684 int error = 1;
685 const char *name =
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);
696 if (zhp != NULL) {
697 zjni_DatasetArrayCallbackData_t data = {0};
698 data.data.env = env;
699 data.data.list = (zjni_Collection_t *)list;
700 data.typemask = child_typemask;
702 (void) zfs_iter_children(zhp, zjni_create_add_Dataset,
703 &data);
705 zfs_close(zhp);
707 if ((*env)->ExceptionOccurred(env) == NULL) {
708 error = 0;
710 } else
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);
717 if (zphp != NULL) {
718 /* A faulted pool has no datasets */
719 error = 0;
720 zpool_close(zphp);
724 (*env)->ReleaseStringUTFChars(env, parentUTF, name);
726 if (!error) {
727 array = zjni_Collection_to_array(
728 env, (zjni_Collection_t *)list, arrayClass);
732 return (array);
735 jobjectArray
736 zjni_get_Datasets_dependents(JNIEnv *env, jobjectArray paths)
738 jint i;
739 jint npaths;
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);
748 data.data.env = env;
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) {
759 const char *path =
760 (*env)->GetStringUTFChars(env, pathUTF, NULL);
762 zfs_handle_t *zhp = zfs_open(g_zfs, path,
763 ZFS_TYPE_DATASET);
764 if (zhp != NULL) {
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,
777 path);
779 if (zphp != NULL) {
781 * Add this Pool to list (and
782 * close zphp)
784 (void) zjni_create_add_Pool(zphp,
785 &data.data);
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");
798 return (array);
802 * Gets a Dataset of the given name and type, or NULL if no such
803 * Dataset exists.
805 jobject
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);
815 if (zphp != NULL) {
816 device = create_PoolBean(env, zphp, zhp);
817 zpool_close(zphp);
819 } else if (zhp != NULL) {
820 /* Creates a Dataset object of the appropriate class */
821 device = create_DatasetBean(env, zhp);
824 if (zhp != NULL) {
825 zfs_close(zhp);
828 (*env)->ReleaseStringUTFChars(env, nameUTF, name);
830 return (device);