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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2020 Joyent, Inc.
25 */
26
27 #include "libzfs_jni_util.h"
28 #include "libzfs_jni_pool.h"
29 #include <libzutil.h>
30 #include <strings.h>
31
32 /*
33 * Types
34 */
35
36 typedef struct ImportablePoolBean {
37 zjni_Object_t super;
38 PoolStatsBean_t interface_PoolStats;
39
40 jmethodID method_setName;
41 jmethodID method_setId;
42 } ImportablePoolBean_t;
43
44 typedef struct VirtualDeviceBean {
45 zjni_Object_t super;
46 DeviceStatsBean_t interface_DeviceStats;
47
48 jmethodID method_setPoolName;
49 jmethodID method_setParentIndex;
50 jmethodID method_setIndex;
51 } VirtualDeviceBean_t;
52
53 typedef struct LeafVirtualDeviceBean {
54 VirtualDeviceBean_t super;
55
56 jmethodID method_setName;
57 } LeafVirtualDeviceBean_t;
58
59 typedef struct DiskVirtualDeviceBean {
60 LeafVirtualDeviceBean_t super;
61 } DiskVirtualDeviceBean_t;
62
63 typedef struct SliceVirtualDeviceBean {
64 LeafVirtualDeviceBean_t super;
65 } SliceVirtualDeviceBean_t;
66
67 typedef struct FileVirtualDeviceBean {
68 LeafVirtualDeviceBean_t super;
69 } FileVirtualDeviceBean_t;
70
71 typedef struct RAIDVirtualDeviceBean {
72 VirtualDeviceBean_t super;
73
74 jmethodID method_setParity;
75 } RAIDVirtualDeviceBean_t;
76
77 typedef struct MirrorVirtualDeviceBean {
78 VirtualDeviceBean_t super;
79 } MirrorVirtualDeviceBean_t;
80
81 /*
82 * Data
83 */
84
85 /* vdev_state_t to DeviceStats$DeviceState map */
86 static zjni_field_mapping_t vdev_state_map[] = {
87 { VDEV_STATE_CANT_OPEN, "VDEV_STATE_CANT_OPEN" },
88 { VDEV_STATE_CLOSED, "VDEV_STATE_CLOSED" },
89 { VDEV_STATE_DEGRADED, "VDEV_STATE_DEGRADED" },
90 { VDEV_STATE_HEALTHY, "VDEV_STATE_HEALTHY" },
91 { VDEV_STATE_OFFLINE, "VDEV_STATE_OFFLINE" },
92 { VDEV_STATE_UNKNOWN, "VDEV_STATE_UNKNOWN" },
93 { -1, NULL },
94 };
95
96 /* vdev_aux_t to DeviceStats$DeviceStatus map */
97 static zjni_field_mapping_t vdev_aux_map[] = {
98 { VDEV_AUX_NONE, "VDEV_AUX_NONE" },
99 { VDEV_AUX_OPEN_FAILED, "VDEV_AUX_OPEN_FAILED" },
100 { VDEV_AUX_CORRUPT_DATA, "VDEV_AUX_CORRUPT_DATA" },
101 { VDEV_AUX_NO_REPLICAS, "VDEV_AUX_NO_REPLICAS" },
102 { VDEV_AUX_BAD_GUID_SUM, "VDEV_AUX_BAD_GUID_SUM" },
103 { VDEV_AUX_TOO_SMALL, "VDEV_AUX_TOO_SMALL" },
104 { VDEV_AUX_BAD_LABEL, "VDEV_AUX_BAD_LABEL" },
105 { -1, NULL },
106 };
107
108 /* zpool_state_t to PoolStats$PoolState map */
109 static zjni_field_mapping_t pool_state_map[] = {
110 { POOL_STATE_ACTIVE, "POOL_STATE_ACTIVE" },
111 { POOL_STATE_EXPORTED, "POOL_STATE_EXPORTED" },
112 { POOL_STATE_DESTROYED, "POOL_STATE_DESTROYED" },
113 { POOL_STATE_SPARE, "POOL_STATE_SPARE" },
114 { POOL_STATE_UNINITIALIZED, "POOL_STATE_UNINITIALIZED" },
115 { POOL_STATE_UNAVAIL, "POOL_STATE_UNAVAIL" },
116 { POOL_STATE_POTENTIALLY_ACTIVE, "POOL_STATE_POTENTIALLY_ACTIVE" },
117 { -1, NULL },
118 };
119
120 /* zpool_status_t to PoolStats$PoolStatus map */
121 static zjni_field_mapping_t zpool_status_map[] = {
122 { ZPOOL_STATUS_CORRUPT_CACHE, "ZPOOL_STATUS_CORRUPT_CACHE" },
123 { ZPOOL_STATUS_MISSING_DEV_R, "ZPOOL_STATUS_MISSING_DEV_R" },
124 { ZPOOL_STATUS_MISSING_DEV_NR, "ZPOOL_STATUS_MISSING_DEV_NR" },
125 { ZPOOL_STATUS_CORRUPT_LABEL_R, "ZPOOL_STATUS_CORRUPT_LABEL_R" },
126 { ZPOOL_STATUS_CORRUPT_LABEL_NR, "ZPOOL_STATUS_CORRUPT_LABEL_NR" },
127 { ZPOOL_STATUS_BAD_GUID_SUM, "ZPOOL_STATUS_BAD_GUID_SUM" },
128 { ZPOOL_STATUS_CORRUPT_POOL, "ZPOOL_STATUS_CORRUPT_POOL" },
129 { ZPOOL_STATUS_CORRUPT_DATA, "ZPOOL_STATUS_CORRUPT_DATA" },
130 { ZPOOL_STATUS_FAILING_DEV, "ZPOOL_STATUS_FAILING_DEV" },
131 { ZPOOL_STATUS_VERSION_NEWER, "ZPOOL_STATUS_VERSION_NEWER" },
132 { ZPOOL_STATUS_HOSTID_MISMATCH, "ZPOOL_STATUS_HOSTID_MISMATCH" },
133 { ZPOOL_STATUS_FAULTED_DEV_R, "ZPOOL_STATUS_FAULTED_DEV_R" },
134 { ZPOOL_STATUS_FAULTED_DEV_NR, "ZPOOL_STATUS_FAULTED_DEV_NR" },
135 { ZPOOL_STATUS_BAD_LOG, "ZPOOL_STATUS_BAD_LOG" },
136 { ZPOOL_STATUS_VERSION_OLDER, "ZPOOL_STATUS_VERSION_OLDER" },
137 { ZPOOL_STATUS_RESILVERING, "ZPOOL_STATUS_RESILVERING" },
138 { ZPOOL_STATUS_OFFLINE_DEV, "ZPOOL_STATUS_OFFLINE_DEV" },
139 { ZPOOL_STATUS_REMOVED_DEV, "ZPOOL_STATUS_REMOVED_DEV" },
140 { ZPOOL_STATUS_OK, "ZPOOL_STATUS_OK" },
141 { -1, NULL }
142 };
143
144 /*
145 * Function prototypes
146 */
147
148 static void new_ImportablePoolBean(JNIEnv *, ImportablePoolBean_t *);
149 static void new_VirtualDevice(JNIEnv *, VirtualDeviceBean_t *);
150 static void new_LeafVirtualDevice(JNIEnv *, LeafVirtualDeviceBean_t *);
151 static void new_DiskVirtualDeviceBean(JNIEnv *, DiskVirtualDeviceBean_t *);
152 static void new_SliceVirtualDeviceBean(JNIEnv *, SliceVirtualDeviceBean_t *);
153 static void new_FileVirtualDeviceBean(JNIEnv *, FileVirtualDeviceBean_t *);
154 static void new_RAIDVirtualDeviceBean(JNIEnv *, RAIDVirtualDeviceBean_t *);
155 static void new_MirrorVirtualDeviceBean(JNIEnv *, MirrorVirtualDeviceBean_t *);
156 static int populate_ImportablePoolBean(
157 JNIEnv *, ImportablePoolBean_t *, nvlist_t *);
158 static int populate_VirtualDeviceBean(JNIEnv *, zpool_handle_t *,
159 nvlist_t *, uint64_t *p_vdev_id, VirtualDeviceBean_t *);
160 static int populate_LeafVirtualDeviceBean(JNIEnv *, zpool_handle_t *,
161 nvlist_t *, uint64_t *p_vdev_id, LeafVirtualDeviceBean_t *);
162 static int populate_DiskVirtualDeviceBean(JNIEnv *, zpool_handle_t *,
163 nvlist_t *, uint64_t *p_vdev_id, DiskVirtualDeviceBean_t *);
164 static int populate_SliceVirtualDeviceBean(JNIEnv *, zpool_handle_t *,
165 nvlist_t *, uint64_t *p_vdev_id, SliceVirtualDeviceBean_t *);
166 static int populate_FileVirtualDeviceBean(JNIEnv *, zpool_handle_t *,
167 nvlist_t *, uint64_t *p_vdev_id, FileVirtualDeviceBean_t *);
168 static int populate_RAIDVirtualDeviceBean(JNIEnv *, zpool_handle_t *,
169 nvlist_t *, uint64_t *p_vdev_id, RAIDVirtualDeviceBean_t *);
170 static int populate_MirrorVirtualDeviceBean(JNIEnv *, zpool_handle_t *,
171 nvlist_t *, uint64_t *p_vdev_id, MirrorVirtualDeviceBean_t *);
172 static jobject create_ImportablePoolBean(JNIEnv *, nvlist_t *);
173 static jobject create_DiskVirtualDeviceBean(
174 JNIEnv *, zpool_handle_t *, nvlist_t *, uint64_t *p_vdev_id);
175 static jobject create_SliceVirtualDeviceBean(
176 JNIEnv *, zpool_handle_t *, nvlist_t *, uint64_t *p_vdev_id);
177 static jobject create_FileVirtualDeviceBean(
178 JNIEnv *, zpool_handle_t *, nvlist_t *, uint64_t *p_vdev_id);
179 static jobject create_RAIDVirtualDeviceBean(
180 JNIEnv *, zpool_handle_t *, nvlist_t *, uint64_t *p_vdev_id);
181 static jobject create_MirrorVirtualDeviceBean(
182 JNIEnv *, zpool_handle_t *, nvlist_t *, uint64_t *p_vdev_id);
183 static char *find_field(const zjni_field_mapping_t *, int);
184 static jobject zjni_vdev_state_to_obj(JNIEnv *, vdev_state_t);
185 static jobject zjni_vdev_aux_to_obj(JNIEnv *, vdev_aux_t);
186
187 /*
188 * Static functions
189 */
190
191 /* Create a ImportablePoolBean */
192 static void
new_ImportablePoolBean(JNIEnv * env,ImportablePoolBean_t * bean)193 new_ImportablePoolBean(JNIEnv *env, ImportablePoolBean_t *bean)
194 {
195 zjni_Object_t *object = (zjni_Object_t *)bean;
196
197 if (object->object == NULL) {
198 object->class =
199 (*env)->FindClass(env,
200 ZFSJNI_PACKAGE_DATA "ImportablePoolBean");
201
202 object->constructor =
203 (*env)->GetMethodID(env, object->class, "<init>", "()V");
204
205 object->object =
206 (*env)->NewObject(env, object->class, object->constructor);
207 }
208
209 new_PoolStats(env, &(bean->interface_PoolStats), object);
210
211 bean->method_setName = (*env)->GetMethodID(
212 env, object->class, "setName", "(Ljava/lang/String;)V");
213
214 bean->method_setId = (*env)->GetMethodID(
215 env, object->class, "setId", "(J)V");
216 }
217
218 /* Create a VirtualDeviceBean */
219 static void
new_VirtualDevice(JNIEnv * env,VirtualDeviceBean_t * bean)220 new_VirtualDevice(JNIEnv *env, VirtualDeviceBean_t *bean)
221 {
222 zjni_Object_t *object = (zjni_Object_t *)bean;
223
224 if (object->object == NULL) {
225 object->class =
226 (*env)->FindClass(env,
227 ZFSJNI_PACKAGE_DATA "VirtualDeviceBean");
228
229 object->constructor =
230 (*env)->GetMethodID(env, object->class, "<init>", "()V");
231
232 object->object =
233 (*env)->NewObject(env, object->class, object->constructor);
234 }
235
236 new_DeviceStats(env, &(bean->interface_DeviceStats), object);
237
238 bean->method_setPoolName = (*env)->GetMethodID(
239 env, object->class, "setPoolName", "(Ljava/lang/String;)V");
240
241 bean->method_setParentIndex = (*env)->GetMethodID(
242 env, object->class, "setParentIndex", "(Ljava/lang/Long;)V");
243
244 bean->method_setIndex = (*env)->GetMethodID(
245 env, object->class, "setIndex", "(J)V");
246 }
247
248 /* Create a LeafVirtualDeviceBean */
249 static void
new_LeafVirtualDevice(JNIEnv * env,LeafVirtualDeviceBean_t * bean)250 new_LeafVirtualDevice(JNIEnv *env, LeafVirtualDeviceBean_t *bean)
251 {
252 zjni_Object_t *object = (zjni_Object_t *)bean;
253
254 if (object->object == NULL) {
255 object->class =
256 (*env)->FindClass(env,
257 ZFSJNI_PACKAGE_DATA "LeafVirtualDeviceBean");
258
259 object->constructor =
260 (*env)->GetMethodID(env, object->class, "<init>", "()V");
261
262 object->object =
263 (*env)->NewObject(env, object->class, object->constructor);
264 }
265
266 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean);
267
268 bean->method_setName = (*env)->GetMethodID(
269 env, object->class, "setName", "(Ljava/lang/String;)V");
270 }
271
272 /* Create a DiskVirtualDeviceBean */
273 static void
new_DiskVirtualDeviceBean(JNIEnv * env,DiskVirtualDeviceBean_t * bean)274 new_DiskVirtualDeviceBean(JNIEnv *env, DiskVirtualDeviceBean_t *bean)
275 {
276 zjni_Object_t *object = (zjni_Object_t *)bean;
277
278 if (object->object == NULL) {
279 object->class = (*env)->FindClass(
280 env, ZFSJNI_PACKAGE_DATA "DiskVirtualDeviceBean");
281
282 object->constructor =
283 (*env)->GetMethodID(env, object->class, "<init>", "()V");
284
285 object->object =
286 (*env)->NewObject(env, object->class, object->constructor);
287 }
288
289 new_LeafVirtualDevice(env, (LeafVirtualDeviceBean_t *)bean);
290 }
291
292 /* Create a SliceVirtualDeviceBean */
293 static void
new_SliceVirtualDeviceBean(JNIEnv * env,SliceVirtualDeviceBean_t * bean)294 new_SliceVirtualDeviceBean(JNIEnv *env, SliceVirtualDeviceBean_t *bean)
295 {
296 zjni_Object_t *object = (zjni_Object_t *)bean;
297
298 if (object->object == NULL) {
299 object->class = (*env)->FindClass(
300 env, ZFSJNI_PACKAGE_DATA "SliceVirtualDeviceBean");
301
302 object->constructor =
303 (*env)->GetMethodID(env, object->class, "<init>", "()V");
304
305 object->object =
306 (*env)->NewObject(env, object->class, object->constructor);
307 }
308
309 new_LeafVirtualDevice(env, (LeafVirtualDeviceBean_t *)bean);
310 }
311
312 /* Create a FileVirtualDeviceBean */
313 static void
new_FileVirtualDeviceBean(JNIEnv * env,FileVirtualDeviceBean_t * bean)314 new_FileVirtualDeviceBean(JNIEnv *env, FileVirtualDeviceBean_t *bean)
315 {
316 zjni_Object_t *object = (zjni_Object_t *)bean;
317
318 if (object->object == NULL) {
319 object->class = (*env)->FindClass(
320 env, ZFSJNI_PACKAGE_DATA "FileVirtualDeviceBean");
321
322 object->constructor =
323 (*env)->GetMethodID(env, object->class, "<init>", "()V");
324
325 object->object =
326 (*env)->NewObject(env, object->class, object->constructor);
327 }
328
329 new_LeafVirtualDevice(env, (LeafVirtualDeviceBean_t *)bean);
330 }
331
332 /* Create a RAIDVirtualDeviceBean */
333 static void
new_RAIDVirtualDeviceBean(JNIEnv * env,RAIDVirtualDeviceBean_t * bean)334 new_RAIDVirtualDeviceBean(JNIEnv *env, RAIDVirtualDeviceBean_t *bean)
335 {
336 zjni_Object_t *object = (zjni_Object_t *)bean;
337
338 if (object->object == NULL) {
339
340 object->class = (*env)->FindClass(
341 env, ZFSJNI_PACKAGE_DATA "RAIDVirtualDeviceBean");
342
343 object->constructor =
344 (*env)->GetMethodID(env, object->class, "<init>", "()V");
345
346 object->object =
347 (*env)->NewObject(env, object->class, object->constructor);
348 }
349
350 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean);
351
352 bean->method_setParity = (*env)->GetMethodID(
353 env, object->class, "setParity", "(J)V");
354 }
355
356 /* Create a MirrorVirtualDeviceBean */
357 static void
new_MirrorVirtualDeviceBean(JNIEnv * env,MirrorVirtualDeviceBean_t * bean)358 new_MirrorVirtualDeviceBean(JNIEnv *env, MirrorVirtualDeviceBean_t *bean)
359 {
360 zjni_Object_t *object = (zjni_Object_t *)bean;
361
362 if (object->object == NULL) {
363 object->class = (*env)->FindClass(
364 env, ZFSJNI_PACKAGE_DATA "MirrorVirtualDeviceBean");
365
366 object->constructor =
367 (*env)->GetMethodID(env, object->class, "<init>", "()V");
368
369 object->object =
370 (*env)->NewObject(env, object->class, object->constructor);
371 }
372
373 new_VirtualDevice(env, (VirtualDeviceBean_t *)bean);
374 }
375
376 static int
populate_ImportablePoolBean(JNIEnv * env,ImportablePoolBean_t * bean,nvlist_t * config)377 populate_ImportablePoolBean(JNIEnv *env, ImportablePoolBean_t *bean,
378 nvlist_t *config)
379 {
380 char *c;
381 char *name;
382 uint64_t guid;
383 uint64_t state;
384 uint64_t version;
385 nvlist_t *devices;
386
387 zjni_Object_t *object = (zjni_Object_t *)bean;
388 PoolStatsBean_t *pool_stats = &(bean->interface_PoolStats);
389 DeviceStatsBean_t *dev_stats = (DeviceStatsBean_t *)pool_stats;
390
391 if (nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME, &name) ||
392 nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) ||
393 nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE, &state) ||
394 nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) ||
395 nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &devices) ||
396 populate_DeviceStatsBean(env, devices, dev_stats, object)) {
397 return (-1);
398 }
399
400 (*env)->CallVoidMethod(env, object->object,
401 bean->method_setName, (*env)->NewStringUTF(env, name));
402
403 (*env)->CallVoidMethod(env, object->object,
404 bean->method_setId, (jlong)guid);
405
406 (*env)->CallVoidMethod(env, object->object,
407 pool_stats->method_setPoolState,
408 zjni_pool_state_to_obj(env, (pool_state_t)state));
409
410 (*env)->CallVoidMethod(env, object->object,
411 pool_stats->method_setPoolStatus,
412 zjni_pool_status_to_obj(env, zpool_import_status(config, &c,
413 NULL)));
414
415 (*env)->CallVoidMethod(env, object->object,
416 pool_stats->method_setPoolVersion, (jlong)version);
417
418 return (0);
419 }
420
421 static int
populate_VirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,VirtualDeviceBean_t * bean)422 populate_VirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
423 nvlist_t *vdev, uint64_t *p_vdev_id, VirtualDeviceBean_t *bean)
424 {
425 int result;
426 uint64_t vdev_id;
427 jstring poolUTF;
428
429 zjni_Object_t *object = (zjni_Object_t *)bean;
430 DeviceStatsBean_t *stats = &(bean->interface_DeviceStats);
431
432 result = populate_DeviceStatsBean(env, vdev, stats, object);
433 if (result != 0) {
434 return (1);
435 }
436
437 /* Set pool name */
438 poolUTF = (*env)->NewStringUTF(env, zpool_get_name(zhp));
439 (*env)->CallVoidMethod(
440 env, object->object, bean->method_setPoolName, poolUTF);
441
442 /* Set parent vdev index */
443 (*env)->CallVoidMethod(
444 env, object->object, bean->method_setParentIndex,
445 p_vdev_id == NULL ? NULL :
446 zjni_long_to_Long(env, *p_vdev_id));
447
448 /* Get index */
449 result = nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_GUID, &vdev_id);
450 if (result != 0) {
451 zjni_throw_exception(env,
452 "could not retrieve virtual device ID (pool %s)",
453 zpool_get_name(zhp));
454 return (1);
455 }
456
457 (*env)->CallVoidMethod(
458 env, object->object, bean->method_setIndex, (jlong)vdev_id);
459
460 return (0);
461 }
462
463 static int
populate_LeafVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,LeafVirtualDeviceBean_t * bean)464 populate_LeafVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
465 nvlist_t *vdev, uint64_t *p_vdev_id, LeafVirtualDeviceBean_t *bean)
466 {
467 return (populate_VirtualDeviceBean(
468 env, zhp, vdev, p_vdev_id, (VirtualDeviceBean_t *)bean));
469 }
470
471 static int
populate_DiskVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,DiskVirtualDeviceBean_t * bean)472 populate_DiskVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
473 nvlist_t *vdev, uint64_t *p_vdev_id, DiskVirtualDeviceBean_t *bean)
474 {
475 char *path;
476 int result = populate_LeafVirtualDeviceBean(
477 env, zhp, vdev, p_vdev_id, (LeafVirtualDeviceBean_t *)bean);
478
479 if (result) {
480 /* Must not call any more Java methods to preserve exception */
481 return (-1);
482 }
483
484 /* Set path */
485 result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path);
486 if (result != 0) {
487 zjni_throw_exception(env,
488 "could not retrieve path from disk virtual device "
489 "(pool %s)", zpool_get_name(zhp));
490 } else {
491
492 regex_t re;
493 regmatch_t matches[2];
494 jstring pathUTF = NULL;
495
496 /* Strip off slice portion of name, if applicable */
497 if (regcomp(&re, "^(/dev/dsk/.*)s[0-9]+$", REG_EXTENDED) == 0) {
498 if (regexec(&re, path, 2, matches, 0) == 0) {
499 regmatch_t *match = matches + 1;
500 if (match->rm_so != -1 && match->rm_eo != -1) {
501 char *tmp = strdup(path);
502 if (tmp != NULL) {
503 char *end = tmp + match->rm_eo;
504 *end = '\0';
505 pathUTF = (*env)->NewStringUTF(
506 env, tmp);
507 free(tmp);
508 }
509 }
510 }
511 regfree(&re);
512 }
513 if (regcomp(&re, "^(/dev/dsk/.*)s[0-9]+/old$", REG_EXTENDED) ==
514 0) {
515 if (regexec(&re, path, 2, matches, 0) == 0) {
516 regmatch_t *match = matches + 1;
517 if (match->rm_so != -1 && match->rm_eo != -1) {
518 char *tmp = strdup(path);
519 if (tmp != NULL) {
520 (void) strcpy(tmp +
521 match->rm_eo, "/old");
522 pathUTF = (*env)->NewStringUTF(
523 env, tmp);
524 free(tmp);
525 }
526 }
527 }
528 regfree(&re);
529 }
530
531 if (pathUTF == NULL) {
532 pathUTF = (*env)->NewStringUTF(env, path);
533 }
534
535 (*env)->CallVoidMethod(env, ((zjni_Object_t *)bean)->object,
536 ((LeafVirtualDeviceBean_t *)bean)->method_setName, pathUTF);
537 }
538
539 return (result != 0);
540 }
541
542 static int
populate_SliceVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,SliceVirtualDeviceBean_t * bean)543 populate_SliceVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
544 nvlist_t *vdev, uint64_t *p_vdev_id, SliceVirtualDeviceBean_t *bean)
545 {
546 char *path;
547 int result = populate_LeafVirtualDeviceBean(
548 env, zhp, vdev, p_vdev_id, (LeafVirtualDeviceBean_t *)bean);
549
550 if (result) {
551 /* Must not call any more Java methods to preserve exception */
552 return (-1);
553 }
554
555 /* Set path */
556 result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path);
557 if (result != 0) {
558 zjni_throw_exception(env,
559 "could not retrieve path from slice virtual device (pool "
560 "%s)", zpool_get_name(zhp));
561 } else {
562
563 jstring pathUTF = (*env)->NewStringUTF(env, path);
564 (*env)->CallVoidMethod(env, ((zjni_Object_t *)bean)->object,
565 ((LeafVirtualDeviceBean_t *)bean)->method_setName,
566 pathUTF);
567 }
568
569 return (result != 0);
570 }
571
572 static int
populate_FileVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,FileVirtualDeviceBean_t * bean)573 populate_FileVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
574 nvlist_t *vdev, uint64_t *p_vdev_id, FileVirtualDeviceBean_t *bean)
575 {
576 char *path;
577 int result = populate_LeafVirtualDeviceBean(
578 env, zhp, vdev, p_vdev_id, (LeafVirtualDeviceBean_t *)bean);
579
580 if (result) {
581 /* Must not call any more Java methods to preserve exception */
582 return (-1);
583 }
584
585 /* Set path */
586 result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_PATH, &path);
587 if (result != 0) {
588 zjni_throw_exception(env,
589 "could not retrieve path from disk virtual device "
590 "(pool %s)", zpool_get_name(zhp));
591 } else {
592
593 jstring pathUTF = (*env)->NewStringUTF(env, path);
594 (*env)->CallVoidMethod(env, ((zjni_Object_t *)bean)->object,
595 ((LeafVirtualDeviceBean_t *)bean)->method_setName, pathUTF);
596 }
597
598 return (result != 0);
599 }
600
601 static int
populate_RAIDVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,RAIDVirtualDeviceBean_t * bean)602 populate_RAIDVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
603 nvlist_t *vdev, uint64_t *p_vdev_id, RAIDVirtualDeviceBean_t *bean)
604 {
605 return (populate_VirtualDeviceBean(env, zhp, vdev, p_vdev_id,
606 (VirtualDeviceBean_t *)bean));
607 }
608
609 static int
populate_MirrorVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id,MirrorVirtualDeviceBean_t * bean)610 populate_MirrorVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
611 nvlist_t *vdev, uint64_t *p_vdev_id, MirrorVirtualDeviceBean_t *bean)
612 {
613 return (populate_VirtualDeviceBean(env, zhp, vdev, p_vdev_id,
614 (VirtualDeviceBean_t *)bean));
615 }
616
617 static jobject
create_ImportablePoolBean(JNIEnv * env,nvlist_t * config)618 create_ImportablePoolBean(JNIEnv *env, nvlist_t *config)
619 {
620 int result;
621 ImportablePoolBean_t bean_obj = {0};
622 ImportablePoolBean_t *bean = &bean_obj;
623
624 /* Construct ImportablePoolBean */
625 new_ImportablePoolBean(env, bean);
626
627 result = populate_ImportablePoolBean(env, bean, config);
628 if (result) {
629 /* Must not call any more Java methods to preserve exception */
630 return (NULL);
631 }
632
633 return (((zjni_Object_t *)bean)->object);
634 }
635
636 static jobject
create_DiskVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id)637 create_DiskVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
638 nvlist_t *vdev, uint64_t *p_vdev_id)
639 {
640 int result;
641 DiskVirtualDeviceBean_t bean_obj = {0};
642 DiskVirtualDeviceBean_t *bean = &bean_obj;
643
644 /* Construct DiskVirtualDeviceBean */
645 new_DiskVirtualDeviceBean(env, bean);
646
647 result = populate_DiskVirtualDeviceBean(
648 env, zhp, vdev, p_vdev_id, bean);
649 if (result) {
650 /* Must not call any more Java methods to preserve exception */
651 return (NULL);
652 }
653
654 return (((zjni_Object_t *)bean)->object);
655 }
656
657 static jobject
create_SliceVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id)658 create_SliceVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
659 nvlist_t *vdev, uint64_t *p_vdev_id)
660 {
661 int result;
662 SliceVirtualDeviceBean_t bean_obj = {0};
663 SliceVirtualDeviceBean_t *bean = &bean_obj;
664
665 /* Construct SliceVirtualDeviceBean */
666 new_SliceVirtualDeviceBean(env, bean);
667
668 result = populate_SliceVirtualDeviceBean(
669 env, zhp, vdev, p_vdev_id, bean);
670 if (result) {
671 /* Must not call any more Java methods to preserve exception */
672 return (NULL);
673 }
674
675 return (((zjni_Object_t *)bean)->object);
676 }
677
678 static jobject
create_FileVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id)679 create_FileVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
680 nvlist_t *vdev, uint64_t *p_vdev_id)
681 {
682 int result;
683 FileVirtualDeviceBean_t bean_obj = {0};
684 FileVirtualDeviceBean_t *bean = &bean_obj;
685
686 /* Construct FileVirtualDeviceBean */
687 new_FileVirtualDeviceBean(env, bean);
688
689 result = populate_FileVirtualDeviceBean(
690 env, zhp, vdev, p_vdev_id, bean);
691 if (result) {
692 /* Must not call any more Java methods to preserve exception */
693 return (NULL);
694 }
695
696 return (((zjni_Object_t *)bean)->object);
697 }
698
699 static jobject
create_RAIDVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id)700 create_RAIDVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
701 nvlist_t *vdev, uint64_t *p_vdev_id)
702 {
703 int result;
704 uint64_t parity;
705 RAIDVirtualDeviceBean_t bean_obj = {0};
706 RAIDVirtualDeviceBean_t *bean = &bean_obj;
707
708 ((zjni_Object_t *)bean)->object = NULL;
709
710 /* Construct RAIDVirtualDeviceBean */
711 new_RAIDVirtualDeviceBean(env, bean);
712
713 /* Set parity bit */
714 result = nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_NPARITY,
715 &parity);
716 if (result) {
717 /* Default to RAID-Z1 in case of error */
718 parity = 1;
719 }
720
721 (*env)->CallVoidMethod(
722 env, ((zjni_Object_t *)bean)->object, bean->method_setParity,
723 (jlong)parity);
724
725
726 result = populate_RAIDVirtualDeviceBean(
727 env, zhp, vdev, p_vdev_id, bean);
728 if (result) {
729 /* Must not call any more Java methods to preserve exception */
730 return (NULL);
731 }
732
733 return (((zjni_Object_t *)bean)->object);
734 }
735
736 static jobject
create_MirrorVirtualDeviceBean(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id)737 create_MirrorVirtualDeviceBean(JNIEnv *env, zpool_handle_t *zhp,
738 nvlist_t *vdev, uint64_t *p_vdev_id)
739 {
740 int result;
741 MirrorVirtualDeviceBean_t bean_obj = {0};
742 MirrorVirtualDeviceBean_t *bean = &bean_obj;
743
744 /* Construct MirrorVirtualDeviceBean */
745 new_MirrorVirtualDeviceBean(env, bean);
746
747 result = populate_MirrorVirtualDeviceBean(
748 env, zhp, vdev, p_vdev_id, bean);
749 if (result) {
750 /* Must not call any more Java methods to preserve exception */
751 return (NULL);
752 }
753
754 return (((zjni_Object_t *)bean)->object);
755 }
756
757 static char *
find_field(const zjni_field_mapping_t * mapping,int value)758 find_field(const zjni_field_mapping_t *mapping, int value)
759 {
760 int i;
761 for (i = 0; mapping[i].name != NULL; i++) {
762 if (value == mapping[i].value) {
763 return (mapping[i].name);
764 }
765 }
766 return (NULL);
767 }
768
769 /*
770 * Converts a vdev_state_t to a Java DeviceStats$DeviceState object.
771 */
772 static jobject
zjni_vdev_state_to_obj(JNIEnv * env,vdev_state_t state)773 zjni_vdev_state_to_obj(JNIEnv *env, vdev_state_t state)
774 {
775 return (zjni_int_to_enum(env, state,
776 ZFSJNI_PACKAGE_DATA "DeviceStats$DeviceState",
777 "VDEV_STATE_UNKNOWN", vdev_state_map));
778 }
779
780 /*
781 * Converts a vdev_aux_t to a Java DeviceStats$DeviceStatus object.
782 */
783 static jobject
zjni_vdev_aux_to_obj(JNIEnv * env,vdev_aux_t aux)784 zjni_vdev_aux_to_obj(JNIEnv *env, vdev_aux_t aux)
785 {
786 return (zjni_int_to_enum(env, aux,
787 ZFSJNI_PACKAGE_DATA "DeviceStats$DeviceStatus",
788 "VDEV_AUX_NONE", vdev_aux_map));
789 }
790
791 /*
792 * Package-private functions
793 */
794
795 /* Create a DeviceStatsBean */
796 void
new_DeviceStats(JNIEnv * env,DeviceStatsBean_t * bean,zjni_Object_t * object)797 new_DeviceStats(JNIEnv *env, DeviceStatsBean_t *bean, zjni_Object_t *object)
798 {
799 bean->method_setSize = (*env)->GetMethodID(
800 env, object->class, "setSize", "(J)V");
801
802 bean->method_setReplacementSize = (*env)->GetMethodID(
803 env, object->class, "setReplacementSize", "(J)V");
804
805 bean->method_setUsed = (*env)->GetMethodID(
806 env, object->class, "setUsed", "(J)V");
807
808 bean->method_setReadBytes = (*env)->GetMethodID(
809 env, object->class, "setReadBytes", "(J)V");
810
811 bean->method_setWriteBytes = (*env)->GetMethodID(
812 env, object->class, "setWriteBytes", "(J)V");
813
814 bean->method_setReadOperations = (*env)->GetMethodID(
815 env, object->class, "setReadOperations", "(J)V");
816
817 bean->method_setWriteOperations = (*env)->GetMethodID(
818 env, object->class, "setWriteOperations", "(J)V");
819
820 bean->method_setReadErrors = (*env)->GetMethodID(
821 env, object->class, "setReadErrors", "(J)V");
822
823 bean->method_setWriteErrors = (*env)->GetMethodID(
824 env, object->class, "setWriteErrors", "(J)V");
825
826 bean->method_setChecksumErrors = (*env)->GetMethodID(
827 env, object->class, "setChecksumErrors", "(J)V");
828
829 bean->method_setDeviceState = (*env)->GetMethodID(
830 env, object->class, "setDeviceState",
831 "(L" ZFSJNI_PACKAGE_DATA "DeviceStats$DeviceState;)V");
832
833 bean->method_setDeviceStatus = (*env)->GetMethodID(
834 env, object->class, "setDeviceStatus",
835 "(L" ZFSJNI_PACKAGE_DATA "DeviceStats$DeviceStatus;)V");
836 }
837
838 /* Create a PoolStatsBean */
839 void
new_PoolStats(JNIEnv * env,PoolStatsBean_t * bean,zjni_Object_t * object)840 new_PoolStats(JNIEnv *env, PoolStatsBean_t *bean, zjni_Object_t *object)
841 {
842 new_DeviceStats(env, (DeviceStatsBean_t *)bean, object);
843
844 bean->method_setPoolState = (*env)->GetMethodID(
845 env, object->class, "setPoolState",
846 "(L" ZFSJNI_PACKAGE_DATA "PoolStats$PoolState;)V");
847
848 bean->method_setPoolStatus = (*env)->GetMethodID(
849 env, object->class, "setPoolStatus",
850 "(L" ZFSJNI_PACKAGE_DATA "PoolStats$PoolStatus;)V");
851
852 bean->method_setPoolVersion = (*env)->GetMethodID(
853 env, object->class, "setPoolVersion", "(J)V");
854 }
855
856 /*
857 * Gets the root vdev (an nvlist_t *) for the given pool.
858 */
859 nvlist_t *
zjni_get_root_vdev(zpool_handle_t * zhp)860 zjni_get_root_vdev(zpool_handle_t *zhp)
861 {
862 nvlist_t *root = NULL;
863
864 if (zhp != NULL) {
865 nvlist_t *attrs = zpool_get_config(zhp, NULL);
866
867 if (attrs != NULL) {
868 int result = nvlist_lookup_nvlist(
869 attrs, ZPOOL_CONFIG_VDEV_TREE, &root);
870 if (result != 0) {
871 root = NULL;
872 }
873 }
874 }
875
876 return (root);
877 }
878
879 /*
880 * Gets the vdev (an nvlist_t *) with the given vdev_id, below the
881 * given vdev. If the given vdev is NULL, all vdevs within the given
882 * pool are searched.
883 *
884 * If p_vdev_id is not NULL, it will be set to the ID of the parent
885 * vdev, if any, or to vdev_id_to_find if the searched-for vdev is a
886 * toplevel vdev.
887 */
888 nvlist_t *
zjni_get_vdev(zpool_handle_t * zhp,nvlist_t * vdev_parent,uint64_t vdev_id_to_find,uint64_t * p_vdev_id)889 zjni_get_vdev(zpool_handle_t *zhp, nvlist_t *vdev_parent,
890 uint64_t vdev_id_to_find, uint64_t *p_vdev_id)
891 {
892 int result;
893 uint64_t id = vdev_id_to_find;
894
895 /* Was a vdev specified? */
896 if (vdev_parent == NULL) {
897 /* No -- retrieve the top-level pool vdev */
898 vdev_parent = zjni_get_root_vdev(zhp);
899 } else {
900 /* Get index of this vdev and compare with vdev_id_to_find */
901 result = nvlist_lookup_uint64(
902 vdev_parent, ZPOOL_CONFIG_GUID, &id);
903 if (result == 0 && id == vdev_id_to_find) {
904 return (vdev_parent);
905 }
906 }
907
908 if (vdev_parent != NULL) {
909
910 nvlist_t **children;
911 uint_t nelem = 0;
912
913 /* Get the vdevs under this vdev */
914 result = nvlist_lookup_nvlist_array(
915 vdev_parent, ZPOOL_CONFIG_CHILDREN, &children, &nelem);
916
917 if (result == 0) {
918
919 int i;
920 nvlist_t *child;
921
922 /* For each vdev child... */
923 for (i = 0; i < nelem; i++) {
924 if (p_vdev_id != NULL) {
925 /* Save parent vdev id */
926 *p_vdev_id = id;
927 }
928
929 child = zjni_get_vdev(zhp, children[i],
930 vdev_id_to_find, p_vdev_id);
931 if (child != NULL) {
932 return (child);
933 }
934 }
935 }
936 }
937
938 return (NULL);
939 }
940
941 jobject
zjni_get_VirtualDevice_from_vdev(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev,uint64_t * p_vdev_id)942 zjni_get_VirtualDevice_from_vdev(JNIEnv *env, zpool_handle_t *zhp,
943 nvlist_t *vdev, uint64_t *p_vdev_id)
944 {
945 jobject obj = NULL;
946 char *type = NULL;
947 int result = nvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE, &type);
948
949 if (result == 0) {
950 if (strcmp(type, VDEV_TYPE_DISK) == 0) {
951 uint64_t wholedisk;
952 if (nvlist_lookup_uint64(vdev, ZPOOL_CONFIG_WHOLE_DISK,
953 &wholedisk) == 0 && wholedisk) {
954 obj = create_DiskVirtualDeviceBean(
955 env, zhp, vdev, p_vdev_id);
956 } else {
957 obj = create_SliceVirtualDeviceBean(
958 env, zhp, vdev, p_vdev_id);
959 }
960 } else if (strcmp(type, VDEV_TYPE_FILE) == 0) {
961 obj = create_FileVirtualDeviceBean(
962 env, zhp, vdev, p_vdev_id);
963 } else if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
964 obj = create_RAIDVirtualDeviceBean(
965 env, zhp, vdev, p_vdev_id);
966 } else if (strcmp(type, VDEV_TYPE_MIRROR) == 0) {
967 obj = create_MirrorVirtualDeviceBean(
968 env, zhp, vdev, p_vdev_id);
969 } else if (strcmp(type, VDEV_TYPE_REPLACING) == 0) {
970
971 /* Get the vdevs under this vdev */
972 nvlist_t **children;
973 uint_t nelem = 0;
974 int result = nvlist_lookup_nvlist_array(
975 vdev, ZPOOL_CONFIG_CHILDREN, &children, &nelem);
976
977 if (result == 0 && nelem > 0) {
978
979 /* Get last vdev child (replacement device) */
980 nvlist_t *child = children[nelem - 1];
981
982 obj = zjni_get_VirtualDevice_from_vdev(env,
983 zhp, child, p_vdev_id);
984 }
985 }
986 }
987
988 return (obj);
989 }
990
991 jobject
zjni_get_VirtualDevices_from_vdev(JNIEnv * env,zpool_handle_t * zhp,nvlist_t * vdev_parent,uint64_t * p_vdev_id)992 zjni_get_VirtualDevices_from_vdev(JNIEnv *env, zpool_handle_t *zhp,
993 nvlist_t *vdev_parent, uint64_t *p_vdev_id)
994 {
995 /* Create an array list for the vdevs */
996 zjni_ArrayList_t list_class = {0};
997 zjni_ArrayList_t *list_class_p = &list_class;
998 zjni_new_ArrayList(env, list_class_p);
999
1000 /* Was a vdev specified? */
1001 if (vdev_parent == NULL) {
1002 /* No -- retrieve the top-level pool vdev */
1003 vdev_parent = zjni_get_root_vdev(zhp);
1004 }
1005
1006 if (vdev_parent != NULL) {
1007
1008 /* Get the vdevs under this vdev */
1009 nvlist_t **children;
1010 uint_t nelem = 0;
1011 int result = nvlist_lookup_nvlist_array(
1012 vdev_parent, ZPOOL_CONFIG_CHILDREN, &children, &nelem);
1013
1014 if (result == 0) {
1015
1016 /* For each vdev child... */
1017 int i;
1018 for (i = 0; i < nelem; i++) {
1019 nvlist_t *child = children[i];
1020
1021 /* Create a Java object from this vdev */
1022 jobject obj =
1023 zjni_get_VirtualDevice_from_vdev(env,
1024 zhp, child, p_vdev_id);
1025
1026 if ((*env)->ExceptionOccurred(env) != NULL) {
1027 /*
1028 * Must not call any more Java methods
1029 * to preserve exception
1030 */
1031 return (NULL);
1032 }
1033
1034 if (obj != NULL) {
1035 /* Add child to child vdev list */
1036 (*env)->CallBooleanMethod(env,
1037 ((zjni_Object_t *)
1038 list_class_p)->object,
1039 ((zjni_Collection_t *)
1040 list_class_p)->method_add, obj);
1041 }
1042 }
1043 }
1044 }
1045
1046 return (zjni_Collection_to_array(
1047 env, (zjni_Collection_t *)list_class_p,
1048 ZFSJNI_PACKAGE_DATA "VirtualDevice"));
1049 }
1050
1051 int
zjni_create_add_ImportablePool(nvlist_t * config,void * data)1052 zjni_create_add_ImportablePool(nvlist_t *config, void *data)
1053 {
1054
1055 JNIEnv *env = ((zjni_ArrayCallbackData_t *)data)->env;
1056 zjni_Collection_t *list = ((zjni_ArrayCallbackData_t *)data)->list;
1057
1058 /* Construct ImportablePool object */
1059 jobject bean = create_ImportablePoolBean(env, config);
1060 if (bean == NULL) {
1061 return (-1);
1062 }
1063
1064 /* Add bean to list */
1065 (*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
1066 ((zjni_Collection_t *)list)->method_add, bean);
1067
1068 return (0);
1069 }
1070
1071 int
populate_DeviceStatsBean(JNIEnv * env,nvlist_t * vdev,DeviceStatsBean_t * bean,zjni_Object_t * object)1072 populate_DeviceStatsBean(JNIEnv *env, nvlist_t *vdev,
1073 DeviceStatsBean_t *bean, zjni_Object_t *object)
1074 {
1075 uint_t c;
1076 vdev_stat_t *vs;
1077
1078 int result = nvlist_lookup_uint64_array(
1079 vdev, ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &c);
1080 if (result != 0) {
1081 zjni_throw_exception(env,
1082 "could not retrieve virtual device statistics");
1083 return (1);
1084 }
1085
1086 (*env)->CallVoidMethod(env, object->object,
1087 bean->method_setUsed, (jlong)vs->vs_alloc);
1088
1089 (*env)->CallVoidMethod(env, object->object,
1090 bean->method_setSize, (jlong)vs->vs_space);
1091
1092 (*env)->CallVoidMethod(env, object->object,
1093 bean->method_setReplacementSize, (jlong)vs->vs_rsize);
1094
1095 (*env)->CallVoidMethod(env, object->object,
1096 bean->method_setReadBytes, (jlong)vs->vs_bytes[ZIO_TYPE_READ]);
1097
1098 (*env)->CallVoidMethod(env, object->object,
1099 bean->method_setWriteBytes, (jlong)vs->vs_bytes[ZIO_TYPE_WRITE]);
1100
1101 (*env)->CallVoidMethod(env, object->object,
1102 bean->method_setReadOperations, (jlong)vs->vs_ops[ZIO_TYPE_READ]);
1103
1104 (*env)->CallVoidMethod(env, object->object,
1105 bean->method_setWriteOperations, (jlong)vs->vs_ops[ZIO_TYPE_WRITE]);
1106
1107 (*env)->CallVoidMethod(env, object->object,
1108 bean->method_setReadErrors, (jlong)vs->vs_read_errors);
1109
1110 (*env)->CallVoidMethod(env, object->object,
1111 bean->method_setWriteErrors, (jlong)vs->vs_write_errors);
1112
1113 (*env)->CallVoidMethod(env, object->object,
1114 bean->method_setChecksumErrors, (jlong)vs->vs_checksum_errors);
1115
1116 (*env)->CallVoidMethod(env, object->object,
1117 bean->method_setDeviceState,
1118 zjni_vdev_state_to_obj(env, vs->vs_state));
1119
1120 (*env)->CallVoidMethod(env, object->object,
1121 bean->method_setDeviceStatus,
1122 zjni_vdev_aux_to_obj(env, vs->vs_aux));
1123
1124 return (0);
1125 }
1126
1127 /*
1128 * Converts a pool_state_t to a Java PoolStats$PoolState object.
1129 */
1130 jobject
zjni_pool_state_to_obj(JNIEnv * env,pool_state_t state)1131 zjni_pool_state_to_obj(JNIEnv *env, pool_state_t state)
1132 {
1133 return (zjni_int_to_enum(env, state,
1134 ZFSJNI_PACKAGE_DATA "PoolStats$PoolState",
1135 "POOL_STATE_ACTIVE", pool_state_map));
1136 }
1137
1138 /*
1139 * Converts a zpool_status_t to a Java PoolStats$PoolStatus object.
1140 */
1141 jobject
zjni_pool_status_to_obj(JNIEnv * env,zpool_status_t status)1142 zjni_pool_status_to_obj(JNIEnv *env, zpool_status_t status)
1143 {
1144 return (zjni_int_to_enum(env, status,
1145 ZFSJNI_PACKAGE_DATA "PoolStats$PoolStatus",
1146 "ZPOOL_STATUS_OK", zpool_status_map));
1147 }
1148
1149 /*
1150 * Extern functions
1151 */
1152
1153 /*
1154 * Iterates through each importable pool on the system. For each
1155 * importable pool, runs the given function with the given void as the
1156 * last arg.
1157 */
1158 int
zjni_ipool_iter(int argc,char ** argv,zjni_ipool_iter_f func,void * data)1159 zjni_ipool_iter(int argc, char **argv, zjni_ipool_iter_f func, void *data)
1160 {
1161 nvlist_t *pools;
1162 importargs_t iarg = { 0 };
1163
1164 iarg.paths = argc;
1165 iarg.path = argv;
1166 iarg.can_be_active = B_TRUE;
1167
1168 pools = zpool_search_import(g_zfs, &iarg, &libzfs_config_ops);
1169
1170 if (pools != NULL) {
1171 nvpair_t *elem = NULL;
1172
1173 while ((elem = nvlist_next_nvpair(pools, elem)) != NULL) {
1174 nvlist_t *config;
1175
1176 if (nvpair_value_nvlist(elem, &config) != 0 ||
1177 func(config, data)) {
1178 return (-1);
1179 }
1180 }
1181 }
1182
1183 return (0);
1184 }
1185
1186 char *
zjni_vdev_state_to_str(vdev_state_t state)1187 zjni_vdev_state_to_str(vdev_state_t state)
1188 {
1189 return (find_field(vdev_state_map, state));
1190 }
1191
1192 char *
zjni_vdev_aux_to_str(vdev_aux_t aux)1193 zjni_vdev_aux_to_str(vdev_aux_t aux)
1194 {
1195 return (find_field(vdev_aux_map, aux));
1196 }
1197
1198 char *
zjni_pool_state_to_str(pool_state_t state)1199 zjni_pool_state_to_str(pool_state_t state)
1200 {
1201 return (find_field(pool_state_map, state));
1202 }
1203
1204 char *
zjni_pool_status_to_str(zpool_status_t status)1205 zjni_pool_status_to_str(zpool_status_t status)
1206 {
1207 return (find_field(zpool_status_map, status));
1208 }
1209