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 #include "libzfs_jni_disk.h"
28
29 /*
30 * Function prototypes
31 */
32
33 static jobject create_DiskDeviceBean(JNIEnv *, dmgt_disk_t *);
34 static jobject get_SliceUsage_Use(JNIEnv *, char *);
35 static jobject create_SliceUsage(JNIEnv *env, dmgt_slice_t *sp);
36 static jobject create_SliceDeviceBean(JNIEnv *env, dmgt_slice_t *sp);
37 static jobjectArray create_SliceDeviceBean_array(JNIEnv *, dmgt_slice_t **);
38
39 /*
40 * Static functions
41 */
42
43 static jobject
create_DiskDeviceBean(JNIEnv * env,dmgt_disk_t * dp)44 create_DiskDeviceBean(JNIEnv *env, dmgt_disk_t *dp)
45 {
46 jobject disk = NULL;
47
48 int naliases = zjni_count_elements((void **)dp->aliases);
49 jobjectArray aliases = zjni_c_string_array_to_java(
50 env, dp->aliases, naliases);
51 if (aliases != NULL) {
52 jobjectArray slices = create_SliceDeviceBean_array(env,
53 dp->slices);
54 if (slices != NULL) {
55 jstring nameUTF = (*env)->NewStringUTF(env, dp->name);
56
57 jboolean in_use = dp->in_use ? JNI_TRUE : JNI_FALSE;
58
59 jclass class_DiskDeviceBean = (*env)->FindClass(
60 env, ZFSJNI_PACKAGE_DATA "DiskDeviceBean");
61
62 jmethodID constructor =
63 (*env)->GetMethodID(env, class_DiskDeviceBean,
64 "<init>",
65 "(JLjava/lang/String;[Ljava/lang/String;[L"
66 ZFSJNI_PACKAGE_DATA "SliceDeviceBean;Z)V");
67
68 disk = (*env)->NewObject(env, class_DiskDeviceBean,
69 constructor, dp->size, nameUTF, aliases, slices,
70 in_use);
71 }
72 }
73
74 return (disk);
75 }
76
77 static jobject
get_SliceUsage_Use(JNIEnv * env,char * dm_usage)78 get_SliceUsage_Use(JNIEnv *env, char *dm_usage)
79 {
80 jobject enumVal = NULL;
81
82 if (dm_usage != NULL) {
83 jclass class_SliceUsage_Use = (*env)->FindClass(
84 env, ZFSJNI_PACKAGE_DATA "SliceUsage$Use");
85
86 jfieldID id = (*env)->GetStaticFieldID(env,
87 class_SliceUsage_Use,
88 dm_usage, "L" ZFSJNI_PACKAGE_DATA "SliceUsage$Use;");
89
90 if (id != NULL) {
91 /* Retrieve the proper SliceUsage$Use enum value */
92 enumVal = (*env)->GetStaticObjectField(
93 env, class_SliceUsage_Use, id);
94 #ifdef DEBUG
95 } else {
96 (void) fprintf(stderr, "Unknown slice usage: %s\n",
97 dm_usage);
98 #endif /* DEBUG */
99 }
100 }
101
102 return (enumVal);
103 }
104
105 static jobject
create_SliceUsage(JNIEnv * env,dmgt_slice_t * sp)106 create_SliceUsage(JNIEnv *env, dmgt_slice_t *sp)
107 {
108 jobject usage = NULL;
109 if (sp->used_name != NULL) {
110 jobject use = get_SliceUsage_Use(env, sp->used_name);
111
112 if (use != NULL) {
113 jstring usedByUTF =
114 (*env)->NewStringUTF(env, sp->used_by);
115
116 jclass class_SliceUsage = (*env)->FindClass(
117 env, ZFSJNI_PACKAGE_DATA "SliceUsage");
118
119 jmethodID constructor =
120 (*env)->GetMethodID(env, class_SliceUsage, "<init>",
121 "(L" ZFSJNI_PACKAGE_DATA
122 "SliceUsage$Use;Ljava/lang/String;)V");
123
124 usage = (*env)->NewObject(env,
125 class_SliceUsage, constructor, use, usedByUTF);
126 }
127 }
128
129 return (usage);
130 }
131
132 static jobject
create_SliceDeviceBean(JNIEnv * env,dmgt_slice_t * sp)133 create_SliceDeviceBean(JNIEnv *env, dmgt_slice_t *sp)
134 {
135 jobject slice = NULL;
136
137 /* May be NULL if unused */
138 jobject usage = create_SliceUsage(env, sp);
139
140 jstring nameUTF = (*env)->NewStringUTF(env, sp->name);
141
142 jclass class_SliceDeviceBean = (*env)->FindClass(
143 env, ZFSJNI_PACKAGE_DATA "SliceDeviceBean");
144
145 jmethodID constructor =
146 (*env)->GetMethodID(env, class_SliceDeviceBean, "<init>",
147 "(JLjava/lang/String;JL" ZFSJNI_PACKAGE_DATA "SliceUsage;)V");
148
149 slice = (*env)->NewObject(env, class_SliceDeviceBean,
150 constructor, sp->size, nameUTF, sp->start, usage);
151
152 return (slice);
153 }
154
155 static jobjectArray
create_SliceDeviceBean_array(JNIEnv * env,dmgt_slice_t ** slices)156 create_SliceDeviceBean_array(JNIEnv *env, dmgt_slice_t **slices)
157 {
158 /* Create an array list */
159 zjni_ArrayList_t list_class = {0};
160 zjni_ArrayList_t *list_class_p = &list_class;
161 zjni_new_ArrayList(env, list_class_p);
162
163 if (slices != NULL) {
164 int i;
165 for (i = 0; slices[i] != NULL; i++) {
166 dmgt_slice_t *slice = slices[i];
167 jobject obj;
168 obj = create_SliceDeviceBean(env, slice);
169 if (obj != NULL) {
170 (*env)->CallBooleanMethod(env,
171 ((zjni_Object_t *)list_class_p)->object,
172 ((zjni_Collection_t *)list_class_p)->
173 method_add, obj);
174 }
175 }
176 }
177
178 return (zjni_Collection_to_array(
179 env, (zjni_Collection_t *)list_class_p,
180 ZFSJNI_PACKAGE_DATA "SliceDeviceBean"));
181 }
182
183 /*
184 * Package-private functions
185 */
186
187 int
zjni_create_add_DiskDevice(dmgt_disk_t * dp,void * data)188 zjni_create_add_DiskDevice(dmgt_disk_t *dp, void *data)
189 {
190 JNIEnv *env = ((zjni_ArrayCallbackData_t *)data)->env;
191 zjni_Collection_t *list = ((zjni_ArrayCallbackData_t *)data)->list;
192 jobject disk = create_DiskDeviceBean(env, dp);
193
194 /* Add disk to zjni_ArrayList */
195 (*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
196 ((zjni_Collection_t *)list)->method_add, disk);
197
198 return (0);
199 }
200