1fa9e4066Sahrens /*
2fa9e4066Sahrens  * CDDL HEADER START
3fa9e4066Sahrens  *
4fa9e4066Sahrens  * The contents of this file are subject to the terms of the
532f884e0Stalley  * Common Development and Distribution License (the "License").
632f884e0Stalley  * You may not use this file except in compliance with the License.
7fa9e4066Sahrens  *
8fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
10fa9e4066Sahrens  * See the License for the specific language governing permissions
11fa9e4066Sahrens  * and limitations under the License.
12fa9e4066Sahrens  *
13fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18fa9e4066Sahrens  *
19fa9e4066Sahrens  * CDDL HEADER END
20fa9e4066Sahrens  */
2132f884e0Stalley 
22fa9e4066Sahrens /*
23990b4856Slling  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24fa9e4066Sahrens  * Use is subject to license terms.
25fa9e4066Sahrens  */
26fa9e4066Sahrens 
279adfa60dSMatthew Ahrens /*
289adfa60dSMatthew Ahrens  * Copyright (c) 2015 by Delphix. All rights reserved.
299adfa60dSMatthew Ahrens  */
30fa9e4066Sahrens 
31fbfd10ffStalley #include "libzfs_jni_util.h"
32fa9e4066Sahrens #include "libzfs_jni_dataset.h"
33fa9e4066Sahrens #include "libzfs_jni_property.h"
34fbfd10ffStalley #include "libzfs_jni_pool.h"
35fa9e4066Sahrens #include <strings.h>
36fa9e4066Sahrens 
37fa9e4066Sahrens #define	REGEX_ZFS_NAME "^((([^/]*)(/.+)?)[/@])?([^/]+)/*"
38fa9e4066Sahrens #define	REGEX_ZFS_NAME_NGROUPS	6
39fa9e4066Sahrens #define	REGEX_ZFS_NAME_POOL_GROUP 3
40fa9e4066Sahrens #define	REGEX_ZFS_NAME_PARENT_GROUP 2
41fa9e4066Sahrens #define	REGEX_ZFS_NAME_BASE_GROUP 5
42fa9e4066Sahrens 
43fa9e4066Sahrens /*
44fa9e4066Sahrens  * Types
45fa9e4066Sahrens  */
46fa9e4066Sahrens 
47fa9e4066Sahrens typedef struct DatasetBean {
48fa9e4066Sahrens 	zjni_Object_t super;
49fa9e4066Sahrens 
50fa9e4066Sahrens 	jmethodID method_setPoolName;
51fa9e4066Sahrens 	jmethodID method_setParentName;
52fa9e4066Sahrens 	jmethodID method_setBaseName;
53fa9e4066Sahrens 	jmethodID method_setProperties;
54fa9e4066Sahrens 	jmethodID method_addProperty;
55fa9e4066Sahrens } DatasetBean_t;
56fa9e4066Sahrens 
57fa9e4066Sahrens typedef struct FileSystemBean {
58fa9e4066Sahrens 	DatasetBean_t super;
59fa9e4066Sahrens } FileSystemBean_t;
60fa9e4066Sahrens 
61fa9e4066Sahrens typedef struct PoolBean {
62fa9e4066Sahrens 	FileSystemBean_t super;
63fbfd10ffStalley 	PoolStatsBean_t interface_PoolStats;
64fa9e4066Sahrens } PoolBean_t;
65fa9e4066Sahrens 
66fa9e4066Sahrens typedef struct VolumeBean {
67fa9e4066Sahrens 	DatasetBean_t super;
68fa9e4066Sahrens } VolumeBean_t;
69fa9e4066Sahrens 
70fa9e4066Sahrens typedef struct SnapshotBean {
71fa9e4066Sahrens 	DatasetBean_t super;
72fa9e4066Sahrens } SnapshotBean_t;
73fa9e4066Sahrens 
74fa9e4066Sahrens typedef struct FileSystemSnapshotBean {
75fa9e4066Sahrens 	DatasetBean_t super;
76fa9e4066Sahrens } FileSystemSnapshotBean_t;
77fa9e4066Sahrens 
78fa9e4066Sahrens typedef struct VolumeSnapshotBean {
79fa9e4066Sahrens 	DatasetBean_t super;
80fa9e4066Sahrens } VolumeSnapshotBean_t;
81fa9e4066Sahrens 
82fa9e4066Sahrens /*
83fa9e4066Sahrens  * Function prototypes
84fa9e4066Sahrens  */
85fa9e4066Sahrens 
86fa9e4066Sahrens static void new_DatasetBean(JNIEnv *, DatasetBean_t *);
87fa9e4066Sahrens static void new_PoolBean(JNIEnv *, PoolBean_t *);
88fa9e4066Sahrens static void new_FileSystemBean(JNIEnv *, FileSystemBean_t *);
89fa9e4066Sahrens static void new_VolumeBean(JNIEnv *, VolumeBean_t *);
90fa9e4066Sahrens static void new_SnapshotBean(JNIEnv *, SnapshotBean_t *);
91fa9e4066Sahrens static void new_FileSystemSnapshotBean(JNIEnv *, FileSystemSnapshotBean_t *);
92fa9e4066Sahrens static void new_VolumeSnapshotBean(JNIEnv *, VolumeSnapshotBean_t *);
9332f884e0Stalley static int set_name_in_DatasetBean(JNIEnv *, char *, DatasetBean_t *);
94fa9e4066Sahrens static int populate_DatasetBean(JNIEnv *, zfs_handle_t *, DatasetBean_t *);
9532f884e0Stalley static int populate_PoolBean(
9632f884e0Stalley     JNIEnv *, zpool_handle_t *, zfs_handle_t *, PoolBean_t *);
97fa9e4066Sahrens static int populate_FileSystemBean(
98fa9e4066Sahrens     JNIEnv *, zfs_handle_t *, FileSystemBean_t *);
99fa9e4066Sahrens static int populate_VolumeBean(
100fa9e4066Sahrens     JNIEnv *, zfs_handle_t *, VolumeBean_t *);
101fa9e4066Sahrens static int populate_SnapshotBean(JNIEnv *, zfs_handle_t *, SnapshotBean_t *);
102fa9e4066Sahrens static int populate_FileSystemSnapshotBean(
103fa9e4066Sahrens     JNIEnv *, zfs_handle_t *, FileSystemSnapshotBean_t *);
104fa9e4066Sahrens static int populate_VolumeSnapshotBean(
105fa9e4066Sahrens     JNIEnv *, zfs_handle_t *, VolumeSnapshotBean_t *);
10632f884e0Stalley static jobject create_PoolBean(JNIEnv *, zpool_handle_t *, zfs_handle_t *);
107fa9e4066Sahrens static jobject create_FileSystemBean(JNIEnv *, zfs_handle_t *);
108fa9e4066Sahrens static jobject create_VolumeBean(JNIEnv *, zfs_handle_t *);
109fa9e4066Sahrens static jobject create_FileSystemSnapshotBean(JNIEnv *, zfs_handle_t *);
110fa9e4066Sahrens static jobject create_VolumeSnapshotBean(JNIEnv *, zfs_handle_t *);
111fa9e4066Sahrens static jobject create_DatasetBean(JNIEnv *, zfs_handle_t *);
112fa9e4066Sahrens static int is_fs_snapshot(zfs_handle_t *);
11332f884e0Stalley static int is_pool_name(const char *);
114fa9e4066Sahrens 
115fa9e4066Sahrens /*
116fa9e4066Sahrens  * Static functions
117fa9e4066Sahrens  */
118fa9e4066Sahrens 
119fa9e4066Sahrens /* Create a DatasetBean */
120fa9e4066Sahrens static void
new_DatasetBean(JNIEnv * env,DatasetBean_t * bean)121fa9e4066Sahrens new_DatasetBean(JNIEnv *env, DatasetBean_t *bean)
122fa9e4066Sahrens {
123fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
124fa9e4066Sahrens 
125fa9e4066Sahrens 	if (object->object == NULL) {
126fa9e4066Sahrens 		object->class =
127fa9e4066Sahrens 		    (*env)->FindClass(env, ZFSJNI_PACKAGE_DATA "DatasetBean");
128fa9e4066Sahrens 
129fa9e4066Sahrens 		object->constructor =
130fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
131fa9e4066Sahrens 
132fa9e4066Sahrens 		object->object =
133fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
134fa9e4066Sahrens 	}
135fa9e4066Sahrens 
136fa9e4066Sahrens 	bean->method_setPoolName = (*env)->GetMethodID(
137fa9e4066Sahrens 	    env, object->class, "setPoolName", "(Ljava/lang/String;)V");
138fa9e4066Sahrens 
139fa9e4066Sahrens 	bean->method_setParentName = (*env)->GetMethodID(
140fa9e4066Sahrens 	    env, object->class, "setParentName", "(Ljava/lang/String;)V");
141fa9e4066Sahrens 
142fa9e4066Sahrens 	bean->method_setBaseName = (*env)->GetMethodID(
143fa9e4066Sahrens 	    env, object->class, "setBaseName", "(Ljava/lang/String;)V");
144fa9e4066Sahrens 
145fa9e4066Sahrens 	bean->method_setProperties = (*env)->GetMethodID(
146fa9e4066Sahrens 	    env, object->class, "setProperties",
147fa9e4066Sahrens 	    "([L" ZFSJNI_PACKAGE_DATA "Property;)V");
148fa9e4066Sahrens 
149fa9e4066Sahrens 	bean->method_addProperty = (*env)->GetMethodID(
150fa9e4066Sahrens 	    env, object->class, "addProperty",
151fa9e4066Sahrens 	    "(L" ZFSJNI_PACKAGE_DATA "Property;)V");
152fa9e4066Sahrens }
153fa9e4066Sahrens 
154fa9e4066Sahrens /* Create a PoolBean */
155fa9e4066Sahrens static void
new_PoolBean(JNIEnv * env,PoolBean_t * bean)156fa9e4066Sahrens new_PoolBean(JNIEnv *env, PoolBean_t *bean)
157fa9e4066Sahrens {
158fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
159fa9e4066Sahrens 
160fa9e4066Sahrens 	if (object->object == NULL) {
161fa9e4066Sahrens 
162fa9e4066Sahrens 		object->class =
163fa9e4066Sahrens 		    (*env)->FindClass(env, ZFSJNI_PACKAGE_DATA "PoolBean");
164fa9e4066Sahrens 
165fa9e4066Sahrens 		object->constructor =
166fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
167fa9e4066Sahrens 
168fa9e4066Sahrens 		object->object =
169fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
170fa9e4066Sahrens 	}
171fa9e4066Sahrens 
172fa9e4066Sahrens 	new_FileSystemBean(env, (FileSystemBean_t *)bean);
173fbfd10ffStalley 	new_PoolStats(env, &(bean->interface_PoolStats), object);
174fa9e4066Sahrens }
175fa9e4066Sahrens 
176fa9e4066Sahrens /* Create a FileSystemBean */
177fa9e4066Sahrens static void
new_FileSystemBean(JNIEnv * env,FileSystemBean_t * bean)178fa9e4066Sahrens new_FileSystemBean(JNIEnv *env, FileSystemBean_t *bean)
179fa9e4066Sahrens {
180fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
181fa9e4066Sahrens 
182fa9e4066Sahrens 	if (object->object == NULL) {
183fa9e4066Sahrens 		object->class =
184fa9e4066Sahrens 		    (*env)->FindClass(env,
185990b4856Slling 		    ZFSJNI_PACKAGE_DATA "FileSystemBean");
186fa9e4066Sahrens 
187fa9e4066Sahrens 		object->constructor =
188fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
189fa9e4066Sahrens 
190fa9e4066Sahrens 		object->object =
191fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
192fa9e4066Sahrens 	}
193fa9e4066Sahrens 
194fa9e4066Sahrens 	new_DatasetBean(env, (DatasetBean_t *)bean);
195fa9e4066Sahrens }
196fa9e4066Sahrens 
197fa9e4066Sahrens /* Create a VolumeBean */
198fa9e4066Sahrens static void
new_VolumeBean(JNIEnv * env,VolumeBean_t * bean)199fa9e4066Sahrens new_VolumeBean(JNIEnv *env, VolumeBean_t *bean)
200fa9e4066Sahrens {
201fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
202fa9e4066Sahrens 
203fa9e4066Sahrens 	if (object->object == NULL) {
204fa9e4066Sahrens 		object->class =
205fa9e4066Sahrens 		    (*env)->FindClass(env,
206990b4856Slling 		    ZFSJNI_PACKAGE_DATA "VolumeBean");
207fa9e4066Sahrens 
208fa9e4066Sahrens 		object->constructor =
209fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
210fa9e4066Sahrens 
211fa9e4066Sahrens 		object->object =
212fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
213fa9e4066Sahrens 	}
214fa9e4066Sahrens 
215fa9e4066Sahrens 	new_DatasetBean(env, (DatasetBean_t *)bean);
216fa9e4066Sahrens }
217fa9e4066Sahrens 
218fa9e4066Sahrens /* Create a SnapshotBean */
219fa9e4066Sahrens static void
new_SnapshotBean(JNIEnv * env,SnapshotBean_t * bean)220fa9e4066Sahrens new_SnapshotBean(JNIEnv *env, SnapshotBean_t *bean)
221fa9e4066Sahrens {
222fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
223fa9e4066Sahrens 
224fa9e4066Sahrens 	if (object->object == NULL) {
225fa9e4066Sahrens 		object->class =
226fa9e4066Sahrens 		    (*env)->FindClass(env,
227990b4856Slling 		    ZFSJNI_PACKAGE_DATA "SnapshotBean");
228fa9e4066Sahrens 
229fa9e4066Sahrens 		object->constructor =
230fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
231fa9e4066Sahrens 
232fa9e4066Sahrens 		object->object =
233fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
234fa9e4066Sahrens 	}
235fa9e4066Sahrens 
236fa9e4066Sahrens 	new_DatasetBean(env, (DatasetBean_t *)bean);
237fa9e4066Sahrens }
238fa9e4066Sahrens 
239fa9e4066Sahrens /* Create a FileSystemSnapshotBean */
240fa9e4066Sahrens static void
new_FileSystemSnapshotBean(JNIEnv * env,FileSystemSnapshotBean_t * bean)241fa9e4066Sahrens new_FileSystemSnapshotBean(JNIEnv *env, FileSystemSnapshotBean_t *bean)
242fa9e4066Sahrens {
243fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
244fa9e4066Sahrens 
245fa9e4066Sahrens 	if (object->object == NULL) {
246fa9e4066Sahrens 		object->class =
247fa9e4066Sahrens 		    (*env)->FindClass(env,
248990b4856Slling 		    ZFSJNI_PACKAGE_DATA "FileSystemSnapshotBean");
249fa9e4066Sahrens 
250fa9e4066Sahrens 		object->constructor =
251fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
252fa9e4066Sahrens 
253fa9e4066Sahrens 		object->object =
254fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
255fa9e4066Sahrens 	}
256fa9e4066Sahrens 
257fa9e4066Sahrens 	new_SnapshotBean(env, (SnapshotBean_t *)bean);
258fa9e4066Sahrens }
259fa9e4066Sahrens 
260fa9e4066Sahrens /* Create a VolumeSnapshotBean */
261fa9e4066Sahrens static void
new_VolumeSnapshotBean(JNIEnv * env,VolumeSnapshotBean_t * bean)262fa9e4066Sahrens new_VolumeSnapshotBean(JNIEnv *env, VolumeSnapshotBean_t *bean)
263fa9e4066Sahrens {
264fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
265fa9e4066Sahrens 
266fa9e4066Sahrens 	if (object->object == NULL) {
267fa9e4066Sahrens 		object->class =
268fa9e4066Sahrens 		    (*env)->FindClass(env,
269990b4856Slling 		    ZFSJNI_PACKAGE_DATA "VolumeSnapshotBean");
270fa9e4066Sahrens 
271fa9e4066Sahrens 		object->constructor =
272fa9e4066Sahrens 		    (*env)->GetMethodID(env, object->class, "<init>", "()V");
273fa9e4066Sahrens 
274fa9e4066Sahrens 		object->object =
275fa9e4066Sahrens 		    (*env)->NewObject(env, object->class, object->constructor);
276fa9e4066Sahrens 	}
277fa9e4066Sahrens 
278fa9e4066Sahrens 	new_SnapshotBean(env, (SnapshotBean_t *)bean);
279fa9e4066Sahrens }
280fa9e4066Sahrens 
281fa9e4066Sahrens static int
set_name_in_DatasetBean(JNIEnv * env,char * name,DatasetBean_t * bean)28232f884e0Stalley set_name_in_DatasetBean(JNIEnv *env, char *name, DatasetBean_t *bean)
283fa9e4066Sahrens {
284fa9e4066Sahrens 	jstring poolUTF;
285fa9e4066Sahrens 	jstring parentUTF;
286fa9e4066Sahrens 	jstring baseUTF;
287fa9e4066Sahrens 	zjni_Object_t *object = (zjni_Object_t *)bean;
288fa9e4066Sahrens 
289fa9e4066Sahrens 	/*
290fa9e4066Sahrens 	 * zhp->zfs_name has the format
291fa9e4066Sahrens 	 * <pool>[[/<container...>]/<dataset>[@<snapshot>]]
292fa9e4066Sahrens 	 */
293fa9e4066Sahrens 
294fa9e4066Sahrens 	regex_t re;
295fa9e4066Sahrens 	regmatch_t matches[REGEX_ZFS_NAME_NGROUPS];
296fa9e4066Sahrens 
297fa9e4066Sahrens 	if (regcomp(&re, REGEX_ZFS_NAME, REG_EXTENDED) != 0 ||
298fa9e4066Sahrens 	    regexec(&re, name, REGEX_ZFS_NAME_NGROUPS, matches, 0) != 0) {
299fa9e4066Sahrens 		regfree(&re);
300fa9e4066Sahrens 		zjni_throw_exception(env, "invalid name: %s", name);
301fa9e4066Sahrens 		return (-1);
302fa9e4066Sahrens 	}
303fa9e4066Sahrens 
304fa9e4066Sahrens 	regfree(&re);
305fa9e4066Sahrens 
306fa9e4066Sahrens 	/* Set names */
307fa9e4066Sahrens 	poolUTF = zjni_get_matched_string(
308fa9e4066Sahrens 	    env, name, matches + REGEX_ZFS_NAME_POOL_GROUP);
309fa9e4066Sahrens 	parentUTF = zjni_get_matched_string(
310fa9e4066Sahrens 	    env, name, matches + REGEX_ZFS_NAME_PARENT_GROUP);
311fa9e4066Sahrens 	baseUTF = zjni_get_matched_string(
312fa9e4066Sahrens 	    env, name, matches + REGEX_ZFS_NAME_BASE_GROUP);
313fa9e4066Sahrens 
314fa9e4066Sahrens 	if (poolUTF == NULL) {
315fa9e4066Sahrens 		poolUTF = baseUTF;
316fa9e4066Sahrens 	}
317fa9e4066Sahrens 
318fa9e4066Sahrens 	(*env)->CallVoidMethod(
319fa9e4066Sahrens 	    env, object->object, bean->method_setPoolName, poolUTF);
320fa9e4066Sahrens 	(*env)->CallVoidMethod(
321fa9e4066Sahrens 	    env, object->object, bean->method_setBaseName, baseUTF);
322fa9e4066Sahrens 
323fa9e4066Sahrens 	if (parentUTF != NULL) {
324fa9e4066Sahrens 		(*env)->CallVoidMethod(
325fa9e4066Sahrens 		    env, object->object, bean->method_setParentName, parentUTF);
326fa9e4066Sahrens 	}
327fa9e4066Sahrens 
32832f884e0Stalley 	return (0);
32932f884e0Stalley }
33032f884e0Stalley 
33132f884e0Stalley static int
populate_DatasetBean(JNIEnv * env,zfs_handle_t * zhp,DatasetBean_t * bean)33232f884e0Stalley populate_DatasetBean(JNIEnv *env, zfs_handle_t *zhp, DatasetBean_t *bean)
33332f884e0Stalley {
33432f884e0Stalley 	jobjectArray properties;
33532f884e0Stalley 	zjni_Object_t *object = (zjni_Object_t *)bean;
33632f884e0Stalley 
33732f884e0Stalley 	int result = set_name_in_DatasetBean(
33832f884e0Stalley 	    env, (char *)zfs_get_name(zhp), bean);
33932f884e0Stalley 	if (result != 0) {
34032f884e0Stalley 		/* Must not call any more Java methods to preserve exception */
34132f884e0Stalley 		return (-1);
34232f884e0Stalley 	}
34332f884e0Stalley 
344fa9e4066Sahrens 	properties = zjni_get_Dataset_properties(env, zhp);
345fa9e4066Sahrens 	if (properties == NULL) {
346fa9e4066Sahrens 		/* Must not call any more Java methods to preserve exception */
347fa9e4066Sahrens 		return (-1);
348fa9e4066Sahrens 	}
349fa9e4066Sahrens 
350fa9e4066Sahrens 	(*env)->CallVoidMethod(
351fa9e4066Sahrens 	    env, object->object, bean->method_setProperties, properties);
352fa9e4066Sahrens 
353fa9e4066Sahrens 	return (0);
354fa9e4066Sahrens }
355fa9e4066Sahrens 
356fa9e4066Sahrens static int
populate_PoolBean(JNIEnv * env,zpool_handle_t * zphp,zfs_handle_t * zhp,PoolBean_t * bean)35732f884e0Stalley populate_PoolBean(JNIEnv *env, zpool_handle_t *zphp, zfs_handle_t *zhp,
35832f884e0Stalley     PoolBean_t *bean)
359fa9e4066Sahrens {
360fbfd10ffStalley 	int result = 0;
36132f884e0Stalley 	zjni_Object_t *object = (zjni_Object_t *)bean;
36232f884e0Stalley 	PoolStatsBean_t *pool_stats = &(bean->interface_PoolStats);
36332f884e0Stalley 	DeviceStatsBean_t *dev_stats = (DeviceStatsBean_t *)pool_stats;
36432f884e0Stalley 	nvlist_t *devices = zjni_get_root_vdev(zphp);
3653349c8dcStalley 
36632f884e0Stalley 	if (devices == NULL ||
36732f884e0Stalley 	    populate_DeviceStatsBean(env, devices, dev_stats, object)) {
368fbfd10ffStalley 		result = -1;
369fbfd10ffStalley 	} else {
37032f884e0Stalley 		char *msgid;
37132f884e0Stalley 
37232f884e0Stalley 		/* Override value set in populate_DeviceStatsBean */
37332f884e0Stalley 		(*env)->CallVoidMethod(env, object->object,
37432f884e0Stalley 		    dev_stats->method_setSize,
375990b4856Slling 		    zpool_get_prop_int(zphp, ZPOOL_PROP_SIZE, NULL));
37632f884e0Stalley 
37732f884e0Stalley 		(*env)->CallVoidMethod(env, object->object,
37832f884e0Stalley 		    pool_stats->method_setPoolState,
37932f884e0Stalley 		    zjni_pool_state_to_obj(
380990b4856Slling 		    env, zpool_get_state(zphp)));
38132f884e0Stalley 
38232f884e0Stalley 		(*env)->CallVoidMethod(env, object->object,
38332f884e0Stalley 		    pool_stats->method_setPoolStatus,
38432f884e0Stalley 		    zjni_pool_status_to_obj(env,
385*eb633035STom Caputi 		    zpool_get_status(zphp, &msgid, NULL)));
38632f884e0Stalley 
387a55b6846Scristian 		(*env)->CallVoidMethod(env, object->object,
388a55b6846Scristian 		    pool_stats->method_setPoolVersion,
389a55b6846Scristian 		    zpool_get_prop_int(zphp, ZPOOL_PROP_VERSION, NULL));
390a55b6846Scristian 
39132f884e0Stalley 		/*
39232f884e0Stalley 		 * If a root file system does not exist for this pool, the pool
39332f884e0Stalley 		 * is likely faulted, so just set its name in the Java object.
39432f884e0Stalley 		 * Otherwise, populate all fields of the Java object.
39532f884e0Stalley 		 */
39632f884e0Stalley 		if (zhp == NULL) {
397990b4856Slling 			result = set_name_in_DatasetBean(env,
398990b4856Slling 			    (char *)zpool_get_name(zphp),
399990b4856Slling 			    (DatasetBean_t *)bean);
400fbfd10ffStalley 		} else {
401990b4856Slling 			result = populate_FileSystemBean(
402990b4856Slling 			    env, zhp, (FileSystemBean_t *)bean);
403fbfd10ffStalley 		}
404fbfd10ffStalley 	}
4053349c8dcStalley 
406fbfd10ffStalley 	return (result != 0);
407fa9e4066Sahrens }
408fa9e4066Sahrens 
409fa9e4066Sahrens static int
populate_FileSystemBean(JNIEnv * env,zfs_handle_t * zhp,FileSystemBean_t * bean)410fa9e4066Sahrens populate_FileSystemBean(JNIEnv *env, zfs_handle_t *zhp, FileSystemBean_t *bean)
411fa9e4066Sahrens {
412fa9e4066Sahrens 	return (populate_DatasetBean(env, zhp, (DatasetBean_t *)bean));
413fa9e4066Sahrens }
414fa9e4066Sahrens 
415fa9e4066Sahrens static int
populate_VolumeBean(JNIEnv * env,zfs_handle_t * zhp,VolumeBean_t * bean)416fa9e4066Sahrens populate_VolumeBean(JNIEnv *env, zfs_handle_t *zhp, VolumeBean_t *bean)
417fa9e4066Sahrens {
418fa9e4066Sahrens 	return (populate_DatasetBean(env, zhp, (DatasetBean_t *)bean));
419fa9e4066Sahrens }
420fa9e4066Sahrens 
421fa9e4066Sahrens static int
populate_SnapshotBean(JNIEnv * env,zfs_handle_t * zhp,SnapshotBean_t * bean)422fa9e4066Sahrens populate_SnapshotBean(JNIEnv *env, zfs_handle_t *zhp, SnapshotBean_t *bean)
423fa9e4066Sahrens {
424fa9e4066Sahrens 	return (populate_DatasetBean(env, zhp, (DatasetBean_t *)bean));
425fa9e4066Sahrens }
426fa9e4066Sahrens 
427fa9e4066Sahrens static int
populate_FileSystemSnapshotBean(JNIEnv * env,zfs_handle_t * zhp,FileSystemSnapshotBean_t * bean)428fa9e4066Sahrens populate_FileSystemSnapshotBean(JNIEnv *env, zfs_handle_t *zhp,
429fa9e4066Sahrens     FileSystemSnapshotBean_t *bean)
430fa9e4066Sahrens {
431fa9e4066Sahrens 	return (populate_SnapshotBean(env, zhp, (SnapshotBean_t *)bean));
432fa9e4066Sahrens }
433fa9e4066Sahrens 
434fa9e4066Sahrens static int
populate_VolumeSnapshotBean(JNIEnv * env,zfs_handle_t * zhp,VolumeSnapshotBean_t * bean)435fa9e4066Sahrens populate_VolumeSnapshotBean(JNIEnv *env, zfs_handle_t *zhp,
436fa9e4066Sahrens     VolumeSnapshotBean_t *bean)
437fa9e4066Sahrens {
438fa9e4066Sahrens 	return (populate_SnapshotBean(env, zhp, (SnapshotBean_t *)bean));
439fa9e4066Sahrens }
440fa9e4066Sahrens 
441fa9e4066Sahrens static jobject
create_PoolBean(JNIEnv * env,zpool_handle_t * zphp,zfs_handle_t * zhp)44232f884e0Stalley create_PoolBean(JNIEnv *env, zpool_handle_t *zphp, zfs_handle_t *zhp)
443fa9e4066Sahrens {
444fa9e4066Sahrens 	int result;
445fa9e4066Sahrens 	PoolBean_t bean_obj = {0};
446fa9e4066Sahrens 	PoolBean_t *bean = &bean_obj;
447fa9e4066Sahrens 
448fa9e4066Sahrens 	/* Construct PoolBean */
449fa9e4066Sahrens 	new_PoolBean(env, bean);
450fa9e4066Sahrens 
45132f884e0Stalley 	result = populate_PoolBean(env, zphp, zhp, bean);
452fa9e4066Sahrens 	if (result) {
453fa9e4066Sahrens 		/* Must not call any more Java methods to preserve exception */
454fa9e4066Sahrens 		return (NULL);
455fa9e4066Sahrens 	}
456fa9e4066Sahrens 
457fa9e4066Sahrens 	return (((zjni_Object_t *)bean)->object);
458fa9e4066Sahrens }
459fa9e4066Sahrens 
460fa9e4066Sahrens static jobject
create_FileSystemBean(JNIEnv * env,zfs_handle_t * zhp)461fa9e4066Sahrens create_FileSystemBean(JNIEnv *env, zfs_handle_t *zhp)
462fa9e4066Sahrens {
463fa9e4066Sahrens 	int result;
464fa9e4066Sahrens 	FileSystemBean_t bean_obj = {0};
465fa9e4066Sahrens 	FileSystemBean_t *bean = &bean_obj;
466fa9e4066Sahrens 
467fa9e4066Sahrens 	/* Construct FileSystemBean */
468fa9e4066Sahrens 	new_FileSystemBean(env, bean);
469fa9e4066Sahrens 
470fa9e4066Sahrens 	result = populate_FileSystemBean(env, zhp, bean);
471fa9e4066Sahrens 	if (result) {
472fa9e4066Sahrens 		/* Must not call any more Java methods to preserve exception */
473fa9e4066Sahrens 		return (NULL);
474fa9e4066Sahrens 	}
475fa9e4066Sahrens 
476fa9e4066Sahrens 	return (((zjni_Object_t *)bean)->object);
477fa9e4066Sahrens }
478fa9e4066Sahrens 
479fa9e4066Sahrens static jobject
create_VolumeBean(JNIEnv * env,zfs_handle_t * zhp)480fa9e4066Sahrens create_VolumeBean(JNIEnv *env, zfs_handle_t *zhp)
481fa9e4066Sahrens {
482fa9e4066Sahrens 	int result;
483fa9e4066Sahrens 	VolumeBean_t bean_obj = {0};
484fa9e4066Sahrens 	VolumeBean_t *bean = &bean_obj;
485fa9e4066Sahrens 
486fa9e4066Sahrens 	/* Construct VolumeBean */
487fa9e4066Sahrens 	new_VolumeBean(env, bean);
488fa9e4066Sahrens 
489fa9e4066Sahrens 	result = populate_VolumeBean(env, zhp, bean);
490fa9e4066Sahrens 	if (result) {
491fa9e4066Sahrens 		/* Must not call any more Java methods to preserve exception */
492fa9e4066Sahrens 		return (NULL);
493fa9e4066Sahrens 	}
494fa9e4066Sahrens 
495fa9e4066Sahrens 	return (((zjni_Object_t *)bean)->object);
496fa9e4066Sahrens }
497fa9e4066Sahrens 
498fa9e4066Sahrens static jobject
create_FileSystemSnapshotBean(JNIEnv * env,zfs_handle_t * zhp)499fa9e4066Sahrens create_FileSystemSnapshotBean(JNIEnv *env, zfs_handle_t *zhp)
500fa9e4066Sahrens {
501fa9e4066Sahrens 	int result;
502fa9e4066Sahrens 	FileSystemSnapshotBean_t bean_obj = {0};
503fa9e4066Sahrens 	FileSystemSnapshotBean_t *bean = &bean_obj;
504fa9e4066Sahrens 
505fa9e4066Sahrens 	/* Construct FileSystemSnapshotBean */
506fa9e4066Sahrens 	new_FileSystemSnapshotBean(env, bean);
507fa9e4066Sahrens 
508fa9e4066Sahrens 	result = populate_FileSystemSnapshotBean(env, zhp, bean);
509fa9e4066Sahrens 	if (result) {
510fa9e4066Sahrens 		/* Must not call any more Java methods to preserve exception */
511fa9e4066Sahrens 		return (NULL);
512fa9e4066Sahrens 	}
513fa9e4066Sahrens 
514fa9e4066Sahrens 	return (((zjni_Object_t *)bean)->object);
515fa9e4066Sahrens }
516fa9e4066Sahrens 
517fa9e4066Sahrens static jobject
create_VolumeSnapshotBean(JNIEnv * env,zfs_handle_t * zhp)518fa9e4066Sahrens create_VolumeSnapshotBean(JNIEnv *env, zfs_handle_t *zhp)
519fa9e4066Sahrens {
520fa9e4066Sahrens 	int result;
521fa9e4066Sahrens 	VolumeSnapshotBean_t bean_obj = {0};
522fa9e4066Sahrens 	VolumeSnapshotBean_t *bean = &bean_obj;
523fa9e4066Sahrens 
524fa9e4066Sahrens 	/* Construct VolumeSnapshotBean */
525fa9e4066Sahrens 	new_VolumeSnapshotBean(env, bean);
526fa9e4066Sahrens 
527fa9e4066Sahrens 	result = populate_VolumeSnapshotBean(env, zhp, bean);
528fa9e4066Sahrens 	if (result) {
529fa9e4066Sahrens 		/* Must not call any more Java methods to preserve exception */
530fa9e4066Sahrens 		return (NULL);
531fa9e4066Sahrens 	}
532fa9e4066Sahrens 
533fa9e4066Sahrens 	return (((zjni_Object_t *)bean)->object);
534fa9e4066Sahrens }
535fa9e4066Sahrens 
536fa9e4066Sahrens static jobject
create_DatasetBean(JNIEnv * env,zfs_handle_t * zhp)537fa9e4066Sahrens create_DatasetBean(JNIEnv *env, zfs_handle_t *zhp)
538fa9e4066Sahrens {
539fa9e4066Sahrens 	jobject object = NULL;
540fa9e4066Sahrens 
541fa9e4066Sahrens 	switch (zfs_get_type(zhp)) {
542fa9e4066Sahrens 	case ZFS_TYPE_FILESYSTEM:
54332f884e0Stalley 		object = create_FileSystemBean(env, zhp);
544fa9e4066Sahrens 		break;
545fa9e4066Sahrens 
546fa9e4066Sahrens 	case ZFS_TYPE_VOLUME:
547fa9e4066Sahrens 		object = create_VolumeBean(env, zhp);
548fa9e4066Sahrens 		break;
549fa9e4066Sahrens 
550fa9e4066Sahrens 	case ZFS_TYPE_SNAPSHOT:
551fa9e4066Sahrens 		object = is_fs_snapshot(zhp) ?
552fa9e4066Sahrens 		    create_FileSystemSnapshotBean(env, zhp) :
553fa9e4066Sahrens 		    create_VolumeSnapshotBean(env, zhp);
554fa9e4066Sahrens 		break;
555fa9e4066Sahrens 	}
556fa9e4066Sahrens 
557fa9e4066Sahrens 	return (object);
558fa9e4066Sahrens }
559fa9e4066Sahrens 
560fa9e4066Sahrens /*
561fa9e4066Sahrens  * Determines whether the given snapshot is a snapshot of a file
562fa9e4066Sahrens  * system or of a volume.
563fa9e4066Sahrens  *
564fa9e4066Sahrens  * Returns:
565fa9e4066Sahrens  *
566fa9e4066Sahrens  *	0 if it is a volume snapshot
567fa9e4066Sahrens  *	1 if it is a file system snapshot
568fa9e4066Sahrens  *	-1 on error
569fa9e4066Sahrens  */
570fa9e4066Sahrens static int
is_fs_snapshot(zfs_handle_t * zhp)571fa9e4066Sahrens is_fs_snapshot(zfs_handle_t *zhp)
572fa9e4066Sahrens {
5739adfa60dSMatthew Ahrens 	char parent[ZFS_MAX_DATASET_NAME_LEN];
574fa9e4066Sahrens 	zfs_handle_t *parent_zhp;
575fa9e4066Sahrens 	int isfs;
576fa9e4066Sahrens 
577fa9e4066Sahrens 	if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) {
578fa9e4066Sahrens 		return (-1);
579fa9e4066Sahrens 	}
580fa9e4066Sahrens 
581fa9e4066Sahrens 	zjni_get_dataset_from_snapshot(
582fa9e4066Sahrens 	    zfs_get_name(zhp), parent, sizeof (parent));
583fa9e4066Sahrens 
584990b4856Slling 	parent_zhp = zfs_open(g_zfs, parent, ZFS_TYPE_DATASET);
585fa9e4066Sahrens 	if (parent_zhp == NULL) {
586fa9e4066Sahrens 		return (-1);
587fa9e4066Sahrens 	}
588fa9e4066Sahrens 
589fa9e4066Sahrens 	isfs = zfs_get_type(parent_zhp) == ZFS_TYPE_FILESYSTEM;
590fa9e4066Sahrens 	zfs_close(parent_zhp);
591fa9e4066Sahrens 
592fa9e4066Sahrens 	return (isfs);
593fa9e4066Sahrens }
594fa9e4066Sahrens 
595fa9e4066Sahrens static int
is_pool_name(const char * name)59632f884e0Stalley is_pool_name(const char *name)
597fa9e4066Sahrens {
598389056bdStomee 	return (strchr(name, '/') == NULL && strchr(name, '@') == NULL);
599fa9e4066Sahrens }
600fa9e4066Sahrens 
60132f884e0Stalley /*
60232f884e0Stalley  * Package-private functions
60332f884e0Stalley  */
60432f884e0Stalley 
60532f884e0Stalley /*
60632f884e0Stalley  * Callback function for zpool_iter().  Creates a Pool and adds it to
60732f884e0Stalley  * the given zjni_ArrayList.
60832f884e0Stalley  */
60932f884e0Stalley int
zjni_create_add_Pool(zpool_handle_t * zphp,void * data)61032f884e0Stalley zjni_create_add_Pool(zpool_handle_t *zphp, void *data)
611fa9e4066Sahrens {
61232f884e0Stalley 	JNIEnv *env = ((zjni_ArrayCallbackData_t *)data)->env;
61332f884e0Stalley 	zjni_Collection_t *list = ((zjni_ArrayCallbackData_t *)data)->list;
614fa9e4066Sahrens 
61532f884e0Stalley 	/* Get root fs for this pool -- may be NULL if pool is faulted */
61699653d4eSeschrock 	zfs_handle_t *zhp = zfs_open(g_zfs, zpool_get_name(zphp),
61799653d4eSeschrock 	    ZFS_TYPE_FILESYSTEM);
61832f884e0Stalley 
61932f884e0Stalley 	jobject bean = create_PoolBean(env, zphp, zhp);
620fa9e4066Sahrens 
621990b4856Slling 	if (zhp != NULL)
622990b4856Slling 		zfs_close(zhp);
623fa9e4066Sahrens 
62432f884e0Stalley 	zpool_close(zphp);
62532f884e0Stalley 
62632f884e0Stalley 	if (bean == NULL) {
62732f884e0Stalley 		/* Must not call any more Java methods to preserve exception */
62832f884e0Stalley 		return (-1);
629fa9e4066Sahrens 	}
630fa9e4066Sahrens 
63132f884e0Stalley 	/* Add pool to zjni_ArrayList */
63232f884e0Stalley 	(*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
63332f884e0Stalley 	    ((zjni_Collection_t *)list)->method_add, bean);
634fa9e4066Sahrens 
63532f884e0Stalley 	return (0);
63632f884e0Stalley }
637fa9e4066Sahrens 
638fa9e4066Sahrens /*
639fa9e4066Sahrens  * Callback function for zfs_iter_children().  Creates the appropriate
640fa9e4066Sahrens  * Dataset and adds it to the given zjni_ArrayList.  Per the contract
641fa9e4066Sahrens  * with zfs_iter_children(), calls zfs_close() on the given
642fa9e4066Sahrens  * zfs_handle_t.
643fa9e4066Sahrens  */
644fa9e4066Sahrens int
zjni_create_add_Dataset(zfs_handle_t * zhp,void * data)645fa9e4066Sahrens zjni_create_add_Dataset(zfs_handle_t *zhp, void *data)
646fa9e4066Sahrens {
647fa9e4066Sahrens 	JNIEnv *env = ((zjni_ArrayCallbackData_t *)data)->env;
648fa9e4066Sahrens 	zjni_Collection_t *list = ((zjni_ArrayCallbackData_t *)data)->list;
649fa9e4066Sahrens 	zfs_type_t typemask =
650fa9e4066Sahrens 	    ((zjni_DatasetArrayCallbackData_t *)data)->typemask;
651fa9e4066Sahrens 
652fa9e4066Sahrens 	/* Only add allowed types */
653fa9e4066Sahrens 	if (zfs_get_type(zhp) & typemask) {
654fa9e4066Sahrens 
655fa9e4066Sahrens 		jobject bean = create_DatasetBean(env, zhp);
656fa9e4066Sahrens 		zfs_close(zhp);
657fa9e4066Sahrens 
658fa9e4066Sahrens 		if (bean == NULL) {
659fa9e4066Sahrens 			/*
660fa9e4066Sahrens 			 * Must not call any more Java methods to preserve
661fa9e4066Sahrens 			 * exception
662fa9e4066Sahrens 			 */
663fa9e4066Sahrens 			return (-1);
664fa9e4066Sahrens 		}
665fa9e4066Sahrens 
66632f884e0Stalley 		/* Add Dataset to zjni_ArrayList */
667fa9e4066Sahrens 		(*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
668fa9e4066Sahrens 		    ((zjni_Collection_t *)list)->method_add, bean);
6693ccfa83cSahrens 	} else {
6703ccfa83cSahrens 		zfs_close(zhp);
671fa9e4066Sahrens 	}
672fa9e4066Sahrens 
673fa9e4066Sahrens 	return (0);
674fa9e4066Sahrens }
675fa9e4066Sahrens 
676fa9e4066Sahrens jobjectArray
zjni_get_Datasets_below(JNIEnv * env,jstring parentUTF,zfs_type_t parent_typemask,zfs_type_t child_typemask,char * arrayClass)677fa9e4066Sahrens zjni_get_Datasets_below(JNIEnv *env, jstring parentUTF,
678fa9e4066Sahrens     zfs_type_t parent_typemask, zfs_type_t child_typemask, char *arrayClass)
679fa9e4066Sahrens {
680fa9e4066Sahrens 	jobjectArray array = NULL;
681fa9e4066Sahrens 
68232f884e0Stalley 	if (parentUTF != NULL) {
68332f884e0Stalley 		zfs_handle_t *zhp;
68432f884e0Stalley 		int error = 1;
68532f884e0Stalley 		const char *name =
68632f884e0Stalley 		    (*env)->GetStringUTFChars(env, parentUTF, NULL);
687fa9e4066Sahrens 
68832f884e0Stalley 		/* Create an array list to hold the children */
68932f884e0Stalley 		zjni_DatasetSet_t list_obj = {0};
69032f884e0Stalley 		zjni_DatasetSet_t *list = &list_obj;
69132f884e0Stalley 		zjni_new_DatasetSet(env, list);
692fa9e4066Sahrens 
69332f884e0Stalley 		/* Retrieve parent dataset */
69499653d4eSeschrock 		zhp = zfs_open(g_zfs, name, parent_typemask);
695fa9e4066Sahrens 
69632f884e0Stalley 		if (zhp != NULL) {
69732f884e0Stalley 			zjni_DatasetArrayCallbackData_t data = {0};
69832f884e0Stalley 			data.data.env = env;
69932f884e0Stalley 			data.data.list = (zjni_Collection_t *)list;
70032f884e0Stalley 			data.typemask = child_typemask;
70132f884e0Stalley 
70232f884e0Stalley 			(void) zfs_iter_children(zhp, zjni_create_add_Dataset,
70332f884e0Stalley 			    &data);
70432f884e0Stalley 
70532f884e0Stalley 			zfs_close(zhp);
70632f884e0Stalley 
70732f884e0Stalley 			if ((*env)->ExceptionOccurred(env) == NULL) {
70832f884e0Stalley 				error = 0;
70932f884e0Stalley 			}
71032f884e0Stalley 		} else
71132f884e0Stalley 
71232f884e0Stalley 		/* Parent is not a dataset -- see if it's a faulted pool */
71332f884e0Stalley 		if ((parent_typemask & ZFS_TYPE_FILESYSTEM) &&
71432f884e0Stalley 		    is_pool_name(name)) {
71599653d4eSeschrock 			zpool_handle_t *zphp = zpool_open_canfail(g_zfs, name);
71632f884e0Stalley 
71732f884e0Stalley 			if (zphp != NULL) {
71832f884e0Stalley 				/* A faulted pool has no datasets */
71932f884e0Stalley 				error = 0;
72032f884e0Stalley 				zpool_close(zphp);
72132f884e0Stalley 			}
72232f884e0Stalley 		}
723fa9e4066Sahrens 
72432f884e0Stalley 		(*env)->ReleaseStringUTFChars(env, parentUTF, name);
72532f884e0Stalley 
72632f884e0Stalley 		if (!error) {
727fbfd10ffStalley 			array = zjni_Collection_to_array(
728fbfd10ffStalley 			    env, (zjni_Collection_t *)list, arrayClass);
729fbfd10ffStalley 		}
730fa9e4066Sahrens 	}
731fa9e4066Sahrens 
732fa9e4066Sahrens 	return (array);
733fa9e4066Sahrens }
734fa9e4066Sahrens 
735fa9e4066Sahrens jobjectArray
zjni_get_Datasets_dependents(JNIEnv * env,jobjectArray paths)736fa9e4066Sahrens zjni_get_Datasets_dependents(JNIEnv *env, jobjectArray paths)
737fa9e4066Sahrens {
738fa9e4066Sahrens 	jint i;
739fa9e4066Sahrens 	jint npaths;
740fa9e4066Sahrens 	zjni_DatasetArrayCallbackData_t data = {0};
741fa9e4066Sahrens 	jobjectArray array = NULL;
742fa9e4066Sahrens 
743fa9e4066Sahrens 	/* Create a list to hold the children */
744fa9e4066Sahrens 	zjni_DatasetSet_t list_obj = {0};
745fa9e4066Sahrens 	zjni_DatasetSet_t *list = &list_obj;
746fa9e4066Sahrens 	zjni_new_DatasetSet(env, list);
747fa9e4066Sahrens 
748fa9e4066Sahrens 	data.data.env = env;
749fa9e4066Sahrens 	data.data.list = (zjni_Collection_t *)list;
750990b4856Slling 	data.typemask = ZFS_TYPE_DATASET;
751fa9e4066Sahrens 
752fa9e4066Sahrens 	npaths = (*env)->GetArrayLength(env, paths);
753fa9e4066Sahrens 	for (i = 0; i < npaths; i++) {
754fa9e4066Sahrens 
755fa9e4066Sahrens 		jstring pathUTF = (jstring)
756fa9e4066Sahrens 		    ((*env)->GetObjectArrayElement(env, paths, i));
757fa9e4066Sahrens 
75832f884e0Stalley 		if (pathUTF != NULL) {
75932f884e0Stalley 			const char *path =
76032f884e0Stalley 			    (*env)->GetStringUTFChars(env, pathUTF, NULL);
76132f884e0Stalley 
762990b4856Slling 			zfs_handle_t *zhp = zfs_open(g_zfs, path,
763990b4856Slling 			    ZFS_TYPE_DATASET);
76432f884e0Stalley 			if (zhp != NULL) {
76532f884e0Stalley 				/* Add all dependents of this Dataset to list */
7663bb79becSeschrock 				(void) zfs_iter_dependents(zhp, B_FALSE,
76732f884e0Stalley 				    zjni_create_add_Dataset, &data);
76832f884e0Stalley 
76932f884e0Stalley 				/* Add this Dataset to list (and close zhp) */
77032f884e0Stalley 				(void) zjni_create_add_Dataset(zhp, &data);
7713ccfa83cSahrens 			} else if (is_pool_name(path)) {
7723ccfa83cSahrens 				/*
7733ccfa83cSahrens 				 * Path is not a dataset -
7743ccfa83cSahrens 				 * see if it's a faulted pool
7753ccfa83cSahrens 				 */
77699653d4eSeschrock 				zpool_handle_t *zphp = zpool_open_canfail(g_zfs,
77799653d4eSeschrock 				    path);
77832f884e0Stalley 
77932f884e0Stalley 				if (zphp != NULL) {
78032f884e0Stalley 					/*
78132f884e0Stalley 					 * Add this Pool to list (and
78232f884e0Stalley 					 * close zphp)
78332f884e0Stalley 					 */
78432f884e0Stalley 					(void) zjni_create_add_Pool(zphp,
78532f884e0Stalley 					    &data.data);
78632f884e0Stalley 				}
78732f884e0Stalley 			}
78832f884e0Stalley 
78932f884e0Stalley 			(*env)->ReleaseStringUTFChars(env, pathUTF, path);
790fa9e4066Sahrens 		}
791fa9e4066Sahrens 	}
792fa9e4066Sahrens 
793fa9e4066Sahrens 	if ((*env)->ExceptionOccurred(env) == NULL) {
794fa9e4066Sahrens 		array = zjni_Collection_to_array(env, (zjni_Collection_t *)list,
795fa9e4066Sahrens 		    ZFSJNI_PACKAGE_DATA "Dataset");
796fa9e4066Sahrens 	}
797fa9e4066Sahrens 
798fa9e4066Sahrens 	return (array);
799fa9e4066Sahrens }
800fa9e4066Sahrens 
801fa9e4066Sahrens /*
802fa9e4066Sahrens  * Gets a Dataset of the given name and type, or NULL if no such
803fa9e4066Sahrens  * Dataset exists.
804fa9e4066Sahrens  */
805fa9e4066Sahrens jobject
zjni_get_Dataset(JNIEnv * env,jstring nameUTF,zfs_type_t typemask)806fa9e4066Sahrens zjni_get_Dataset(JNIEnv *env, jstring nameUTF, zfs_type_t typemask)
807fa9e4066Sahrens {
808fa9e4066Sahrens 	jobject device = NULL;
80932f884e0Stalley 	const char *name = (*env)->GetStringUTFChars(env, nameUTF, NULL);
81099653d4eSeschrock 	zfs_handle_t *zhp = zfs_open(g_zfs, name, typemask);
81132f884e0Stalley 
81232f884e0Stalley 	if ((typemask & ZFS_TYPE_FILESYSTEM) && is_pool_name(name)) {
81399653d4eSeschrock 		zpool_handle_t *zphp = zpool_open_canfail(g_zfs, name);
81432f884e0Stalley 
81532f884e0Stalley 		if (zphp != NULL) {
81632f884e0Stalley 			device = create_PoolBean(env, zphp, zhp);
81732f884e0Stalley 			zpool_close(zphp);
81832f884e0Stalley 		}
81932f884e0Stalley 	} else if (zhp != NULL) {
82032f884e0Stalley 		/* Creates a Dataset object of the appropriate class */
821fbfd10ffStalley 		device = create_DatasetBean(env, zhp);
82232f884e0Stalley 	}
82332f884e0Stalley 
82432f884e0Stalley 	if (zhp != NULL) {
825fa9e4066Sahrens 		zfs_close(zhp);
826fa9e4066Sahrens 	}
827fa9e4066Sahrens 
82832f884e0Stalley 	(*env)->ReleaseStringUTFChars(env, nameUTF, name);
82932f884e0Stalley 
830fa9e4066Sahrens 	return (device);
831fa9e4066Sahrens }
832