1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include "libzfs_jni_disk.h"
30
31 /*
32 * Function prototypes
33 */
34
35 static jobject create_DiskDeviceBean(JNIEnv *, dmgt_disk_t *);
36 static jobject get_SliceUsage_Use(JNIEnv *, char *);
37 static jobject create_SliceUsage(JNIEnv *env, dmgt_slice_t *sp);
38 static jobject create_SliceDeviceBean(JNIEnv *env, dmgt_slice_t *sp);
39 static jobjectArray create_SliceDeviceBean_array(JNIEnv *, dmgt_slice_t **);
40
41 /*
42 * Static functions
43 */
44
45 static jobject
create_DiskDeviceBean(JNIEnv * env,dmgt_disk_t * dp)46 create_DiskDeviceBean(JNIEnv *env, dmgt_disk_t *dp)
47 {
48 jobject disk = NULL;
49
50 int naliases = zjni_count_elements((void **)dp->aliases);
51 jobjectArray aliases = zjni_c_string_array_to_java(
52 env, dp->aliases, naliases);
53 if (aliases != NULL) {
54 jobjectArray slices = create_SliceDeviceBean_array(env,
55 dp->slices);
56 if (slices != NULL) {
57 jstring nameUTF = (*env)->NewStringUTF(env, dp->name);
58
59 jboolean in_use = dp->in_use ? JNI_TRUE : JNI_FALSE;
60
61 jclass class_DiskDeviceBean = (*env)->FindClass(
62 env, ZFSJNI_PACKAGE_DATA "DiskDeviceBean");
63
64 jmethodID constructor =
65 (*env)->GetMethodID(env, class_DiskDeviceBean,
66 "<init>",
67 "(JLjava/lang/String;[Ljava/lang/String;[L"
68 ZFSJNI_PACKAGE_DATA "SliceDeviceBean;Z)V");
69
70 disk = (*env)->NewObject(env, class_DiskDeviceBean,
71 constructor, dp->size, nameUTF, aliases, slices,
72 in_use);
73 }
74 }
75
76 return (disk);
77 }
78
79 static jobject
get_SliceUsage_Use(JNIEnv * env,char * dm_usage)80 get_SliceUsage_Use(JNIEnv *env, char *dm_usage)
81 {
82 jobject enumVal = NULL;
83
84 if (dm_usage != NULL) {
85 jclass class_SliceUsage_Use = (*env)->FindClass(
86 env, ZFSJNI_PACKAGE_DATA "SliceUsage$Use");
87
88 jfieldID id = (*env)->GetStaticFieldID(env,
89 class_SliceUsage_Use,
90 dm_usage, "L" ZFSJNI_PACKAGE_DATA "SliceUsage$Use;");
91
92 if (id != NULL) {
93 /* Retrieve the proper SliceUsage$Use enum value */
94 enumVal = (*env)->GetStaticObjectField(
95 env, class_SliceUsage_Use, id);
96 #ifdef DEBUG
97 } else {
98 (void) fprintf(stderr, "Unknown slice usage: %s\n",
99 dm_usage);
100 #endif /* DEBUG */
101 }
102 }
103
104 return (enumVal);
105 }
106
107 static jobject
create_SliceUsage(JNIEnv * env,dmgt_slice_t * sp)108 create_SliceUsage(JNIEnv *env, dmgt_slice_t *sp)
109 {
110 jobject usage = NULL;
111 if (sp->used_name != NULL) {
112 jobject use = get_SliceUsage_Use(env, sp->used_name);
113
114 if (use != NULL) {
115 jstring usedByUTF =
116 (*env)->NewStringUTF(env, sp->used_by);
117
118 jclass class_SliceUsage = (*env)->FindClass(
119 env, ZFSJNI_PACKAGE_DATA "SliceUsage");
120
121 jmethodID constructor =
122 (*env)->GetMethodID(env, class_SliceUsage, "<init>",
123 "(L" ZFSJNI_PACKAGE_DATA
124 "SliceUsage$Use;Ljava/lang/String;)V");
125
126 usage = (*env)->NewObject(env,
127 class_SliceUsage, constructor, use, usedByUTF);
128 }
129 }
130
131 return (usage);
132 }
133
134 static jobject
create_SliceDeviceBean(JNIEnv * env,dmgt_slice_t * sp)135 create_SliceDeviceBean(JNIEnv *env, dmgt_slice_t *sp)
136 {
137 jobject slice = NULL;
138
139 /* May be NULL if unused */
140 jobject usage = create_SliceUsage(env, sp);
141
142 jstring nameUTF = (*env)->NewStringUTF(env, sp->name);
143
144 jclass class_SliceDeviceBean = (*env)->FindClass(
145 env, ZFSJNI_PACKAGE_DATA "SliceDeviceBean");
146
147 jmethodID constructor =
148 (*env)->GetMethodID(env, class_SliceDeviceBean, "<init>",
149 "(JLjava/lang/String;JL" ZFSJNI_PACKAGE_DATA "SliceUsage;)V");
150
151 slice = (*env)->NewObject(env, class_SliceDeviceBean,
152 constructor, sp->size, nameUTF, sp->start, usage);
153
154 return (slice);
155 }
156
157 static jobjectArray
create_SliceDeviceBean_array(JNIEnv * env,dmgt_slice_t ** slices)158 create_SliceDeviceBean_array(JNIEnv *env, dmgt_slice_t **slices)
159 {
160 /* Create an array list */
161 zjni_ArrayList_t list_class = {0};
162 zjni_ArrayList_t *list_class_p = &list_class;
163 zjni_new_ArrayList(env, list_class_p);
164
165 if (slices != NULL) {
166 int i;
167 for (i = 0; slices[i] != NULL; i++) {
168 dmgt_slice_t *slice = slices[i];
169 jobject obj;
170 obj = create_SliceDeviceBean(env, slice);
171 if (obj != NULL) {
172 (*env)->CallBooleanMethod(env,
173 ((zjni_Object_t *)list_class_p)->object,
174 ((zjni_Collection_t *)list_class_p)->
175 method_add, obj);
176 }
177 }
178 }
179
180 return (zjni_Collection_to_array(
181 env, (zjni_Collection_t *)list_class_p,
182 ZFSJNI_PACKAGE_DATA "SliceDeviceBean"));
183 }
184
185 /*
186 * Package-private functions
187 */
188
189 int
zjni_create_add_DiskDevice(dmgt_disk_t * dp,void * data)190 zjni_create_add_DiskDevice(dmgt_disk_t *dp, void *data)
191 {
192 JNIEnv *env = ((zjni_ArrayCallbackData_t *)data)->env;
193 zjni_Collection_t *list = ((zjni_ArrayCallbackData_t *)data)->list;
194 jobject disk = create_DiskDeviceBean(env, dp);
195
196 /* Add disk to zjni_ArrayList */
197 (*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
198 ((zjni_Collection_t *)list)->method_add, disk);
199
200 return (0);
201 }
202