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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
26 */
27
28 #include <fcntl.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <stddef.h>
32 #include <stdlib.h>
33 #include <dirent.h>
34 #include <dlfcn.h>
35 #include <link.h>
36 #include <strings.h>
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <sys/mnttab.h>
40 #include <config_admin.h>
41 #include <sys/param.h>
42 #include <libintl.h>
43 #include <libdevinfo.h>
44 #include <raidcfg.h>
45 #include <thread.h>
46 #include <synch.h>
47
48 #ifndef TEXT_DOMAIN
49 #define TEXT_DOMAIN "SYS_TEST"
50 #endif
51
52 #define HASH_SLOTS 16
53 #define HANDLER_SLOTS 256
54
55 /*
56 * Raid object status;
57 */
58 #define OBJ_STATUS_CMD_CLEAN -1
59 #define OBJ_STATUS_OPENED 1
60 #define OBJ_STATUS_SCANCOMP 1 << 1
61
62 #if defined(__sparcv9)
63 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg/sparcv9"
64 #elif defined(__amd64)
65 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg/amd64"
66 #else
67 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg"
68 #endif
69
70 /*
71 * Basic types
72 */
73 typedef int raid_obj_id_t;
74 typedef int raid_obj_status_t;
75
76 /*
77 * Data structures used for object maintennance
78 */
79 typedef struct {
80 void *head;
81 void *tail;
82 size_t offset; /* offset of double-linked element (raid_list_el_t) */
83 /* in the linked data structures (objects) */
84 } raid_list_t;
85
86 typedef struct {
87 void *prev;
88 void *next;
89 } raid_list_el_t;
90
91 typedef struct {
92 raid_obj_id_t obj_id_cnt; /* id 0 is reserved */
93 size_t slots; /* How many lists linked by *table */
94 raid_list_t *table;
95 } raid_obj_tab_t;
96
97 /*
98 * Object type structure containing function pointers;
99 */
100 typedef struct {
101 int (*compnum)(raid_obj_tab_t *, raid_obj_id_t, raid_obj_type_id_t);
102 int (*complist)(raid_obj_tab_t *, raid_obj_id_t, int, raid_obj_id_t *,
103 raid_obj_type_id_t);
104 int (*get_attr)(raid_obj_tab_t *, raid_obj_id_t);
105 int (*set_attr)(raid_obj_tab_t *, raid_obj_id_t, uint32_t, uint32_t *,
106 char **);
107 int (*act)(raid_obj_tab_t *, raid_obj_id_t, uint32_t, void *, char **);
108 int (*create_obj)(raid_obj_tab_t *, raid_obj_id_t, int,
109 raid_obj_id_t *, char **);
110 int (*delete_obj)(raid_obj_tab_t *, raid_obj_id_t, char **);
111 int (*bind_obj)(raid_obj_tab_t *, raid_obj_id_t *, char **);
112 int (*unbind_obj)(raid_obj_tab_t *, raid_obj_id_t *, char **);
113 } raid_obj_op_t;
114
115 /*
116 * Common object data structure
117 */
118 typedef struct {
119 raid_list_el_t el; /* double-links */
120
121 raid_obj_type_id_t obj_type_id;
122 raid_obj_id_t obj_id;
123 raid_obj_status_t status;
124
125 raid_obj_id_t container;
126 raid_obj_id_t sibling;
127 raid_obj_id_t component;
128
129 void *data; /* Pointer to attribute structure */
130 raid_obj_handle_t handle;
131 } raid_obj_t;
132
133 /*
134 * Definition about handle
135 */
136 typedef struct {
137 uint32_t next;
138 uint32_t type;
139 uint32_t controller_id;
140 uint32_t array_id;
141 uint32_t disk_id;
142 uint64_t seq_id;
143 uint32_t task_id;
144 uint32_t prop_id;
145 uint32_t fd; /* Only for controller */
146 raid_lib_t *raid_lib; /* Only for controller */
147 } handle_attr_t;
148
149 #define LIST_OBJ_TO_EL(list, obj) \
150 ((void *)((char *)(obj) + (list)->offset))
151 #define OBJ_TAB_SLOT(tab, id) \
152 ((tab)->table + ((id)%(tab)->slots))
153
154 #pragma init(raidcfg_init)
155 #pragma fini(raidcfg_fini)
156
157 /*
158 * Function prototypes
159 */
160 static int intcompare(const void *p1, const void *p2);
161 static uint64_t raid_space_noalign(raid_obj_tab_t *, uint32_t, int,
162 raid_obj_id_t *, arraypart_attr_t *);
163 static int raid_handle_init();
164 static void raid_handle_fini();
165 static raid_obj_handle_t raid_handle_new(raid_obj_type_id_t);
166 static void raid_handle_delete(raid_obj_handle_t);
167 static void raid_handle_delete_controller_comp(uint32_t);
168 static raid_obj_id_t raid_handle_to_obj(raid_obj_tab_t *,
169 raid_obj_handle_t);
170 static raid_obj_handle_t raid_obj_to_handle(raid_obj_tab_t *,
171 raid_obj_id_t);
172 static raid_lib_t *raid_obj_get_lib(raid_obj_tab_t *, raid_obj_id_t);
173 static int raid_obj_set_lib(raid_obj_tab_t *, raid_obj_id_t, raid_lib_t *);
174 static int raid_obj_get_fd(raid_obj_tab_t *, raid_obj_id_t);
175 static int raid_obj_set_fd(raid_obj_tab_t *, raid_obj_id_t, int);
176 static int obj_scan_comp(raid_obj_tab_t *, raid_obj_id_t);
177 static int obj_rescan(raid_obj_tab_t *);
178 static raid_obj_id_t obj_get_comp(raid_obj_tab_t *, raid_obj_id_t,
179 raid_obj_type_id_t);
180 static raid_obj_id_t obj_get_sibling(raid_obj_tab_t *, raid_obj_id_t);
181 static int obj_get_attr(raid_obj_tab_t *, raid_obj_id_t, void **);
182 static raid_obj_id_t obj_locate_controller(raid_obj_tab_t *, uint32_t);
183 static raid_obj_id_t obj_locate_array(raid_obj_tab_t *, uint32_t, uint32_t);
184 static raid_obj_id_t obj_locate_array_recur(raid_obj_tab_t *, raid_obj_id_t,
185 uint32_t);
186 static raid_obj_id_t obj_locate_hsp(raid_obj_tab_t *, uint32_t,
187 uint32_t, uint32_t);
188 static raid_obj_id_t obj_locate_disk(raid_obj_tab_t *, uint32_t, uint32_t);
189 static raid_obj_id_t obj_locate_arraypart(raid_obj_tab_t *, uint32_t,
190 uint32_t, uint32_t);
191 static raid_obj_id_t obj_locate_diskseg(raid_obj_tab_t *, uint32_t,
192 uint32_t, uint32_t);
193 static raid_obj_id_t obj_locate_task(raid_obj_tab_t *, uint32_t, uint32_t);
194 static raid_obj_id_t obj_locate_prop(raid_obj_tab_t *, uint32_t, uint32_t,
195 uint32_t);
196 static raid_obj_id_t obj_get_controller(raid_obj_tab_t *, raid_obj_id_t);
197
198 static int obj_sys_compnum(raid_obj_tab_t *, raid_obj_id_t,
199 raid_obj_type_id_t);
200 static int obj_sys_complist(raid_obj_tab_t *, raid_obj_id_t, int,
201 raid_obj_id_t *, raid_obj_type_id_t);
202 static int obj_controller_compnum(raid_obj_tab_t *, raid_obj_id_t,
203 raid_obj_type_id_t);
204 static int obj_controller_complist(raid_obj_tab_t *, raid_obj_id_t, int,
205 raid_obj_id_t *, raid_obj_type_id_t);
206 static int obj_controller_get_attr(raid_obj_tab_t *, raid_obj_id_t);
207 static int obj_controller_act(raid_obj_tab_t *, raid_obj_id_t,
208 uint32_t, void *, char **);
209 static int obj_array_compnum(raid_obj_tab_t *, raid_obj_id_t,
210 raid_obj_type_id_t);
211 static int obj_array_complist(raid_obj_tab_t *, raid_obj_id_t, int,
212 raid_obj_id_t *, raid_obj_type_id_t);
213 static int obj_array_get_attr(raid_obj_tab_t *, raid_obj_id_t);
214 static int obj_array_set_attr(raid_obj_tab_t *, raid_obj_id_t,
215 uint32_t, uint32_t *, char **);
216 static int obj_disk_compnum(raid_obj_tab_t *, raid_obj_id_t,
217 raid_obj_type_id_t);
218 static int obj_disk_complist(raid_obj_tab_t *, raid_obj_id_t, int,
219 raid_obj_id_t *, raid_obj_type_id_t);
220 static int obj_disk_get_attr(raid_obj_tab_t *, raid_obj_id_t);
221 static int obj_hsp_get_attr(raid_obj_tab_t *, raid_obj_id_t);
222 static int obj_arraypart_get_attr(raid_obj_tab_t *, raid_obj_id_t);
223 static int obj_diskseg_get_attr(raid_obj_tab_t *, raid_obj_id_t);
224 static int obj_task_get_attr(raid_obj_tab_t *, raid_obj_id_t);
225 static int obj_prop_get_attr(raid_obj_tab_t *, raid_obj_id_t);
226 static int obj_array_create(raid_obj_tab_t *, raid_obj_id_t, int,
227 raid_obj_id_t *, char **);
228 static int obj_array_delete(raid_obj_tab_t *, raid_obj_id_t, char **);
229 static int obj_hsp_bind(raid_obj_tab_t *, raid_obj_id_t *, char **);
230 static int obj_hsp_unbind(raid_obj_tab_t *, raid_obj_id_t *, char **);
231
232 static int raid_obj_create_system_obj(raid_obj_tab_t *);
233 static raid_obj_id_t raid_obj_id_new(raid_obj_tab_t *);
234 static void *raid_obj_attr_new(raid_obj_type_id_t);
235 static raid_obj_id_t raid_obj_create(raid_obj_tab_t *, raid_obj_type_id_t);
236 static int raid_obj_delete(raid_obj_tab_t *, raid_obj_id_t);
237 static int raid_obj_add_org(raid_obj_tab_t *, raid_obj_id_t, raid_obj_id_t);
238 static raid_obj_type_id_t raid_obj_get_type(raid_obj_tab_t *, raid_obj_id_t);
239 static int raid_obj_set_type(raid_obj_tab_t *, raid_obj_id_t,
240 raid_obj_type_id_t);
241 static raid_obj_status_t raid_obj_get_status(raid_obj_tab_t *, raid_obj_id_t);
242 static int raid_obj_set_status(raid_obj_tab_t *, raid_obj_id_t,
243 raid_obj_status_t);
244 static int raid_obj_clear_status(raid_obj_tab_t *, raid_obj_id_t,
245 raid_obj_status_t);
246 static raid_obj_id_t raid_obj_get_container(raid_obj_tab_t *, raid_obj_id_t);
247 static int raid_obj_set_container(raid_obj_tab_t *, raid_obj_id_t,
248 raid_obj_id_t);
249 static raid_obj_id_t raid_obj_get_comp(raid_obj_tab_t *, raid_obj_id_t);
250 static int raid_obj_set_comp(raid_obj_tab_t *, raid_obj_id_t, raid_obj_id_t);
251 static raid_obj_id_t raid_obj_get_sibling(raid_obj_tab_t *, raid_obj_id_t);
252 static int raid_obj_set_sibling(raid_obj_tab_t *, raid_obj_id_t,
253 raid_obj_id_t);
254 static void *raid_obj_get_data_ptr(raid_obj_tab_t *, raid_obj_id_t);
255 static int raid_obj_set_data_ptr(raid_obj_tab_t *, raid_obj_id_t, void *);
256 static raid_obj_handle_t raid_obj_get_handle(raid_obj_tab_t *,
257 raid_obj_id_t);
258 static int raid_obj_set_handle(raid_obj_tab_t *, raid_obj_id_t,
259 raid_obj_handle_t);
260
261 static void raid_list_create(raid_list_t *, size_t);
262 static void *raid_list_head(raid_list_t *);
263 static void *raid_list_next(raid_list_t *, void *);
264 static void raid_list_insert_tail(raid_list_t *, void *);
265 static void raid_list_remove(raid_list_t *, void *);
266 static void *raid_list_remove_head(raid_list_t *);
267 static void *raid_list_find(raid_list_t *, raid_obj_id_t);
268 static int raid_obj_tab_create(raid_obj_tab_t *, size_t);
269 static void raid_obj_tab_destroy(raid_obj_tab_t *);
270 static int raid_obj_tab_insert(raid_obj_tab_t *, raid_obj_id_t, void *);
271 static void *raid_obj_tab_remove(raid_obj_tab_t *, raid_obj_id_t);
272 static void *raid_obj_tab_find(raid_obj_tab_t *, raid_obj_id_t);
273 static void raid_list_destroy(raid_list_t *);
274
275 static int controller_id_to_path(uint32_t, char *);
276 static char *controller_id_to_driver_name(uint32_t);
277 static void raid_plugin_init();
278 static raid_lib_t *raid_plugin_load(char *);
279 static raid_lib_t *raid_find_lib(raid_obj_tab_t *, raid_obj_id_t);
280
281 /* Global object table */
282 static raid_obj_tab_t raid_tab_sys = {0, 0, NULL};
283
284 /* Plug-in modules maintenance data structures */
285 static raid_lib_t *raid_lib_sys = NULL;
286
287 /* Handle table definition */
288 static struct {
289 int handle_num;
290 int used;
291 int unused;
292 handle_attr_t *handles;
293 } raid_handle_sys = {0, 0, 0, NULL};
294
295 /*
296 * RAID object method table definition
297 */
298 static raid_obj_op_t raid_obj_op_sys[OBJ_TYPE_ALL] = {
299 {obj_sys_compnum, obj_sys_complist, NULL, NULL, NULL,
300 NULL, NULL, NULL, NULL}, /* system object methods */
301 {obj_controller_compnum, obj_controller_complist,
302 obj_controller_get_attr, NULL, obj_controller_act,
303 NULL, NULL, NULL, NULL}, /* controller object methods */
304 {obj_array_compnum, obj_array_complist, obj_array_get_attr,
305 obj_array_set_attr, NULL, obj_array_create,
306 obj_array_delete, NULL, NULL}, /* array object methods */
307 {obj_disk_compnum, obj_disk_complist, obj_disk_get_attr, NULL,
308 NULL, NULL, NULL, NULL, NULL}, /* disk object methods */
309 {NULL, NULL, obj_hsp_get_attr, NULL, NULL, NULL, NULL, obj_hsp_bind,
310 obj_hsp_unbind}, /* hsp object methods */
311 {NULL, NULL, obj_arraypart_get_attr, NULL, NULL, NULL, NULL,
312 NULL, NULL}, /* array part object methods */
313 {NULL, NULL, obj_diskseg_get_attr, NULL, NULL, NULL, NULL, NULL, NULL},
314 {NULL, NULL, obj_task_get_attr, NULL, NULL, NULL, NULL,
315 NULL, NULL}, /* disk seg object methods */
316 {NULL, NULL, obj_prop_get_attr, NULL, NULL, NULL, NULL,
317 NULL, NULL} /* property object methods */
318 };
319
320 /*
321 * Mutex for multithread safe
322 */
323 static mutex_t raidcfg_mp;
324
325 /*
326 * RaidCfg library APIs
327 */
328 const char *
raidcfg_errstr(int err_code)329 raidcfg_errstr(int err_code)
330 {
331 char *ret_val;
332
333 (void) mutex_lock(&raidcfg_mp);
334 switch (err_code) {
335 case SUCCESS:
336 ret_val = dgettext(TEXT_DOMAIN, "Operation succeeded.\n");
337 break;
338 case STD_IOCTL:
339 ret_val = dgettext(TEXT_DOMAIN,
340 "Request standard IOCTL service.\n");
341 break;
342 case ERR_DRIVER_NOT_FOUND:
343 ret_val = dgettext(TEXT_DOMAIN,
344 "Controller device can not be found.\n");
345 break;
346 case ERR_DRIVER_OPEN:
347 ret_val = dgettext(TEXT_DOMAIN, "Can not open controller.\n");
348 break;
349 case ERR_DRIVER_LOCK:
350 ret_val = dgettext(TEXT_DOMAIN, "Controller is locked.\n");
351 break;
352 case ERR_DRIVER_CLOSED:
353 ret_val = dgettext(TEXT_DOMAIN, "Controller is not opened.\n");
354 break;
355 case ERR_DRIVER_ACROSS:
356 ret_val = dgettext(TEXT_DOMAIN,
357 "Operation across multiple controllers.\n");
358 break;
359 case ERR_ARRAY_LEVEL:
360 ret_val = dgettext(TEXT_DOMAIN,
361 "Operation not support with volume of this level.\n");
362 break;
363 case ERR_ARRAY_SIZE:
364 ret_val = dgettext(TEXT_DOMAIN,
365 "Capacity of array out of range.\n");
366 break;
367 case ERR_ARRAY_STRIPE_SIZE:
368 ret_val = dgettext(TEXT_DOMAIN, "Illegal stripe size.\n");
369 break;
370 case ERR_ARRAY_CACHE_POLICY:
371 ret_val = dgettext(TEXT_DOMAIN,
372 "Illegal cache-write policy.\n");
373 break;
374 case ERR_ARRAY_IN_USE:
375 ret_val = dgettext(TEXT_DOMAIN, "Array or disk in use.\n");
376 break;
377 case ERR_ARRAY_TASK:
378 ret_val = dgettext(TEXT_DOMAIN, "Array has background task.\n");
379 break;
380 case ERR_ARRAY_CONFIG:
381 ret_val = dgettext(TEXT_DOMAIN,
382 "Configuration over device node failed.\n");
383 break;
384 case ERR_ARRAY_DISKNUM:
385 ret_val = dgettext(TEXT_DOMAIN, "Incorrect number of disks.\n");
386 break;
387 case ERR_ARRAY_LAYOUT:
388 ret_val = dgettext(TEXT_DOMAIN, "Illegal array layout.\n");
389 break;
390 case ERR_ARRAY_AMOUNT:
391 ret_val = dgettext(TEXT_DOMAIN, "Too many arrays.\n");
392 break;
393 case ERR_DISK_STATE:
394 ret_val = dgettext(TEXT_DOMAIN,
395 "Incorrect disk status for current operation.\n");
396 break;
397 case ERR_DISK_SPACE:
398 ret_val = dgettext(TEXT_DOMAIN, "No enough disk space.\n");
399 break;
400 case ERR_DISK_SEG_AMOUNT:
401 ret_val = dgettext(TEXT_DOMAIN, "Too many disk segments.\n");
402 break;
403 case ERR_DISK_NOT_EMPTY:
404 ret_val = dgettext(TEXT_DOMAIN, "Disk has occupied space.\n");
405 break;
406 case ERR_DISK_TASK:
407 ret_val = dgettext(TEXT_DOMAIN, "Disk has background task.\n");
408 break;
409 case ERR_TASK_STATE:
410 ret_val = dgettext(TEXT_DOMAIN,
411 "Incorrect task state for current operation.\n");
412 break;
413 case ERR_OP_ILLEGAL:
414 ret_val = dgettext(TEXT_DOMAIN, "Illegal operation.\n");
415 break;
416 case ERR_OP_NO_IMPL:
417 ret_val = dgettext(TEXT_DOMAIN,
418 "Operation is not implemented.\n");
419 break;
420 case ERR_OP_FAILED:
421 ret_val = dgettext(TEXT_DOMAIN, "Operation failed.\n");
422 break;
423 case ERR_DEVICE_NOENT:
424 ret_val = dgettext(TEXT_DOMAIN, "Device not found.\n");
425 break;
426 case ERR_DEVICE_TYPE:
427 ret_val = dgettext(TEXT_DOMAIN, "Illegal type of device.\n");
428 break;
429 case ERR_DEVICE_DUP:
430 ret_val = dgettext(TEXT_DOMAIN, "Device record duplicated.\n");
431 break;
432 case ERR_DEVICE_OVERFLOW:
433 ret_val = dgettext(TEXT_DOMAIN, "Too many devices.\n");
434 break;
435 case ERR_DEVICE_UNCLEAN:
436 ret_val = dgettext(TEXT_DOMAIN, "Device pool is not clean.\n");
437 break;
438 case ERR_DEVICE_INVALID:
439 ret_val = dgettext(TEXT_DOMAIN, "Device record is invalid.\n");
440 break;
441 case ERR_NOMEM:
442 ret_val = dgettext(TEXT_DOMAIN,
443 "Can not allocate more memory space.\n");
444 break;
445 case ERR_PRIV:
446 ret_val = dgettext(TEXT_DOMAIN, "No privilege.\n");
447 break;
448 default:
449 ret_val = dgettext(TEXT_DOMAIN, "Undefined error.\n");
450 }
451 (void) mutex_unlock(&raidcfg_mp);
452
453 return (ret_val);
454 }
455
456 int
raidcfg_get_controller(uint32_t controller_id)457 raidcfg_get_controller(uint32_t controller_id)
458 {
459 raid_obj_id_t obj_id;
460 int ret_val;
461
462 (void) mutex_lock(&raidcfg_mp);
463 (void) obj_rescan(&raid_tab_sys);
464 obj_id = obj_locate_controller(&raid_tab_sys, controller_id);
465 if (obj_id < OBJ_NONE) {
466 (void) mutex_unlock(&raidcfg_mp);
467 return (obj_id);
468 }
469
470 if (obj_id == OBJ_NONE) {
471 (void) mutex_unlock(&raidcfg_mp);
472 return (ERR_DEVICE_NOENT);
473 }
474 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id);
475 (void) mutex_unlock(&raidcfg_mp);
476
477 return (ret_val);
478 }
479
480 int
raidcfg_get_array(int controller_handle,uint64_t target_id,uint64_t lun)481 raidcfg_get_array(int controller_handle, uint64_t target_id, uint64_t lun)
482 {
483 raid_obj_id_t obj_id;
484 raidcfg_array_t *attr;
485 int ret_val;
486
487 (void) mutex_lock(&raidcfg_mp);
488 (void) obj_rescan(&raid_tab_sys);
489 obj_id = raid_handle_to_obj(&raid_tab_sys, controller_handle);
490 if (obj_id < OBJ_NONE) {
491 (void) mutex_unlock(&raidcfg_mp);
492 return (obj_id);
493 }
494
495 obj_id = obj_get_comp(&raid_tab_sys, obj_id, OBJ_TYPE_ARRAY);
496
497 while (obj_id > OBJ_NONE) {
498 (void) obj_get_attr(&raid_tab_sys, obj_id, (void **)(&attr));
499 if (attr->tag.idl.target_id == target_id &&
500 attr->tag.idl.lun == lun)
501 break;
502
503 obj_id = obj_get_sibling(&raid_tab_sys, obj_id);
504 }
505
506 if (obj_id < OBJ_NONE) {
507 (void) mutex_unlock(&raidcfg_mp);
508 return (obj_id);
509 }
510 if (obj_id == OBJ_NONE) {
511 (void) mutex_unlock(&raidcfg_mp);
512 return (ERR_DEVICE_NOENT);
513 }
514 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id);
515 (void) mutex_unlock(&raidcfg_mp);
516
517 return (ret_val);
518 }
519
520 int
raidcfg_get_disk(int controller_handle,disk_tag_t tag)521 raidcfg_get_disk(int controller_handle, disk_tag_t tag)
522 {
523 raid_obj_id_t obj_id;
524 raidcfg_disk_t *attr;
525 int ret_val;
526
527 (void) mutex_lock(&raidcfg_mp);
528 (void) obj_rescan(&raid_tab_sys);
529 obj_id = raid_handle_to_obj(&raid_tab_sys, controller_handle);
530 if (obj_id < OBJ_NONE) {
531 (void) mutex_unlock(&raidcfg_mp);
532 return (obj_id);
533 }
534
535 obj_id = obj_get_comp(&raid_tab_sys, obj_id, OBJ_TYPE_DISK);
536
537 while (obj_id > OBJ_NONE) {
538 (void) obj_get_attr(&raid_tab_sys, obj_id, (void **)(&attr));
539 if (attr->tag.cidl.bus == tag.cidl.bus &&
540 attr->tag.cidl.target_id == tag.cidl.target_id &&
541 attr->tag.cidl.lun == tag.cidl.lun)
542 break;
543
544 obj_id = obj_get_sibling(&raid_tab_sys, obj_id);
545 }
546
547 if (obj_id < OBJ_NONE) {
548 (void) mutex_unlock(&raidcfg_mp);
549 return (obj_id);
550 }
551 if (obj_id == OBJ_NONE) {
552 (void) mutex_unlock(&raidcfg_mp);
553 return (ERR_DEVICE_NOENT);
554 }
555 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id);
556 (void) mutex_unlock(&raidcfg_mp);
557
558 return (ret_val);
559 }
560
561 int
raidcfg_open_controller(int handle,char ** plugin_err_str)562 raidcfg_open_controller(int handle, char **plugin_err_str)
563 {
564 raid_obj_id_t obj_id;
565 int ret;
566
567 (void) mutex_lock(&raidcfg_mp);
568 (void) obj_rescan(&raid_tab_sys);
569 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
570 if (obj_id < OBJ_NONE) {
571 raid_handle_delete(handle);
572 (void) mutex_unlock(&raidcfg_mp);
573 return (ERR_DEVICE_NOENT);
574 }
575
576 ret = obj_controller_act(&raid_tab_sys, obj_id,
577 ACT_CONTROLLER_OPEN, NULL, plugin_err_str);
578 if (ret < SUCCESS) {
579 (void) mutex_unlock(&raidcfg_mp);
580 return (ret);
581 }
582 (void) mutex_unlock(&raidcfg_mp);
583
584 return (SUCCESS);
585 }
586
587 int
raidcfg_close_controller(int handle,char ** plugin_err_str)588 raidcfg_close_controller(int handle, char **plugin_err_str)
589 {
590 raid_obj_id_t obj_id;
591 int ret;
592
593 (void) mutex_lock(&raidcfg_mp);
594 (void) obj_rescan(&raid_tab_sys);
595 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
596 if (obj_id < OBJ_NONE) {
597 raid_handle_delete(handle);
598 (void) mutex_unlock(&raidcfg_mp);
599 return (ERR_DEVICE_NOENT);
600 }
601
602 ret = obj_controller_act(&raid_tab_sys, obj_id,
603 ACT_CONTROLLER_CLOSE, NULL, plugin_err_str);
604 if (ret < SUCCESS) {
605 (void) mutex_unlock(&raidcfg_mp);
606 return (ret);
607 }
608 (void) mutex_unlock(&raidcfg_mp);
609
610 return (SUCCESS);
611 }
612
613 int
raidcfg_get_type(int handle)614 raidcfg_get_type(int handle)
615 {
616 raid_obj_id_t obj_id;
617 int ret_val;
618
619 (void) mutex_lock(&raidcfg_mp);
620 (void) obj_rescan(&raid_tab_sys);
621 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
622 if (obj_id < OBJ_NONE) {
623 raid_handle_delete(handle);
624 (void) mutex_unlock(&raidcfg_mp);
625 return (ERR_DEVICE_NOENT);
626 }
627 ret_val = raid_obj_get_type(&raid_tab_sys, obj_id);
628 (void) mutex_unlock(&raidcfg_mp);
629
630 return (ret_val);
631 }
632
633 int
raidcfg_get_attr(int handle,void * attr)634 raidcfg_get_attr(int handle, void *attr)
635 {
636 raid_obj_id_t obj_id;
637 raid_obj_type_id_t type;
638 void *data;
639 int ret, size;
640
641 (void) mutex_lock(&raidcfg_mp);
642 (void) obj_rescan(&raid_tab_sys);
643 if (attr == NULL) {
644 (void) mutex_unlock(&raidcfg_mp);
645 return (ERR_DEVICE_INVALID);
646 }
647
648 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
649 if (obj_id < OBJ_NONE) {
650 raid_handle_delete(handle);
651 (void) mutex_unlock(&raidcfg_mp);
652 return (ERR_DEVICE_NOENT);
653 }
654
655 type = raid_obj_get_type(&raid_tab_sys, obj_id);
656 ret = obj_get_attr(&raid_tab_sys, obj_id, &data);
657 if (ret < SUCCESS) {
658 (void) mutex_unlock(&raidcfg_mp);
659 return (ret);
660 }
661
662 switch (type) {
663 case OBJ_TYPE_CONTROLLER:
664 size = sizeof (controller_attr_t);
665 break;
666 case OBJ_TYPE_ARRAY:
667 size = sizeof (array_attr_t);
668 break;
669 case OBJ_TYPE_HSP:
670 {
671 raidcfg_hsp_t *dst = attr;
672 hsp_attr_t *src = data;
673 controller_attr_t *ctlr_attr;
674 array_attr_t *array_attr;
675
676 dst->associated_id = src->associated_id;
677 dst->type = src->type;
678
679 obj_id = obj_get_controller(&raid_tab_sys, obj_id);
680 ret = obj_get_attr(&raid_tab_sys, obj_id,
681 (void **)(&ctlr_attr));
682 if (ret < SUCCESS) {
683 (void) mutex_unlock(&raidcfg_mp);
684 return (ret);
685 }
686
687 if (src->type == HSP_TYPE_LOCAL) {
688 obj_id = obj_locate_array(&raid_tab_sys,
689 ctlr_attr->controller_id,
690 src->associated_id);
691 ret = obj_get_attr(&raid_tab_sys, obj_id,
692 (void **)(&array_attr));
693 if (ret < SUCCESS) {
694 (void) mutex_unlock(&raidcfg_mp);
695 return (ret);
696 }
697
698 dst->tag.idl.target_id =
699 array_attr->tag.idl.target_id;
700 dst->tag.idl.lun = array_attr->tag.idl.lun;
701 }
702 }
703 (void) mutex_unlock(&raidcfg_mp);
704 return (SUCCESS);
705 case OBJ_TYPE_DISK:
706 size = sizeof (disk_attr_t);
707 break;
708 case OBJ_TYPE_ARRAY_PART:
709 {
710 raidcfg_arraypart_t *dst = attr;
711 arraypart_attr_t *src = data;
712 controller_attr_t *ctlr_attr;
713 disk_attr_t *disk_attr;
714
715 dst->disk_id = src->disk_id;
716 dst->offset = src->offset;
717 dst->size = src->size;
718 dst->state = src->state;
719
720 obj_id = obj_get_controller(&raid_tab_sys, obj_id);
721 ret = obj_get_attr(&raid_tab_sys, obj_id,
722 (void **)(&ctlr_attr));
723 if (ret < SUCCESS) {
724 (void) mutex_unlock(&raidcfg_mp);
725 return (ret);
726 }
727
728 obj_id = obj_locate_disk(&raid_tab_sys,
729 ctlr_attr->controller_id, src->disk_id);
730 if (obj_id <= OBJ_NONE) {
731 dst->tag.cidl.bus = (uint64_t)OBJ_ATTR_NONE;
732 dst->tag.cidl.target_id =
733 (uint64_t)OBJ_ATTR_NONE;
734 dst->tag.cidl.lun = (uint64_t)OBJ_ATTR_NONE;
735 (void) mutex_unlock(&raidcfg_mp);
736 return (SUCCESS);
737 }
738
739 ret = obj_get_attr(&raid_tab_sys, obj_id,
740 (void **)(&disk_attr));
741 if (ret < SUCCESS) {
742 (void) mutex_unlock(&raidcfg_mp);
743 return (ret);
744 }
745
746 dst->tag.cidl.bus = disk_attr->tag.cidl.bus;
747 dst->tag.cidl.target_id = disk_attr->tag.cidl.target_id;
748 dst->tag.cidl.lun = disk_attr->tag.cidl.lun;
749 }
750 (void) mutex_unlock(&raidcfg_mp);
751 return (SUCCESS);
752 case OBJ_TYPE_DISK_SEG:
753 size = sizeof (diskseg_attr_t);
754 break;
755 case OBJ_TYPE_TASK:
756 size = sizeof (task_attr_t);
757 break;
758 case OBJ_TYPE_PROP:
759 {
760 property_attr_t *src = data, *dst = attr;
761
762 dst->prop_id = src->prop_id;
763 dst->prop_type = src->prop_type;
764 if (dst->prop_size == 0) {
765 dst->prop_size = src->prop_size;
766 (void) mutex_unlock(&raidcfg_mp);
767 return (SUCCESS);
768 }
769
770 if (dst->prop_size < src->prop_size)
771 size = dst->prop_size;
772 else
773 size = src->prop_size;
774
775 (void) memcpy(dst->prop, src->prop, size);
776 (void) mutex_unlock(&raidcfg_mp);
777 return (SUCCESS);
778 }
779 default:
780 (void) mutex_unlock(&raidcfg_mp);
781 return (ERR_DEVICE_TYPE);
782 }
783
784 (void) memcpy(attr, data, size);
785
786 (void) mutex_unlock(&raidcfg_mp);
787 return (ret);
788 }
789
790 int
raidcfg_get_container(int handle)791 raidcfg_get_container(int handle)
792 {
793 raid_obj_id_t obj_id;
794 int ret_val;
795
796 (void) mutex_lock(&raidcfg_mp);
797 (void) obj_rescan(&raid_tab_sys);
798 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
799 if (obj_id < OBJ_NONE) {
800 raid_handle_delete(handle);
801 (void) mutex_unlock(&raidcfg_mp);
802 return (ERR_DEVICE_NOENT);
803 }
804
805 obj_id = raid_obj_get_container(&raid_tab_sys, obj_id);
806 if (obj_id < OBJ_NONE) {
807 (void) mutex_unlock(&raidcfg_mp);
808 return (obj_id);
809 }
810 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id);
811 (void) mutex_unlock(&raidcfg_mp);
812
813 return (ret_val);
814 }
815
816 int
raidcfg_list_head(int handle,raid_obj_type_id_t type)817 raidcfg_list_head(int handle, raid_obj_type_id_t type)
818 {
819 raid_obj_id_t obj_id;
820 int ret_val;
821
822 (void) mutex_lock(&raidcfg_mp);
823 (void) obj_rescan(&raid_tab_sys);
824 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
825 if (obj_id < OBJ_NONE) {
826 raid_handle_delete(handle);
827 (void) mutex_unlock(&raidcfg_mp);
828 return (ERR_DEVICE_NOENT);
829 }
830
831 obj_id = obj_get_comp(&raid_tab_sys, obj_id, type);
832 if (obj_id < OBJ_NONE) {
833 (void) mutex_unlock(&raidcfg_mp);
834 return (obj_id);
835 }
836 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id);
837 (void) mutex_unlock(&raidcfg_mp);
838
839 return (ret_val);
840 }
841
842 int
raidcfg_list_next(int handle)843 raidcfg_list_next(int handle)
844 {
845 raid_obj_id_t obj_id;
846 int ret_val;
847
848 (void) mutex_lock(&raidcfg_mp);
849 (void) obj_rescan(&raid_tab_sys);
850 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
851 if (obj_id < OBJ_NONE) {
852 raid_handle_delete(handle);
853 (void) mutex_unlock(&raidcfg_mp);
854 return (ERR_DEVICE_NOENT);
855 }
856
857 obj_id = obj_get_sibling(&raid_tab_sys, obj_id);
858 if (obj_id < OBJ_NONE) {
859 (void) mutex_unlock(&raidcfg_mp);
860 return (obj_id);
861 }
862 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id);
863 (void) mutex_unlock(&raidcfg_mp);
864
865 return (ret_val);
866 }
867
868 int
raidcfg_set_attr(int handle,uint32_t set_cmd,void * value,char ** plugin_err_str)869 raidcfg_set_attr(int handle, uint32_t set_cmd, void *value,
870 char **plugin_err_str)
871 {
872 raid_obj_id_t obj_id;
873 raid_obj_type_id_t type;
874 int ret;
875
876 (void) mutex_lock(&raidcfg_mp);
877 (void) obj_rescan(&raid_tab_sys);
878 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
879 if (obj_id < OBJ_NONE) {
880 raid_handle_delete(handle);
881 (void) mutex_unlock(&raidcfg_mp);
882 return (ERR_DEVICE_NOENT);
883 }
884
885 type = raid_obj_get_type(&raid_tab_sys, obj_id);
886 if (raid_obj_op_sys[type].set_attr == NULL) {
887 (void) mutex_unlock(&raidcfg_mp);
888 return (ERR_OP_NO_IMPL);
889 }
890
891 ret = raid_obj_op_sys[type].set_attr(&raid_tab_sys,
892 obj_id, set_cmd, value, plugin_err_str);
893
894 (void) mutex_unlock(&raidcfg_mp);
895 return (ret);
896 }
897
898 int
raidcfg_update_fw(int handle,char * file,char ** plugin_err_str)899 raidcfg_update_fw(int handle, char *file, char **plugin_err_str)
900 {
901 raid_obj_id_t obj_id;
902 int ret;
903
904 (void) mutex_lock(&raidcfg_mp);
905 (void) obj_rescan(&raid_tab_sys);
906 obj_id = raid_handle_to_obj(&raid_tab_sys, handle);
907 if (obj_id < OBJ_NONE) {
908 raid_handle_delete(handle);
909 (void) mutex_unlock(&raidcfg_mp);
910 return (ERR_DEVICE_NOENT);
911 }
912
913 if (raid_obj_get_type(&raid_tab_sys, obj_id) != OBJ_TYPE_CONTROLLER) {
914 (void) mutex_unlock(&raidcfg_mp);
915 return (ERR_OP_NO_IMPL);
916 }
917
918 ret = raid_obj_op_sys[OBJ_TYPE_CONTROLLER].act(&raid_tab_sys,
919 obj_id, ACT_CONTROLLER_FLASH_FW, file, plugin_err_str);
920
921 (void) mutex_unlock(&raidcfg_mp);
922 return (ret);
923 }
924
925 int
raidcfg_create_array(int num_of_comps,int * disk_handles,uint32_t raid_level,uint64_t size,uint32_t stripe_size,char ** plugin_err_str)926 raidcfg_create_array(int num_of_comps, int *disk_handles,
927 uint32_t raid_level, uint64_t size, uint32_t stripe_size,
928 char **plugin_err_str)
929 {
930 raid_obj_id_t *disk_obj_ids, obj_id;
931 array_attr_t *array_attr;
932 raid_obj_handle_t array_handle;
933 int i, ret;
934
935 (void) mutex_lock(&raidcfg_mp);
936 (void) obj_rescan(&raid_tab_sys);
937
938 disk_obj_ids = calloc(num_of_comps, sizeof (raid_obj_id_t));
939 if (disk_obj_ids == NULL) {
940 (void) mutex_unlock(&raidcfg_mp);
941 return (ERR_NOMEM);
942 }
943
944 /* convert disk handles into disk object ids; */
945 for (i = 0; i < num_of_comps; ++i) {
946 if (*(disk_handles + i) == OBJ_SEPARATOR_BEGIN ||
947 *(disk_handles + i) == OBJ_SEPARATOR_END) {
948 *(disk_obj_ids + i) = *(disk_handles + i);
949 continue;
950 }
951
952 *(disk_obj_ids + i) = raid_handle_to_obj(&raid_tab_sys,
953 *(disk_handles + i));
954 if (raid_obj_get_type(&raid_tab_sys, *(disk_obj_ids + i)) !=
955 OBJ_TYPE_DISK) {
956 free(disk_obj_ids);
957 (void) obj_rescan(&raid_tab_sys);
958 (void) mutex_unlock(&raidcfg_mp);
959 return (ERR_DEVICE_TYPE);
960 }
961 }
962
963 /* Create an empty array object */
964 obj_id = raid_obj_create(&raid_tab_sys, OBJ_TYPE_ARRAY);
965 if (obj_id < OBJ_NONE) {
966 free(disk_obj_ids);
967 (void) obj_rescan(&raid_tab_sys);
968 (void) mutex_unlock(&raidcfg_mp);
969 return (obj_id);
970 }
971 (void) raid_obj_clear_status(&raid_tab_sys, obj_id,
972 OBJ_STATUS_CMD_CLEAN);
973
974 array_attr = raid_obj_get_data_ptr(&raid_tab_sys, obj_id);
975 array_attr->array_id = (uint32_t)OBJ_ATTR_NONE;
976 array_attr->raid_level = raid_level;
977 array_attr->capacity = size;
978 array_attr->stripe_size = stripe_size;
979 array_attr->write_policy = CACHE_WR_ON;
980 array_attr->read_policy = CACHE_RD_ON;
981
982 ret = raid_obj_op_sys[OBJ_TYPE_ARRAY].create_obj(&raid_tab_sys, obj_id,
983 num_of_comps, disk_obj_ids, plugin_err_str);
984 free(disk_obj_ids);
985
986 if (ret < SUCCESS) {
987 (void) obj_rescan(&raid_tab_sys);
988 (void) mutex_unlock(&raidcfg_mp);
989 return (ret);
990 }
991
992 /* create_obj() method should put the array object in the device tree */
993 array_handle = raid_obj_to_handle(&raid_tab_sys, obj_id);
994
995 (void) obj_rescan(&raid_tab_sys);
996 (void) mutex_unlock(&raidcfg_mp);
997 return (array_handle);
998 }
999
1000 int
raidcfg_delete_array(int array_handle,char ** plugin_err_str)1001 raidcfg_delete_array(int array_handle, char **plugin_err_str)
1002 {
1003 raid_obj_id_t array_obj_id;
1004 int ret;
1005
1006 (void) mutex_lock(&raidcfg_mp);
1007 (void) obj_rescan(&raid_tab_sys);
1008
1009 if (raidcfg_get_type(array_handle) != OBJ_TYPE_ARRAY) {
1010 (void) mutex_unlock(&raidcfg_mp);
1011 return (ERR_DEVICE_TYPE);
1012 }
1013
1014 array_obj_id = raid_handle_to_obj(&raid_tab_sys, array_handle);
1015 if (array_obj_id < OBJ_NONE) {
1016 (void) mutex_unlock(&raidcfg_mp);
1017 return (array_obj_id);
1018 }
1019 if (array_obj_id == OBJ_NONE) {
1020 (void) mutex_unlock(&raidcfg_mp);
1021 return (ERR_DEVICE_INVALID);
1022 }
1023
1024 ret = raid_obj_op_sys[OBJ_TYPE_ARRAY].delete_obj(&raid_tab_sys,
1025 array_obj_id, plugin_err_str);
1026 (void) obj_rescan(&raid_tab_sys);
1027
1028 (void) mutex_unlock(&raidcfg_mp);
1029 return (ret);
1030 }
1031
1032 int
raidcfg_set_hsp(raidcfg_hsp_relation_t * hsp_relations,char ** plugin_err_str)1033 raidcfg_set_hsp(raidcfg_hsp_relation_t *hsp_relations,
1034 char **plugin_err_str)
1035 {
1036 raid_obj_id_t disk_obj_id, array_obj_id;
1037 raid_obj_id_t *hsp_relation_objs;
1038 int ret;
1039
1040 (void) mutex_lock(&raidcfg_mp);
1041 (void) obj_rescan(&raid_tab_sys);
1042 if (hsp_relations == NULL) {
1043 (void) mutex_unlock(&raidcfg_mp);
1044 return (ERR_OP_ILLEGAL);
1045 }
1046
1047 hsp_relation_objs = malloc(2 * sizeof (raid_obj_id_t));
1048 if (hsp_relation_objs == NULL) {
1049 (void) mutex_unlock(&raidcfg_mp);
1050 return (ERR_NOMEM);
1051 }
1052
1053 (void) obj_rescan(&raid_tab_sys);
1054
1055 if (hsp_relations->array_handle != OBJ_ATTR_NONE) {
1056 array_obj_id = raid_handle_to_obj(&raid_tab_sys,
1057 hsp_relations->array_handle);
1058 if (array_obj_id < OBJ_NONE) {
1059 free(hsp_relation_objs);
1060 (void) mutex_unlock(&raidcfg_mp);
1061 return (array_obj_id);
1062 }
1063 if (array_obj_id == OBJ_NONE) {
1064 (void) free(hsp_relation_objs);
1065 (void) mutex_unlock(&raidcfg_mp);
1066 return (ERR_DEVICE_NOENT);
1067 }
1068 if (raidcfg_get_type(hsp_relations->array_handle) !=
1069 OBJ_TYPE_ARRAY) {
1070 free(hsp_relation_objs);
1071 (void) mutex_unlock(&raidcfg_mp);
1072 return (ERR_DEVICE_TYPE);
1073 }
1074 } else
1075 array_obj_id = OBJ_ATTR_NONE;
1076
1077 disk_obj_id = raid_handle_to_obj(&raid_tab_sys,
1078 hsp_relations->disk_handle);
1079 if (disk_obj_id < OBJ_NONE) {
1080 free(hsp_relation_objs);
1081 (void) mutex_unlock(&raidcfg_mp);
1082 return (disk_obj_id);
1083 }
1084 if (disk_obj_id == OBJ_NONE) {
1085 free(hsp_relation_objs);
1086 (void) mutex_unlock(&raidcfg_mp);
1087 return (ERR_DEVICE_NOENT);
1088 }
1089 if (raidcfg_get_type(hsp_relations->disk_handle) !=
1090 OBJ_TYPE_DISK) {
1091 free(hsp_relation_objs);
1092 (void) mutex_unlock(&raidcfg_mp);
1093 return (ERR_DEVICE_TYPE);
1094 }
1095
1096 hsp_relation_objs[0] = array_obj_id;
1097 hsp_relation_objs[1] = disk_obj_id;
1098
1099 ret = raid_obj_op_sys[OBJ_TYPE_HSP].bind_obj(&raid_tab_sys,
1100 hsp_relation_objs, plugin_err_str);
1101
1102 (void) obj_rescan(&raid_tab_sys);
1103 free(hsp_relation_objs);
1104 (void) mutex_unlock(&raidcfg_mp);
1105
1106 return (ret);
1107 }
1108
1109 int
raidcfg_unset_hsp(raidcfg_hsp_relation_t * hsp_relations,char ** plugin_err_str)1110 raidcfg_unset_hsp(raidcfg_hsp_relation_t *hsp_relations,
1111 char **plugin_err_str)
1112 {
1113 raid_obj_id_t disk_obj_id, array_obj_id;
1114 raid_obj_id_t *hsp_relation_objs;
1115 int ret;
1116
1117 (void) mutex_lock(&raidcfg_mp);
1118 (void) obj_rescan(&raid_tab_sys);
1119 if (hsp_relations == NULL) {
1120 (void) mutex_unlock(&raidcfg_mp);
1121 return (ERR_OP_ILLEGAL);
1122 }
1123
1124 hsp_relation_objs = malloc(2 * sizeof (raid_obj_id_t));
1125 if (hsp_relation_objs == NULL) {
1126 (void) mutex_unlock(&raidcfg_mp);
1127 return (ERR_NOMEM);
1128 }
1129
1130 (void) obj_rescan(&raid_tab_sys);
1131
1132 if (hsp_relations->array_handle != OBJ_ATTR_NONE) {
1133 array_obj_id = raid_handle_to_obj(&raid_tab_sys,
1134 hsp_relations->array_handle);
1135 if (array_obj_id < OBJ_NONE) {
1136 free(hsp_relation_objs);
1137 (void) mutex_unlock(&raidcfg_mp);
1138 return (array_obj_id);
1139 }
1140 if (array_obj_id == OBJ_NONE) {
1141 free(hsp_relation_objs);
1142 (void) mutex_unlock(&raidcfg_mp);
1143 return (ERR_DEVICE_NOENT);
1144 }
1145 if (raidcfg_get_type(hsp_relations->array_handle) !=
1146 OBJ_TYPE_ARRAY) {
1147 free(hsp_relation_objs);
1148 (void) mutex_unlock(&raidcfg_mp);
1149 return (ERR_DEVICE_TYPE);
1150 }
1151 } else
1152 array_obj_id = OBJ_ATTR_NONE;
1153
1154 disk_obj_id = raid_handle_to_obj(&raid_tab_sys,
1155 hsp_relations->disk_handle);
1156 if (disk_obj_id < OBJ_NONE) {
1157 free(hsp_relation_objs);
1158 (void) mutex_unlock(&raidcfg_mp);
1159 return (disk_obj_id);
1160 }
1161 if (disk_obj_id == OBJ_NONE) {
1162 free(hsp_relation_objs);
1163 (void) mutex_unlock(&raidcfg_mp);
1164 return (ERR_DEVICE_NOENT);
1165 }
1166 if (raidcfg_get_type(hsp_relations->disk_handle) !=
1167 OBJ_TYPE_DISK) {
1168 free(hsp_relation_objs);
1169 (void) mutex_unlock(&raidcfg_mp);
1170 return (ERR_DEVICE_TYPE);
1171 }
1172
1173 hsp_relation_objs[0] = array_obj_id;
1174 hsp_relation_objs[1] = disk_obj_id;
1175
1176 ret = raid_obj_op_sys[OBJ_TYPE_HSP].unbind_obj(&raid_tab_sys,
1177 hsp_relation_objs, plugin_err_str);
1178
1179 (void) obj_rescan(&raid_tab_sys);
1180 free(hsp_relation_objs);
1181 (void) mutex_unlock(&raidcfg_mp);
1182
1183 return (ret);
1184 }
1185
1186 /*
1187 * RaidCfg lib routines
1188 */
1189 void
raidcfg_init(void)1190 raidcfg_init(void)
1191 {
1192 (void) mutex_init(&raidcfg_mp, USYNC_THREAD, NULL);
1193 raid_plugin_init();
1194 (void) raid_handle_init();
1195 (void) obj_rescan(&raid_tab_sys);
1196 }
1197
1198 void
raidcfg_fini(void)1199 raidcfg_fini(void)
1200 {
1201 /*
1202 * Need to close all opened controllers before destroying object table
1203 */
1204 (void) obj_rescan(&raid_tab_sys);
1205 raid_handle_fini();
1206 raid_obj_tab_destroy(&raid_tab_sys);
1207 raid_plugin_init();
1208 (void) mutex_destroy(&raidcfg_mp);
1209 }
1210
1211 /*
1212 * Support routines
1213 */
1214 static int
intcompare(const void * p1,const void * p2)1215 intcompare(const void *p1, const void *p2)
1216 {
1217 int i, j;
1218 i = *((int *)p1);
1219 j = *((int *)p2);
1220 return (i - j);
1221 }
1222
1223 static uint64_t
raid_space_noalign(raid_obj_tab_t * raid_tab,uint32_t raid_level,int num,raid_obj_id_t * disk_objs,arraypart_attr_t * arraypart_attrs)1224 raid_space_noalign(raid_obj_tab_t *raid_tab, uint32_t raid_level, int num,
1225 raid_obj_id_t *disk_objs, arraypart_attr_t *arraypart_attrs)
1226 {
1227 disk_attr_t *disk_attr;
1228 diskseg_attr_t *diskseg_attr;
1229 raid_obj_id_t obj_id;
1230 uint64_t offset, capacity;
1231 int i, disk_num, sub_array_num, disk_layer;
1232
1233 /* Find out the maximum available space for all disks */
1234 for (i = 0; i < num; ++i) {
1235 if ((disk_objs[i] == OBJ_SEPARATOR_BEGIN) ||
1236 (disk_objs[i] == OBJ_SEPARATOR_END))
1237 continue;
1238
1239 (void) obj_get_attr(raid_tab, disk_objs[i],
1240 (void **)(&disk_attr));
1241 obj_id = obj_get_comp(raid_tab, disk_objs[i],
1242 OBJ_TYPE_DISK_SEG);
1243 if (obj_id == OBJ_NONE) {
1244 arraypart_attrs[i].offset = 0;
1245 arraypart_attrs[i].size = disk_attr->capacity;
1246 continue;
1247 }
1248
1249 (void) obj_get_attr(raid_tab, obj_id, (void **)
1250 (&diskseg_attr));
1251 arraypart_attrs[i].offset = 0;
1252 arraypart_attrs[i].size = diskseg_attr->offset;
1253 offset = diskseg_attr->offset + diskseg_attr->size;
1254
1255 while ((obj_id = obj_get_sibling(raid_tab, obj_id)) !=
1256 OBJ_NONE) {
1257 (void) obj_get_attr(raid_tab, obj_id,
1258 (void **)(&diskseg_attr));
1259 if ((diskseg_attr->offset - offset) >
1260 arraypart_attrs[i].size) {
1261 arraypart_attrs[i].offset = offset;
1262 arraypart_attrs[i].size = diskseg_attr->offset -
1263 offset;
1264 }
1265
1266 offset = diskseg_attr->offset + diskseg_attr->size;
1267 }
1268
1269 if ((disk_attr->capacity - offset) > arraypart_attrs[i].size) {
1270 arraypart_attrs[i].offset = offset;
1271 arraypart_attrs[i].size = disk_attr->capacity -
1272 offset;
1273 }
1274 }
1275
1276 capacity = OBJ_ATTR_NONE;
1277 disk_num = 0;
1278 disk_layer = 0;
1279 sub_array_num = 0;
1280 for (i = 0; i < num; ++i) {
1281 if (disk_objs[i] == OBJ_SEPARATOR_BEGIN) {
1282 ++ disk_layer;
1283 continue;
1284 }
1285 if (disk_objs[i] == OBJ_SEPARATOR_END) {
1286 -- disk_layer;
1287 if (disk_layer != 0)
1288 ++ sub_array_num;
1289 continue;
1290 }
1291
1292 if (capacity > arraypart_attrs[i].size)
1293 capacity = arraypart_attrs[i].size;
1294 ++disk_num;
1295 }
1296
1297 switch (raid_level) {
1298 case RAID_LEVEL_0:
1299 capacity = capacity * disk_num;
1300 break;
1301 case RAID_LEVEL_1:
1302 capacity = capacity * disk_num / 2;
1303 break;
1304 case RAID_LEVEL_1E:
1305 capacity = capacity * disk_num / 2;
1306 break;
1307 case RAID_LEVEL_5:
1308 capacity = capacity * (disk_num - 1);
1309 break;
1310 case RAID_LEVEL_10:
1311 capacity = capacity * disk_num / 2;
1312 break;
1313 case RAID_LEVEL_50:
1314 capacity = capacity * (disk_num - sub_array_num);
1315 break;
1316 default:
1317 return (ERR_ARRAY_LEVEL);
1318 }
1319
1320 return (capacity);
1321 }
1322
1323 /*
1324 * Raid handle maintenance routines
1325 */
1326 static int
raid_handle_init()1327 raid_handle_init()
1328 {
1329 int i;
1330 void *ptr;
1331
1332 raid_handle_sys.handle_num += HANDLER_SLOTS;
1333 ptr = realloc(raid_handle_sys.handles,
1334 raid_handle_sys.handle_num * sizeof (handle_attr_t));
1335 if (ptr == NULL)
1336 return (ERR_NOMEM);
1337 raid_handle_sys.handles = ptr;
1338
1339 /* Clean up the new allocated handles */
1340 for (i = raid_handle_sys.handle_num - HANDLER_SLOTS;
1341 i < raid_handle_sys.handle_num; ++i) {
1342 bzero(&raid_handle_sys.handles[i], sizeof (handle_attr_t));
1343 raid_handle_sys.handles[i].type = OBJ_TYPE_ALL;
1344 raid_handle_sys.handles[i].next = i + 1;
1345 }
1346
1347 /* For the first time of allocation, set up the system object handle */
1348 if (raid_handle_sys.handle_num == HANDLER_SLOTS) {
1349 raid_handle_sys.handles[0].type = OBJ_TYPE_SYSTEM;
1350 raid_handle_sys.handles[0].next = 0;
1351 raid_handle_sys.unused = 1;
1352 raid_handle_sys.used = 0;
1353 }
1354 return (SUCCESS);
1355 }
1356
1357 static void
raid_handle_fini()1358 raid_handle_fini()
1359 {
1360 raid_obj_handle_t i;
1361
1362 i = raid_handle_sys.used;
1363
1364 /* Close all opened controllers */
1365 while (i != 0) {
1366 if ((raid_handle_sys.handles[i].type == OBJ_TYPE_CONTROLLER) &&
1367 (raid_handle_sys.handles[i].fd != 0) &&
1368 (raid_handle_sys.handles[i].raid_lib != NULL))
1369 raid_handle_sys.handles[i].raid_lib->close_controller(
1370 raid_handle_sys.handles[i].controller_id, NULL);
1371 i = raid_handle_sys.handles[i].next;
1372 }
1373
1374 /* Clean up handle space */
1375 raid_handle_sys.handle_num = 0;
1376 raid_handle_sys.unused = 0;
1377 raid_handle_sys.used = 0;
1378 free(raid_handle_sys.handles);
1379 raid_handle_sys.handles = NULL;
1380 }
1381
1382 static raid_obj_handle_t
raid_handle_new(raid_obj_type_id_t type)1383 raid_handle_new(raid_obj_type_id_t type)
1384 {
1385 int ret;
1386
1387 if (raid_handle_sys.unused == raid_handle_sys.handle_num - 1) {
1388 ret = raid_handle_init();
1389 if (ret < SUCCESS)
1390 return (ret);
1391 }
1392
1393 ret = raid_handle_sys.unused;
1394 raid_handle_sys.unused = raid_handle_sys.handles[ret].next;
1395
1396 raid_handle_sys.handles[ret].next = raid_handle_sys.used;
1397 raid_handle_sys.used = ret;
1398 raid_handle_sys.handles[ret].type = type;
1399
1400 return (ret);
1401 }
1402
1403 static void
raid_handle_delete(raid_obj_handle_t handle)1404 raid_handle_delete(raid_obj_handle_t handle)
1405 {
1406 int i = raid_handle_sys.used, j = 0;
1407
1408 if (handle == 0)
1409 return;
1410
1411 while (i != 0 && i != handle) {
1412 j = i;
1413 i = raid_handle_sys.handles[i].next;
1414 }
1415
1416 if (i == handle) {
1417 if (j != 0)
1418 raid_handle_sys.handles[j].next =
1419 raid_handle_sys.handles[i].next;
1420 else
1421 raid_handle_sys.used =
1422 raid_handle_sys.handles[i].next;
1423
1424 raid_handle_sys.handles[i].type = OBJ_TYPE_ALL;
1425 raid_handle_sys.handles[i].next =
1426 raid_handle_sys.unused;
1427 raid_handle_sys.unused = i;
1428 }
1429 }
1430
1431 static void
raid_handle_delete_controller_comp(uint32_t controller_id)1432 raid_handle_delete_controller_comp(uint32_t controller_id)
1433 {
1434 int i = raid_handle_sys.used, j;
1435
1436 while (i != 0) {
1437 j = i;
1438 i = raid_handle_sys.handles[i].next;
1439 if ((raid_handle_sys.handles[j].controller_id ==
1440 controller_id) &&
1441 (raid_handle_sys.handles[j].type !=
1442 OBJ_TYPE_CONTROLLER))
1443 raid_handle_delete(j);
1444 }
1445 }
1446
1447 static raid_obj_id_t
raid_handle_to_obj(raid_obj_tab_t * raid_tab,raid_obj_handle_t handle)1448 raid_handle_to_obj(raid_obj_tab_t *raid_tab, raid_obj_handle_t handle)
1449 {
1450 handle_attr_t *handle_attr;
1451 raid_obj_id_t obj_id;
1452
1453 if (handle == OBJ_SYSTEM)
1454 return (OBJ_SYSTEM);
1455
1456 handle_attr = raid_handle_sys.handles + handle;
1457
1458 switch (handle_attr->type) {
1459 case OBJ_TYPE_SYSTEM:
1460 return (OBJ_SYSTEM);
1461 case OBJ_TYPE_CONTROLLER:
1462 obj_id = obj_locate_controller(raid_tab,
1463 handle_attr->controller_id);
1464 break;
1465 case OBJ_TYPE_ARRAY:
1466 obj_id = obj_locate_array(raid_tab,
1467 handle_attr->controller_id, handle_attr->array_id);
1468 break;
1469 case OBJ_TYPE_HSP:
1470 obj_id = obj_locate_hsp(raid_tab,
1471 handle_attr->controller_id, handle_attr->disk_id,
1472 handle_attr->array_id);
1473 break;
1474 case OBJ_TYPE_DISK:
1475 obj_id = obj_locate_disk(raid_tab,
1476 handle_attr->controller_id, handle_attr->disk_id);
1477 break;
1478 case OBJ_TYPE_ARRAY_PART:
1479 obj_id = obj_locate_arraypart(raid_tab,
1480 handle_attr->controller_id, handle_attr->array_id,
1481 handle_attr->disk_id);
1482 break;
1483 case OBJ_TYPE_DISK_SEG:
1484 obj_id = obj_locate_diskseg(raid_tab,
1485 handle_attr->controller_id,
1486 handle_attr->disk_id, handle_attr->seq_id);
1487 break;
1488 case OBJ_TYPE_TASK:
1489 obj_id = obj_locate_task(raid_tab,
1490 handle_attr->controller_id, handle_attr->task_id);
1491 break;
1492 case OBJ_TYPE_PROP:
1493 obj_id = obj_locate_prop(raid_tab,
1494 handle_attr->controller_id, handle_attr->disk_id,
1495 handle_attr->prop_id);
1496 break;
1497 default:
1498 return (ERR_DEVICE_INVALID);
1499 }
1500
1501 if (obj_id < OBJ_NONE)
1502 return (obj_id);
1503 if (obj_id == OBJ_NONE)
1504 return (ERR_DEVICE_NOENT);
1505
1506 (void) raid_obj_set_handle(raid_tab, obj_id, handle);
1507 return (obj_id);
1508 }
1509
1510 static raid_obj_handle_t
raid_obj_to_handle(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)1511 raid_obj_to_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
1512 {
1513 raid_obj_id_t obj_id_backup = obj_id;
1514 raid_obj_type_id_t type;
1515 raid_obj_handle_t handle;
1516 controller_attr_t *controller_attr;
1517 array_attr_t *array_attr;
1518 hsp_attr_t *hsp_attr;
1519 disk_attr_t *disk_attr;
1520 arraypart_attr_t *arraypart_attr;
1521 diskseg_attr_t *diskseg_attr;
1522 task_attr_t *task_attr;
1523 property_attr_t *prop_attr;
1524
1525 if (obj_id == OBJ_SYSTEM)
1526 return (OBJ_SYSTEM);
1527
1528 /* If the object mapped by a handle */
1529 handle = raid_obj_get_handle(raid_tab, obj_id);
1530 if (handle != 0)
1531 return (handle);
1532
1533 /* Search for existing handles */
1534 for (handle = raid_handle_sys.used; handle != 0;
1535 handle = raid_handle_sys.handles[handle].next)
1536 if (raid_handle_to_obj(raid_tab, handle) == obj_id)
1537 break;
1538
1539 if (handle != 0)
1540 return (handle);
1541
1542 /* Allocate new handle for this object */
1543 type = raid_obj_get_type(raid_tab, obj_id);
1544 handle = raid_handle_new(type);
1545 (void) raid_obj_set_handle(raid_tab, obj_id, handle);
1546 raid_handle_sys.handles[handle].type = type;
1547
1548 switch (type) {
1549 case OBJ_TYPE_SYSTEM:
1550 break;
1551 case OBJ_TYPE_CONTROLLER:
1552 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1553 raid_handle_sys.handles[handle].controller_id =
1554 controller_attr->controller_id;
1555 break;
1556 case OBJ_TYPE_ARRAY:
1557 array_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1558 raid_handle_sys.handles[handle].array_id = array_attr->array_id;
1559 obj_id = obj_get_controller(raid_tab, obj_id);
1560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1561 raid_handle_sys.handles[handle].controller_id =
1562 controller_attr->controller_id;
1563 break;
1564 case OBJ_TYPE_HSP:
1565 hsp_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1566 raid_handle_sys.handles[handle].array_id =
1567 hsp_attr->associated_id;
1568 obj_id = raid_obj_get_container(raid_tab, obj_id);
1569 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1570 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id;
1571 obj_id = obj_get_controller(raid_tab, obj_id);
1572 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1573 raid_handle_sys.handles[handle].controller_id =
1574 controller_attr->controller_id;
1575 break;
1576 case OBJ_TYPE_DISK:
1577 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1578 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id;
1579 obj_id = obj_get_controller(raid_tab, obj_id);
1580 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1581 raid_handle_sys.handles[handle].controller_id =
1582 controller_attr->controller_id;
1583 break;
1584 case OBJ_TYPE_ARRAY_PART:
1585 arraypart_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1586 raid_handle_sys.handles[handle].disk_id =
1587 arraypart_attr->disk_id;
1588 obj_id = raid_obj_get_container(raid_tab, obj_id);
1589 array_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1590 raid_handle_sys.handles[handle].array_id =
1591 array_attr->array_id;
1592 obj_id = obj_get_controller(raid_tab, obj_id);
1593 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1594 raid_handle_sys.handles[handle].controller_id =
1595 controller_attr->controller_id;
1596 break;
1597 case OBJ_TYPE_DISK_SEG:
1598 diskseg_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1599 raid_handle_sys.handles[handle].seq_id = diskseg_attr->seq_no;
1600 obj_id = raid_obj_get_container(raid_tab, obj_id);
1601 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1602 raid_handle_sys.handles[handle].disk_id =
1603 disk_attr->disk_id;
1604 obj_id = obj_get_controller(raid_tab, obj_id);
1605 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1606 raid_handle_sys.handles[handle].controller_id =
1607 controller_attr->controller_id;
1608 break;
1609 case OBJ_TYPE_TASK:
1610 task_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1611 raid_handle_sys.handles[handle].task_id = task_attr->task_id;
1612 obj_id = obj_get_controller(raid_tab, obj_id);
1613 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1614 raid_handle_sys.handles[handle].controller_id =
1615 controller_attr->controller_id;
1616 break;
1617 case OBJ_TYPE_PROP:
1618 prop_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1619 raid_handle_sys.handles[handle].prop_id =
1620 prop_attr->prop_id;
1621 obj_id = raid_obj_get_container(raid_tab, obj_id);
1622 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1623 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id;
1624 obj_id = obj_get_controller(raid_tab, obj_id);
1625 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1626 raid_handle_sys.handles[handle].controller_id =
1627 controller_attr->controller_id;
1628 break;
1629 default:
1630 return (ERR_DEVICE_INVALID);
1631 }
1632
1633 (void) raid_obj_set_handle(raid_tab, obj_id_backup, handle);
1634 return (handle);
1635 }
1636
1637 static raid_lib_t *
raid_obj_get_lib(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)1638 raid_obj_get_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
1639 {
1640 raid_obj_handle_t handle;
1641 controller_attr_t *attr;
1642
1643 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
1644 return (NULL);
1645
1646 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1647 handle = raid_handle_sys.used;
1648 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER ||
1649 raid_handle_sys.handles[handle].controller_id !=
1650 attr->controller_id)
1651 handle = raid_handle_sys.handles[handle].next;
1652
1653 if (handle == 0)
1654 return (NULL);
1655
1656 return (raid_handle_sys.handles[handle].raid_lib);
1657 }
1658
1659 static int
raid_obj_set_lib(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_lib_t * raid_lib)1660 raid_obj_set_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
1661 raid_lib_t *raid_lib)
1662 {
1663 raid_obj_handle_t handle;
1664 controller_attr_t *attr;
1665
1666 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
1667 return (ERR_DEVICE_TYPE);
1668
1669 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1670 handle = raid_handle_sys.used;
1671 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER ||
1672 raid_handle_sys.handles[handle].controller_id !=
1673 attr->controller_id)
1674 handle = raid_handle_sys.handles[handle].next;
1675
1676 if (handle == 0)
1677 return (ERR_DEVICE_NOENT);
1678
1679 raid_handle_sys.handles[handle].raid_lib = raid_lib;
1680 return (SUCCESS);
1681 }
1682
1683 static int
raid_obj_get_fd(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)1684 raid_obj_get_fd(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
1685 {
1686 raid_obj_handle_t handle;
1687 controller_attr_t *attr;
1688
1689 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
1690 return (ERR_DEVICE_TYPE);
1691
1692 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1693 handle = raid_handle_sys.used;
1694 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER ||
1695 raid_handle_sys.handles[handle].controller_id !=
1696 attr->controller_id)
1697 handle = raid_handle_sys.handles[handle].next;
1698
1699 if (handle == 0)
1700 return (ERR_DEVICE_NOENT);
1701
1702 return (raid_handle_sys.handles[handle].fd);
1703 }
1704
1705 static int
raid_obj_set_fd(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,int fd)1706 raid_obj_set_fd(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, int fd)
1707 {
1708 raid_obj_handle_t handle;
1709 controller_attr_t *attr;
1710
1711 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
1712 return (ERR_DEVICE_TYPE);
1713
1714 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1715 handle = raid_handle_sys.used;
1716 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER ||
1717 raid_handle_sys.handles[handle].controller_id !=
1718 attr->controller_id)
1719 handle = raid_handle_sys.handles[handle].next;
1720
1721 if (handle == 0)
1722 return (ERR_DEVICE_NOENT);
1723
1724 raid_handle_sys.handles[handle].fd = fd;
1725 return (SUCCESS);
1726 }
1727
1728 /*
1729 * Raid object maintenance routines
1730 */
1731 static int
obj_scan_comp(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)1732 obj_scan_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
1733 {
1734 raid_obj_status_t status;
1735 raid_obj_type_id_t type;
1736 int ret, i, obj_type_cnt, comp_num;
1737 raid_obj_id_t *comp_list;
1738
1739 status = raid_obj_get_status(raid_tab, obj_id);
1740 if (status < SUCCESS)
1741 return (status);
1742
1743 if (status & OBJ_STATUS_SCANCOMP)
1744 return (SUCCESS);
1745
1746 type = raid_obj_get_type(raid_tab, obj_id);
1747 /* type less than OBJ_TYPE_SYSTEM means error */
1748 if (type < OBJ_TYPE_SYSTEM)
1749 return (ERR_DEVICE_INVALID);
1750
1751 for (obj_type_cnt = OBJ_SYSTEM; obj_type_cnt < OBJ_TYPE_ALL;
1752 ++obj_type_cnt) {
1753 if (raid_obj_op_sys[type].compnum != NULL)
1754 comp_num = raid_obj_op_sys[type].compnum(
1755 raid_tab, obj_id, obj_type_cnt);
1756 else
1757 comp_num = 0;
1758
1759 if (comp_num < SUCCESS)
1760 return (comp_num);
1761 if (comp_num == 0)
1762 continue;
1763
1764 comp_list = calloc(comp_num, sizeof (raid_obj_id_t));
1765 if (comp_list == NULL)
1766 return (ERR_NOMEM);
1767
1768 for (i = 0; i < comp_num; ++i) {
1769 *(comp_list + i) = raid_obj_create(raid_tab,
1770 obj_type_cnt);
1771 if (*(comp_list + i) < SUCCESS) {
1772 ret = *(comp_list + i);
1773 free(comp_list);
1774 return (ret);
1775 }
1776
1777 (void) raid_obj_clear_status(raid_tab,
1778 *(comp_list + i), OBJ_STATUS_CMD_CLEAN);
1779 (void) raid_obj_add_org(raid_tab, *(comp_list + i),
1780 obj_id);
1781 }
1782
1783 if (raid_obj_op_sys[type].complist != NULL)
1784 raid_obj_op_sys[type].complist(raid_tab,
1785 obj_id, comp_num, comp_list, obj_type_cnt);
1786 free(comp_list);
1787 }
1788
1789 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_SCANCOMP);
1790 return (SUCCESS);
1791 }
1792
1793 static int
obj_rescan(raid_obj_tab_t * raid_tab)1794 obj_rescan(raid_obj_tab_t *raid_tab)
1795 {
1796 int ret;
1797
1798 raid_obj_tab_destroy(raid_tab);
1799
1800 if (raid_obj_tab_create(raid_tab, HASH_SLOTS) != SUCCESS)
1801 return (ERR_NOMEM);
1802
1803 if ((ret = raid_obj_create_system_obj(raid_tab)) != SUCCESS) {
1804 raid_obj_tab_destroy(raid_tab);
1805 return (ret);
1806 }
1807
1808 return (SUCCESS);
1809 }
1810
1811 static raid_obj_id_t
obj_get_comp(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_type_id_t obj_type)1812 obj_get_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
1813 raid_obj_type_id_t obj_type)
1814 {
1815 raid_obj_id_t id;
1816 raid_obj_type_id_t type;
1817 raid_obj_status_t status;
1818 int ret;
1819
1820 if ((obj_type < OBJ_TYPE_SYSTEM) || (obj_type > OBJ_TYPE_ALL))
1821 return (ERR_DEVICE_TYPE);
1822
1823 status = raid_obj_get_status(raid_tab, obj_id);
1824 if (status < SUCCESS)
1825 return (status);
1826
1827 if (!(status & OBJ_STATUS_SCANCOMP)) {
1828 ret = obj_scan_comp(raid_tab, obj_id);
1829 if (ret < SUCCESS)
1830 return (ret);
1831 }
1832
1833 id = raid_obj_get_comp(raid_tab, obj_id);
1834 if (id <= OBJ_NONE)
1835 return (id);
1836
1837 type = raid_obj_get_type(raid_tab, id);
1838 if (type < OBJ_TYPE_SYSTEM)
1839 return (type);
1840
1841 if (type == obj_type)
1842 return (id);
1843
1844 while (id > OBJ_NONE) {
1845 id = raid_obj_get_sibling(raid_tab, id);
1846 if (id <= OBJ_NONE)
1847 return (id);
1848
1849 type = raid_obj_get_type(raid_tab, id);
1850 if (type < OBJ_TYPE_SYSTEM)
1851 return (type);
1852
1853 if (type == obj_type)
1854 break;
1855 };
1856
1857 return (id);
1858 }
1859
1860 static raid_obj_id_t
obj_get_sibling(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)1861 obj_get_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
1862 {
1863 raid_obj_id_t id;
1864 raid_obj_type_id_t type, obj_type;
1865
1866 id = obj_id;
1867 obj_type = raid_obj_get_type(raid_tab, id);
1868 if (obj_type < OBJ_TYPE_SYSTEM)
1869 return (obj_type);
1870
1871 do {
1872 id = raid_obj_get_sibling(raid_tab, id);
1873 if (id < OBJ_NONE)
1874 return (id);
1875
1876 type = raid_obj_get_type(raid_tab, id);
1877 if (type < OBJ_TYPE_SYSTEM)
1878 return (type);
1879 } while ((type != obj_type) && (id != OBJ_NONE));
1880
1881 return (id);
1882 }
1883
1884 static int
obj_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,void ** data)1885 obj_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, void **data)
1886 {
1887 raid_obj_type_id_t type;
1888 raid_obj_status_t status;
1889 void *attr;
1890 int ret = SUCCESS;
1891
1892 status = raid_obj_get_status(raid_tab, obj_id);
1893 if (status < SUCCESS)
1894 return (status);
1895
1896 type = raid_obj_get_type(raid_tab, obj_id);
1897 if (type < OBJ_TYPE_SYSTEM)
1898 return (type);
1899
1900 if (!(status & OBJ_STATUS_OPENED)) {
1901 if (raid_obj_op_sys[type].get_attr == NULL)
1902 (void) raid_obj_set_status(raid_tab, obj_id,
1903 OBJ_STATUS_OPENED);
1904 else
1905 ret = raid_obj_op_sys[type].get_attr(raid_tab, obj_id);
1906 }
1907 if (ret < SUCCESS)
1908 return (ret);
1909
1910 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1911 if (attr == NULL && type != OBJ_TYPE_SYSTEM)
1912 return (ERR_DEVICE_INVALID);
1913
1914 *data = attr;
1915 return (SUCCESS);
1916 }
1917
1918 static raid_obj_id_t
obj_locate_controller(raid_obj_tab_t * raid_tab,uint32_t controller_id)1919 obj_locate_controller(raid_obj_tab_t *raid_tab, uint32_t controller_id)
1920 {
1921 raid_obj_id_t obj_id;
1922 controller_attr_t *attr;
1923
1924 obj_id = obj_get_comp(raid_tab, OBJ_SYSTEM, OBJ_TYPE_CONTROLLER);
1925 if (obj_id <= OBJ_NONE)
1926 return (obj_id);
1927
1928 do {
1929 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1930 if (attr == NULL)
1931 return (ERR_DEVICE_INVALID);
1932
1933 if (attr->controller_id == controller_id)
1934 break;
1935 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) != OBJ_NONE);
1936
1937 return (obj_id);
1938 }
1939
1940 static raid_obj_id_t
obj_locate_array(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t array_id)1941 obj_locate_array(raid_obj_tab_t *raid_tab, uint32_t controller_id,
1942 uint32_t array_id)
1943 {
1944 raid_obj_id_t obj_id;
1945
1946 obj_id = obj_locate_controller(raid_tab, controller_id);
1947 if (obj_id < OBJ_NONE)
1948 return (obj_id);
1949
1950 obj_id = obj_locate_array_recur(raid_tab, obj_id, array_id);
1951
1952 return (obj_id);
1953 }
1954
1955 static raid_obj_id_t
obj_locate_array_recur(raid_obj_tab_t * raid_tab,raid_obj_id_t container_obj_id,uint32_t array_id)1956 obj_locate_array_recur(raid_obj_tab_t *raid_tab,
1957 raid_obj_id_t container_obj_id, uint32_t array_id)
1958 {
1959 raid_obj_id_t obj_id, ret;
1960 array_attr_t *attr;
1961
1962 obj_id = obj_get_comp(raid_tab, container_obj_id, OBJ_TYPE_ARRAY);
1963 if (obj_id <= OBJ_NONE)
1964 return (obj_id);
1965
1966 do {
1967 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
1968 if (attr == NULL)
1969 return (ERR_DEVICE_INVALID);
1970
1971 if (attr->array_id == array_id)
1972 break;
1973
1974 ret = obj_locate_array_recur(raid_tab, obj_id, array_id);
1975 if (ret != OBJ_NONE)
1976 return (ret);
1977
1978 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE);
1979
1980 return (obj_id);
1981 }
1982
1983 static raid_obj_id_t
obj_locate_hsp(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t disk_id,uint32_t array_id)1984 obj_locate_hsp(raid_obj_tab_t *raid_tab, uint32_t controller_id,
1985 uint32_t disk_id, uint32_t array_id)
1986 {
1987 raid_obj_id_t obj_id;
1988 hsp_attr_t *hsp_attr;
1989
1990 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id);
1991 if (obj_id <= OBJ_NONE)
1992 return (obj_id);
1993
1994 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_HSP);
1995 if (obj_id <= OBJ_NONE)
1996 return (obj_id);
1997
1998 do {
1999 (void) obj_get_attr(raid_tab, obj_id, (void **)(&hsp_attr));
2000 if (hsp_attr->associated_id == array_id)
2001 break;
2002
2003 obj_id = obj_get_sibling(raid_tab, obj_id);
2004 if (obj_id < OBJ_NONE)
2005 return (obj_id);
2006 } while (obj_id > OBJ_NONE);
2007
2008 return (obj_id);
2009 }
2010
2011 static raid_obj_id_t
obj_locate_disk(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t disk_id)2012 obj_locate_disk(raid_obj_tab_t *raid_tab, uint32_t controller_id,
2013 uint32_t disk_id)
2014 {
2015 raid_obj_id_t obj_id;
2016 disk_attr_t *attr;
2017
2018 obj_id = obj_locate_controller(raid_tab, controller_id);
2019 if (obj_id <= OBJ_NONE)
2020 return (obj_id);
2021
2022 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK);
2023 if (obj_id <= OBJ_NONE)
2024 return (obj_id);
2025
2026 do {
2027 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2028 if (attr == NULL)
2029 return (ERR_DEVICE_INVALID);
2030
2031 if (attr->disk_id == disk_id)
2032 break;
2033 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE);
2034
2035 return (obj_id);
2036 }
2037
2038 static raid_obj_id_t
obj_locate_arraypart(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t array_id,uint32_t disk_id)2039 obj_locate_arraypart(raid_obj_tab_t *raid_tab, uint32_t controller_id,
2040 uint32_t array_id, uint32_t disk_id)
2041 {
2042 raid_obj_id_t obj_id;
2043
2044 arraypart_attr_t *attr;
2045
2046 obj_id = obj_locate_array(raid_tab, controller_id, array_id);
2047 if (obj_id <= OBJ_NONE)
2048 return (obj_id);
2049
2050 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY_PART);
2051 if (obj_id <= OBJ_NONE)
2052 return (obj_id);
2053
2054 do {
2055 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2056 if (attr == NULL)
2057 return (ERR_DEVICE_INVALID);
2058
2059 if (attr->disk_id == disk_id)
2060 break;
2061 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) >
2062 OBJ_NONE);
2063
2064 return (obj_id);
2065 }
2066
2067 static raid_obj_id_t
obj_locate_diskseg(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t disk_id,uint32_t seq_no)2068 obj_locate_diskseg(raid_obj_tab_t *raid_tab, uint32_t controller_id,
2069 uint32_t disk_id, uint32_t seq_no)
2070 {
2071 raid_obj_id_t obj_id;
2072 diskseg_attr_t *attr;
2073
2074 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id);
2075 if (obj_id <= OBJ_NONE)
2076 return (obj_id);
2077
2078 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK_SEG);
2079 if (obj_id <= OBJ_NONE)
2080 return (obj_id);
2081
2082 do {
2083 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2084 if (attr == NULL)
2085 return (ERR_DEVICE_INVALID);
2086
2087 if (attr->seq_no == seq_no)
2088 break;
2089 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE);
2090
2091 return (obj_id);
2092 }
2093
2094 static raid_obj_id_t
obj_locate_task(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t task_id)2095 obj_locate_task(raid_obj_tab_t *raid_tab, uint32_t controller_id,
2096 uint32_t task_id)
2097 {
2098 raid_obj_id_t obj_id, obj_id2, task_obj_id;
2099 task_attr_t *attr;
2100
2101 obj_id = obj_locate_controller(raid_tab, controller_id);
2102 if (obj_id <= OBJ_NONE)
2103 return (obj_id);
2104
2105 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY);
2106 if (obj_id < OBJ_NONE)
2107 return (obj_id);
2108
2109 do {
2110 obj_id2 = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY);
2111 while (obj_id2 != OBJ_NONE) {
2112 task_obj_id = obj_get_comp(raid_tab, obj_id2,
2113 OBJ_TYPE_TASK);
2114
2115 if (task_obj_id < OBJ_NONE)
2116 return (task_obj_id);
2117
2118 if (task_obj_id == OBJ_NONE) {
2119 obj_id2 = obj_get_sibling(raid_tab, obj_id2);
2120 continue;
2121 }
2122
2123 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id);
2124 if (attr == NULL)
2125 return (ERR_DEVICE_INVALID);
2126
2127 if (attr->task_id == task_id)
2128 return (task_obj_id);
2129
2130 obj_id2 = obj_get_sibling(raid_tab, obj_id2);
2131 }
2132
2133 task_obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_TASK);
2134 if (task_obj_id < OBJ_NONE)
2135 return (task_obj_id);
2136
2137 if (task_obj_id == OBJ_NONE)
2138 continue;
2139
2140 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id);
2141 if (attr == NULL)
2142 return (ERR_DEVICE_INVALID);
2143
2144 if (attr->task_id == task_id)
2145 return (task_obj_id);
2146 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE);
2147
2148 if (obj_id < OBJ_NONE)
2149 return (obj_id);
2150
2151 obj_id = obj_locate_controller(raid_tab, controller_id);
2152 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK);
2153 if (obj_id < OBJ_NONE)
2154 return (obj_id);
2155
2156 do {
2157 task_obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_TASK);
2158 if (task_obj_id < OBJ_NONE)
2159 return (task_obj_id);
2160
2161 if (task_obj_id == OBJ_NONE)
2162 continue;
2163
2164 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id);
2165 if (attr == NULL)
2166 return (ERR_DEVICE_INVALID);
2167
2168 if (attr->task_id == task_id)
2169 return (task_obj_id);
2170 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE);
2171
2172 return (obj_id);
2173 }
2174
2175 static raid_obj_id_t
obj_locate_prop(raid_obj_tab_t * raid_tab,uint32_t controller_id,uint32_t disk_id,uint32_t prop_id)2176 obj_locate_prop(raid_obj_tab_t *raid_tab, uint32_t controller_id,
2177 uint32_t disk_id, uint32_t prop_id)
2178 {
2179 raid_obj_id_t obj_id;
2180 property_attr_t *prop_attr;
2181
2182 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id);
2183 if (obj_id < OBJ_NONE)
2184 return (obj_id);
2185
2186 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_PROP);
2187 if (obj_id <= OBJ_NONE)
2188 return (obj_id);
2189
2190 do {
2191 (void) obj_get_attr(raid_tab, obj_id, (void **)(&prop_attr));
2192 if (prop_attr->prop_id == prop_id)
2193 break;
2194
2195 obj_id = obj_get_sibling(raid_tab, obj_id);
2196 if (obj_id < OBJ_NONE)
2197 return (obj_id);
2198 } while (obj_id > OBJ_NONE);
2199
2200 return (obj_id);
2201 }
2202
2203 static raid_obj_id_t
obj_get_controller(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)2204 obj_get_controller(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
2205 {
2206 raid_obj_id_t id = obj_id;
2207
2208 while (raid_obj_get_type(raid_tab, id) != OBJ_TYPE_CONTROLLER) {
2209 id = raid_obj_get_container(raid_tab, id);
2210 if ((id == OBJ_SYSTEM) || (id < OBJ_NONE))
2211 return (ERR_DEVICE_INVALID);
2212 }
2213
2214 return (id);
2215 }
2216
2217 /*
2218 * Raid object operation routines
2219 */
2220 static int
obj_sys_compnum(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_type_id_t comp_type)2221 obj_sys_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2222 raid_obj_type_id_t comp_type)
2223 {
2224 DIR *dir;
2225 struct dirent *dp;
2226 int num = 0;
2227
2228 if ((raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_SYSTEM))
2229 return (ERR_DEVICE_TYPE);
2230
2231 if (comp_type != OBJ_TYPE_CONTROLLER)
2232 return (0);
2233
2234 if ((dir = opendir(CFGDIR)) == NULL)
2235 return (ERR_DRIVER_NOT_FOUND);
2236
2237 while ((dp = readdir(dir)) != NULL) {
2238 uint32_t controller_id;
2239 char path[MAX_PATH_LEN];
2240
2241 if (strcmp(dp->d_name, ".") == 0 ||
2242 strcmp(dp->d_name, "..") == 0)
2243 continue;
2244
2245 if (sscanf(dp->d_name, "c%u", &controller_id) != 1)
2246 continue;
2247
2248 if (controller_id_to_path(controller_id, path) == SUCCESS)
2249 ++ num;
2250 }
2251
2252 (void) closedir(dir);
2253 return (num);
2254 }
2255
2256 static int
obj_sys_complist(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,int num,raid_obj_id_t * comp_list,raid_obj_type_id_t comp_type)2257 obj_sys_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2258 int num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type)
2259 {
2260 DIR *dir;
2261 struct dirent *dp;
2262 controller_attr_t *attr;
2263 uint32_t controller_id;
2264 uint32_t *tmplist;
2265 char path[MAX_PATH_LEN];
2266 int i = 0;
2267
2268 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_SYSTEM)
2269 return (ERR_DEVICE_TYPE);
2270 if ((num <= 0) || (comp_list == NULL))
2271 return (ERR_OP_ILLEGAL);
2272
2273 if (comp_type != OBJ_TYPE_CONTROLLER)
2274 return (0);
2275
2276 if ((dir = opendir(CFGDIR)) == NULL)
2277 return (ERR_DRIVER_NOT_FOUND);
2278 tmplist = calloc(num, sizeof (uint32_t));
2279 if (tmplist == NULL) {
2280 return (ERR_NOMEM);
2281 }
2282 while ((dp = readdir(dir)) != NULL) {
2283 if (strcmp(dp->d_name, ".") == 0 ||
2284 strcmp(dp->d_name, "..") == 0)
2285 continue;
2286
2287 if (sscanf(dp->d_name, "c%u", &controller_id) != 1)
2288 continue;
2289
2290 if (controller_id_to_path(controller_id, path) == SUCCESS) {
2291 tmplist[i] = controller_id;
2292 ++ i;
2293 }
2294 }
2295 qsort((void *)tmplist, num, sizeof (uint32_t), intcompare);
2296 for (i = 0; i < num; i++) {
2297 attr = raid_obj_get_data_ptr(raid_tab,
2298 *(comp_list + i));
2299
2300 if (attr == NULL) {
2301 free(tmplist);
2302 return (ERR_DEVICE_INVALID);
2303 }
2304
2305 attr->controller_id = tmplist[i];
2306 }
2307 free(tmplist);
2308 (void) closedir(dir);
2309 return (SUCCESS);
2310 }
2311
2312 static int
obj_controller_compnum(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_type_id_t comp_type)2313 obj_controller_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2314 raid_obj_type_id_t comp_type)
2315 {
2316 raid_lib_t *raid_lib;
2317 int ret = SUCCESS, fd;
2318 controller_attr_t *ctl_attrp;
2319
2320 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
2321 return (ERR_DEVICE_TYPE);
2322
2323 if ((comp_type != OBJ_TYPE_ARRAY) && (comp_type != OBJ_TYPE_DISK))
2324 return (0);
2325
2326 raid_lib = raid_obj_get_lib(raid_tab, obj_id);
2327 fd = raid_obj_get_fd(raid_tab, obj_id);
2328 ctl_attrp = raid_obj_get_data_ptr(raid_tab, obj_id);
2329 if ((raid_lib == NULL) || (ctl_attrp == NULL) || (fd == 0))
2330 return (ERR_DRIVER_CLOSED);
2331
2332 ret = raid_lib->compnum(ctl_attrp->controller_id, 0,
2333 OBJ_TYPE_CONTROLLER, comp_type);
2334
2335 return (ret);
2336 }
2337
2338 static int
obj_controller_complist(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,int comp_num,raid_obj_id_t * comp_list,raid_obj_type_id_t comp_type)2339 obj_controller_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2340 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type)
2341 {
2342 raid_lib_t *raid_lib;
2343 controller_attr_t *ctl_attrp;
2344 int ret, i, fd;
2345 uint32_t *ids;
2346
2347 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
2348 return (ERR_DEVICE_TYPE);
2349
2350 if ((comp_type != OBJ_TYPE_ARRAY) && (comp_type != OBJ_TYPE_DISK))
2351 return (0);
2352
2353 if ((comp_num <= 0) || (comp_list == NULL))
2354 return (ERR_OP_ILLEGAL);
2355
2356 for (i = 0; i < comp_num; ++i)
2357 if (raid_obj_get_type(raid_tab, *(comp_list + i)) !=
2358 comp_type)
2359 return (ERR_DEVICE_TYPE);
2360
2361 raid_lib = raid_obj_get_lib(raid_tab, obj_id);
2362 ctl_attrp = raid_obj_get_data_ptr(raid_tab, obj_id);
2363 fd = raid_obj_get_fd(raid_tab, obj_id);
2364 if ((raid_lib == NULL) || (ctl_attrp == NULL)|| (fd == 0))
2365 return (ERR_DRIVER_CLOSED);
2366
2367 ids = malloc(comp_num * sizeof (uint32_t));
2368 if (ids == NULL)
2369 return (ERR_NOMEM);
2370
2371 ret = raid_lib->complist(ctl_attrp->controller_id, 0,
2372 OBJ_TYPE_CONTROLLER, comp_type, comp_num, ids);
2373 if (ret < SUCCESS) {
2374 free(ids);
2375 return (ret);
2376 }
2377 qsort((void *)ids, comp_num, sizeof (uint32_t), intcompare);
2378 for (i = 0; i < comp_num; ++ i) {
2379 array_attr_t *array_attr;
2380 disk_attr_t *disk_attr;
2381 void *attr_buf;
2382
2383 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i));
2384 if (attr_buf == NULL) {
2385 free(ids);
2386 return (ERR_DEVICE_INVALID);
2387 }
2388
2389 switch (comp_type) {
2390 case OBJ_TYPE_ARRAY:
2391 array_attr = attr_buf;
2392 array_attr->array_id = *(ids + i);
2393 break;
2394 case OBJ_TYPE_DISK:
2395 disk_attr = attr_buf;
2396 disk_attr->disk_id = *(ids + i);
2397 break;
2398 default:
2399 free(ids);
2400 return (ERR_DEVICE_INVALID);
2401 }
2402 }
2403
2404 free(ids);
2405 return (SUCCESS);
2406 }
2407
2408 static int
obj_controller_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)2409 obj_controller_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
2410 {
2411 controller_attr_t *attr;
2412 raid_lib_t *raid_lib;
2413 int ret = SUCCESS, fd;
2414
2415 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
2416 return (ERR_DEVICE_TYPE);
2417
2418 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
2419 return (SUCCESS);
2420
2421 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2422 if (attr == NULL)
2423 return (ERR_DEVICE_INVALID);
2424
2425 raid_lib = raid_obj_get_lib(raid_tab, obj_id);
2426 fd = raid_obj_get_fd(raid_tab, obj_id);
2427
2428 /*
2429 * For a controller, even it's not opened, we can still
2430 * get the driver name
2431 */
2432
2433 if (fd == 0)
2434 return (SUCCESS);
2435
2436 if (raid_lib == NULL) {
2437 return (SUCCESS);
2438 }
2439
2440 ret = raid_lib->get_attr(attr->controller_id, OBJ_ATTR_NONE,
2441 OBJ_ATTR_NONE, OBJ_TYPE_CONTROLLER, attr);
2442 if (ret < SUCCESS)
2443 return (ret);
2444
2445 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
2446
2447 return (ret);
2448 }
2449
2450 static int
obj_controller_act(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,uint32_t sub_cmd,void * prop_list,char ** plugin_err_str)2451 obj_controller_act(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2452 uint32_t sub_cmd, void *prop_list, char **plugin_err_str)
2453 {
2454 controller_attr_t *attr;
2455 raid_lib_t *raid_lib;
2456 int ret, fd;
2457
2458 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER)
2459 return (ERR_DEVICE_TYPE);
2460
2461 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2462
2463 raid_lib = raid_obj_get_lib(raid_tab, obj_id);
2464 fd = raid_obj_get_fd(raid_tab, obj_id);
2465
2466 switch (sub_cmd) {
2467 case ACT_CONTROLLER_OPEN:
2468 /* Check if already opened */
2469
2470 if (fd > 0)
2471 return (SUCCESS);
2472
2473 /* Check if plugin is already attached */
2474 if (raid_lib == NULL) {
2475 raid_lib = raid_find_lib(raid_tab, obj_id);
2476 if (raid_lib == NULL)
2477 return (ERR_DRIVER_NOT_FOUND);
2478 }
2479
2480 ret = raid_lib->open_controller(attr->controller_id,
2481 plugin_err_str);
2482 if (ret == SUCCESS) {
2483 (void) raid_obj_set_lib(raid_tab, obj_id, raid_lib);
2484 (void) raid_obj_set_fd(raid_tab, obj_id, 1);
2485 }
2486 break;
2487 case ACT_CONTROLLER_CLOSE:
2488
2489 if (fd <= 0)
2490 return (SUCCESS);
2491
2492 if (raid_lib == NULL) {
2493 return (SUCCESS);
2494 }
2495 ret = raid_lib->close_controller(attr->controller_id,
2496 plugin_err_str);
2497 if (ret == SUCCESS) {
2498 (void) raid_obj_set_fd(raid_tab, obj_id, 0);
2499 (void) raid_obj_set_lib(raid_tab, obj_id, NULL);
2500 raid_handle_delete_controller_comp(attr->controller_id);
2501 }
2502 break;
2503 case ACT_CONTROLLER_FLASH_FW:
2504 {
2505 char *filebuf;
2506 int image_fd;
2507 uint32_t size;
2508 struct stat statbuf;
2509
2510 if (prop_list == NULL)
2511 return (ERR_OP_ILLEGAL);
2512
2513 /* Open firmware image file */
2514 image_fd = open((const char *)prop_list,
2515 O_RDONLY | O_NDELAY);
2516 if (image_fd == -1)
2517 return (ERR_OP_FAILED);
2518
2519 if (fstat(image_fd, &statbuf) != 0) {
2520 (void) close(image_fd);
2521 return (ERR_OP_FAILED);
2522 }
2523
2524 filebuf = malloc(statbuf.st_size);
2525 if (filebuf == NULL) {
2526 (void) close(image_fd);
2527 return (ERR_NOMEM);
2528 }
2529
2530 size = read(image_fd, filebuf, statbuf.st_size);
2531 if (size != statbuf.st_size) {
2532 (void) close(image_fd);
2533 free(filebuf);
2534 return (ERR_OP_FAILED);
2535 }
2536
2537 if (fd <= 0) {
2538 (void) close(image_fd);
2539 free(filebuf);
2540 return (ERR_DRIVER_CLOSED);
2541 }
2542
2543 if (raid_lib == NULL) {
2544 (void) close(image_fd);
2545 free(filebuf);
2546 return (ERR_DRIVER_CLOSED);
2547 }
2548 if (raid_lib->flash_fw == NULL) {
2549 (void) close(image_fd);
2550 free(filebuf);
2551 return (ERR_OP_NO_IMPL);
2552 }
2553
2554 ret = raid_lib->flash_fw(attr->controller_id,
2555 filebuf, size, plugin_err_str);
2556 }
2557 break;
2558 default:
2559 return (ERR_OP_ILLEGAL);
2560 }
2561
2562 return (ret);
2563 }
2564
2565 static int
obj_array_compnum(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_type_id_t comp_type)2566 obj_array_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2567 raid_obj_type_id_t comp_type)
2568 {
2569 array_attr_t *attr;
2570 controller_attr_t *ctl_attrp;
2571 raid_obj_id_t controller_obj_id;
2572 raid_lib_t *raid_lib;
2573 int ret = SUCCESS, fd;
2574
2575 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY)
2576 return (ERR_DEVICE_TYPE);
2577
2578 if (comp_type != OBJ_TYPE_ARRAY_PART &&
2579 comp_type != OBJ_TYPE_ARRAY &&
2580 comp_type != OBJ_TYPE_TASK)
2581 return (0);
2582
2583 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2584 if (attr == NULL)
2585 return (ERR_DEVICE_INVALID);
2586
2587 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2588 if (controller_obj_id < OBJ_NONE)
2589 return (ERR_DEVICE_INVALID);
2590
2591 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2592 if (ctl_attrp == NULL) {
2593 return (ERR_DEVICE_INVALID);
2594 }
2595
2596 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2597 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2598 if ((raid_lib == NULL) || (fd == 0))
2599 return (ERR_DRIVER_CLOSED);
2600
2601 ret = raid_lib->compnum(ctl_attrp->controller_id, attr->array_id,
2602 OBJ_TYPE_ARRAY, comp_type);
2603
2604 return (ret);
2605 }
2606
2607 static int
obj_array_complist(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,int comp_num,raid_obj_id_t * comp_list,raid_obj_type_id_t comp_type)2608 obj_array_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2609 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type)
2610 {
2611 array_attr_t *attr;
2612 controller_attr_t *ctl_attrp;
2613 raid_obj_id_t controller_obj_id;
2614 raid_lib_t *raid_lib;
2615 int ret, i, fd;
2616 uint32_t *ids;
2617
2618 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY)
2619 return (ERR_DEVICE_TYPE);
2620
2621 if (comp_type != OBJ_TYPE_ARRAY_PART &&
2622 comp_type != OBJ_TYPE_ARRAY &&
2623 comp_type != OBJ_TYPE_TASK)
2624 return (0);
2625
2626 if (comp_num <= 0 || comp_list == NULL)
2627 return (ERR_OP_ILLEGAL);
2628
2629 for (i = 0; i < comp_num; ++i)
2630 if (raid_obj_get_type(raid_tab, *(comp_list + i)) !=
2631 comp_type)
2632 return (ERR_DEVICE_TYPE);
2633
2634 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2635 if (attr == NULL)
2636 return (ERR_DEVICE_INVALID);
2637
2638 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2639 if (controller_obj_id < OBJ_NONE)
2640 return (ERR_DEVICE_INVALID);
2641
2642 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2643 if (ctl_attrp == NULL) {
2644 return (ERR_DEVICE_INVALID);
2645 }
2646
2647 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2648 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2649 if ((raid_lib == NULL) || (fd == 0))
2650 return (ERR_DRIVER_CLOSED);
2651
2652 ids = malloc(comp_num * sizeof (uint32_t));
2653 if (ids == NULL)
2654 return (ERR_NOMEM);
2655
2656 ret = raid_lib->complist(ctl_attrp->controller_id,
2657 attr->array_id, OBJ_TYPE_ARRAY, comp_type, comp_num, ids);
2658
2659 if (ret < SUCCESS) {
2660 free(ids);
2661 return (ret);
2662 }
2663
2664 for (i = 0; i < comp_num; ++ i) {
2665 array_attr_t *array_attr;
2666 arraypart_attr_t *arraypart_attr;
2667 task_attr_t *task_attr;
2668 void *attr_buf;
2669
2670 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i));
2671 if (attr_buf == NULL) {
2672 free(ids);
2673 return (ERR_DEVICE_INVALID);
2674 }
2675
2676 switch (comp_type) {
2677 case OBJ_TYPE_ARRAY:
2678 array_attr = attr_buf;
2679 array_attr->array_id = *(ids + i);
2680 break;
2681 case OBJ_TYPE_ARRAY_PART:
2682 arraypart_attr = attr_buf;
2683 arraypart_attr->disk_id = *(ids + i);
2684 break;
2685 case OBJ_TYPE_TASK:
2686 task_attr = attr_buf;
2687 task_attr->task_id = *(ids + i);
2688 break;
2689 default:
2690 free(ids);
2691 return (ERR_DEVICE_INVALID);
2692 }
2693 }
2694
2695
2696 free(ids);
2697 return (ret);
2698 }
2699
2700 static int
obj_array_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)2701 obj_array_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
2702 {
2703 array_attr_t *attr;
2704 controller_attr_t *ctl_attrp;
2705 raid_lib_t *raid_lib;
2706 int ret = SUCCESS, fd;
2707 raid_obj_id_t controller_obj_id;
2708
2709 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY)
2710 return (ERR_DEVICE_TYPE);
2711
2712 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
2713 return (SUCCESS);
2714
2715 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2716 if (attr == NULL)
2717 return (ERR_DEVICE_INVALID);
2718
2719 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2720 if (controller_obj_id < OBJ_NONE)
2721 return (ERR_DEVICE_INVALID);
2722
2723 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2724 if (ctl_attrp == NULL) {
2725 return (ERR_DEVICE_INVALID);
2726 }
2727
2728 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2729 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2730 if ((raid_lib == NULL) || (fd == 0))
2731 return (ERR_DRIVER_CLOSED);
2732
2733 ret = raid_lib->get_attr(ctl_attrp->controller_id,
2734 attr->array_id, 0, OBJ_TYPE_ARRAY, attr);
2735
2736 if (ret < SUCCESS)
2737 return (ret);
2738
2739 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
2740
2741 return (ret);
2742 }
2743
2744 static int
obj_array_set_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,uint32_t sub_cmd,uint32_t * value,char ** plugin_err_str)2745 obj_array_set_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2746 uint32_t sub_cmd, uint32_t *value, char **plugin_err_str)
2747 {
2748 array_attr_t *attr;
2749 controller_attr_t *ctl_attrp;
2750 raid_lib_t *raid_lib;
2751 int ret = SUCCESS, fd;
2752 raid_obj_id_t controller_obj_id;
2753
2754 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY)
2755 return (ERR_DEVICE_TYPE);
2756
2757 switch (sub_cmd) {
2758 case SET_CACHE_WR_PLY:
2759 if (*value != CACHE_WR_OFF &&
2760 *value != CACHE_WR_ON)
2761 return (ERR_OP_ILLEGAL);
2762 break;
2763 case SET_CACHE_RD_PLY:
2764 if (*value != CACHE_RD_OFF &&
2765 *value != CACHE_RD_ON)
2766 return (ERR_OP_ILLEGAL);
2767 break;
2768 case SET_ACTIVATION_PLY:
2769 if (*value != ARRAY_ACT_ACTIVATE)
2770 return (ERR_OP_ILLEGAL);
2771 break;
2772 default:
2773 return (ERR_OP_ILLEGAL);
2774 }
2775
2776 (void) obj_get_attr(raid_tab, obj_id, (void **)(&attr));
2777
2778 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2779 if (controller_obj_id < OBJ_NONE)
2780 return (ERR_DEVICE_INVALID);
2781
2782 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2783 if (ctl_attrp == NULL) {
2784 return (ERR_DEVICE_INVALID);
2785 }
2786
2787 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2788 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2789 if ((raid_lib == NULL) || (fd == 0))
2790 return (ERR_DRIVER_CLOSED);
2791
2792 if (raid_lib->set_attr == NULL)
2793 return (ERR_OP_NO_IMPL);
2794
2795 ret = raid_lib->set_attr(ctl_attrp->controller_id,
2796 attr->array_id, sub_cmd, value, plugin_err_str);
2797
2798 return (ret);
2799 }
2800
2801 static int
obj_disk_compnum(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_type_id_t comp_type)2802 obj_disk_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2803 raid_obj_type_id_t comp_type)
2804 {
2805 disk_attr_t *attr;
2806 controller_attr_t *ctl_attrp;
2807 raid_obj_id_t controller_obj_id;
2808 raid_lib_t *raid_lib;
2809 int ret = SUCCESS, fd;
2810
2811 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK)
2812 return (ERR_DEVICE_TYPE);
2813
2814 if (comp_type != OBJ_TYPE_DISK_SEG &&
2815 comp_type != OBJ_TYPE_HSP &&
2816 comp_type != OBJ_TYPE_TASK &&
2817 comp_type != OBJ_TYPE_PROP)
2818 return (0);
2819 ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr));
2820 if ((ret != SUCCESS) || (attr == NULL)) {
2821 return (ERR_DEVICE_INVALID);
2822 }
2823 if (attr->state == DISK_STATE_FAILED) {
2824 return (SUCCESS);
2825 }
2826
2827 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2828 if (controller_obj_id < OBJ_NONE)
2829 return (ERR_DEVICE_INVALID);
2830
2831 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2832 if (ctl_attrp == NULL) {
2833 return (ERR_DEVICE_INVALID);
2834 }
2835
2836 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2837 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2838 if ((raid_lib == NULL) || (fd == 0))
2839 return (ERR_DRIVER_CLOSED);
2840
2841 ret = raid_lib->compnum(ctl_attrp->controller_id,
2842 attr->disk_id, OBJ_TYPE_DISK, comp_type);
2843
2844 return (ret);
2845 }
2846
2847 static int
obj_disk_complist(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,int comp_num,raid_obj_id_t * comp_list,raid_obj_type_id_t comp_type)2848 obj_disk_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
2849 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type)
2850 {
2851 disk_attr_t *attr;
2852 controller_attr_t *ctl_attrp;
2853 raid_obj_id_t controller_obj_id;
2854 raid_lib_t *raid_lib;
2855 int ret, i, fd;
2856 uint32_t *ids;
2857
2858 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK)
2859 return (ERR_DEVICE_TYPE);
2860
2861 if (comp_type != OBJ_TYPE_DISK_SEG &&
2862 comp_type != OBJ_TYPE_HSP &&
2863 comp_type != OBJ_TYPE_TASK &&
2864 comp_type != OBJ_TYPE_PROP)
2865 return (0);
2866
2867 if (comp_num <= 0 || comp_list == NULL)
2868 return (ERR_OP_ILLEGAL);
2869
2870 for (i = 0; i < comp_num; ++i)
2871 if (raid_obj_get_type(raid_tab, *(comp_list + i)) !=
2872 comp_type)
2873 return (ERR_DEVICE_TYPE);
2874 ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr));
2875 if ((ret != SUCCESS) || (attr == NULL)) {
2876 return (ERR_DEVICE_INVALID);
2877 }
2878 if (attr->state == DISK_STATE_FAILED) {
2879 return (SUCCESS);
2880 }
2881
2882 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2883 if (controller_obj_id < OBJ_NONE)
2884 return (ERR_DEVICE_INVALID);
2885
2886 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2887 if (ctl_attrp == NULL) {
2888 return (ERR_DEVICE_INVALID);
2889 }
2890
2891 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2892 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2893 if ((raid_lib == NULL) || (fd == 0))
2894 return (ERR_DRIVER_CLOSED);
2895
2896 ids = malloc(comp_num * sizeof (uint32_t));
2897 if (ids == NULL)
2898 return (ERR_NOMEM);
2899
2900 ret = raid_lib->complist(ctl_attrp->controller_id,
2901 attr->disk_id, OBJ_TYPE_DISK, comp_type, comp_num, ids);
2902
2903 if (ret < SUCCESS) {
2904 free(ids);
2905 return (ret);
2906 }
2907
2908 for (i = 0; i < comp_num; ++ i) {
2909 diskseg_attr_t *diskseg_attr;
2910 hsp_attr_t *hsp_attr;
2911 task_attr_t *task_attr;
2912 property_attr_t *prop_attr;
2913 void *attr_buf;
2914
2915 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i));
2916 if (attr_buf == NULL) {
2917 free(ids);
2918 return (ERR_DEVICE_INVALID);
2919 }
2920
2921 switch (comp_type) {
2922 case OBJ_TYPE_DISK_SEG:
2923 diskseg_attr = attr_buf;
2924 diskseg_attr->seq_no = *(ids + i);
2925 break;
2926 case OBJ_TYPE_HSP:
2927 hsp_attr = attr_buf;
2928 hsp_attr->associated_id = *(ids + i);
2929 break;
2930 case OBJ_TYPE_TASK:
2931 task_attr = attr_buf;
2932 task_attr->task_id = *(ids + i);
2933 break;
2934 case OBJ_TYPE_PROP:
2935 prop_attr = attr_buf;
2936 prop_attr->prop_id = *(ids + i);
2937 break;
2938 default:
2939 free(ids);
2940 return (ERR_DEVICE_INVALID);
2941 }
2942 }
2943
2944
2945 free(ids);
2946 return (ret);
2947 }
2948
2949 static int
obj_disk_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)2950 obj_disk_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
2951 {
2952 disk_attr_t *attr;
2953 controller_attr_t *ctl_attrp;
2954 raid_lib_t *raid_lib;
2955 int ret = SUCCESS, fd;
2956 raid_obj_id_t controller_obj_id;
2957
2958 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK)
2959 return (ERR_DEVICE_TYPE);
2960
2961 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
2962 return (SUCCESS);
2963
2964 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
2965 if (attr == NULL)
2966 return (ERR_DEVICE_INVALID);
2967
2968 controller_obj_id = obj_get_controller(raid_tab, obj_id);
2969 if (controller_obj_id < OBJ_NONE)
2970 return (ERR_DEVICE_INVALID);
2971
2972 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
2973 if (ctl_attrp == NULL) {
2974 return (ERR_DEVICE_INVALID);
2975 }
2976
2977 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
2978 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
2979 if ((raid_lib == NULL) || (fd == 0))
2980 return (ERR_DRIVER_CLOSED);
2981
2982 ret = raid_lib->get_attr(ctl_attrp->controller_id,
2983 attr->disk_id, 0, OBJ_TYPE_DISK, attr);
2984
2985 if (ret < SUCCESS)
2986 return (ret);
2987
2988 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
2989
2990 return (ret);
2991 }
2992
2993 static int
obj_hsp_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)2994 obj_hsp_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
2995 {
2996 hsp_attr_t *attr;
2997
2998 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_HSP)
2999 return (ERR_DEVICE_TYPE);
3000
3001 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
3002 return (SUCCESS);
3003
3004 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
3005 if (attr == NULL)
3006 return (ERR_DEVICE_INVALID);
3007
3008 if (attr->associated_id == (uint32_t)OBJ_ATTR_NONE)
3009 attr->type = HSP_TYPE_GLOBAL;
3010 else
3011 attr->type = HSP_TYPE_LOCAL;
3012
3013 return (SUCCESS);
3014 }
3015
3016 static int
obj_arraypart_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)3017 obj_arraypart_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
3018 {
3019 arraypart_attr_t *attr;
3020 array_attr_t *array_attr;
3021 controller_attr_t *ctl_attrp;
3022 raid_lib_t *raid_lib;
3023 int ret = SUCCESS, fd;
3024 raid_obj_id_t controller_obj_id, array_obj_id;
3025
3026 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY_PART)
3027 return (ERR_DEVICE_TYPE);
3028
3029 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
3030 return (SUCCESS);
3031
3032 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
3033 if (attr == NULL)
3034 return (ERR_DEVICE_INVALID);
3035
3036 array_obj_id = raid_obj_get_container(raid_tab, obj_id);
3037 if (array_obj_id < OBJ_NONE)
3038 return (ERR_DEVICE_INVALID);
3039
3040 array_attr = raid_obj_get_data_ptr(raid_tab, array_obj_id);
3041 if (array_attr == NULL)
3042 return (ERR_DEVICE_INVALID);
3043
3044 controller_obj_id = obj_get_controller(raid_tab, obj_id);
3045 if (controller_obj_id < OBJ_NONE)
3046 return (ERR_DEVICE_INVALID);
3047
3048 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
3049 if (ctl_attrp == NULL) {
3050 return (ERR_DEVICE_INVALID);
3051 }
3052
3053 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3054 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3055 if ((raid_lib == NULL) || (fd == 0))
3056 return (ERR_DRIVER_CLOSED);
3057
3058 ret = raid_lib->get_attr(ctl_attrp->controller_id,
3059 array_attr->array_id, attr->disk_id,
3060 OBJ_TYPE_ARRAY_PART, attr);
3061
3062 if (ret < SUCCESS)
3063 return (ret);
3064
3065 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
3066
3067 return (ret);
3068 }
3069
3070 static int
obj_diskseg_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)3071 obj_diskseg_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
3072 {
3073 diskseg_attr_t *attr;
3074 disk_attr_t *disk_attr;
3075 controller_attr_t *ctl_attrp;
3076 raid_lib_t *raid_lib;
3077 int ret = SUCCESS, fd;
3078 raid_obj_id_t controller_obj_id, disk_obj_id;
3079
3080 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK_SEG)
3081 return (ERR_DEVICE_TYPE);
3082
3083 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
3084 return (SUCCESS);
3085
3086 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
3087 if (attr == NULL)
3088 return (ERR_DEVICE_INVALID);
3089
3090 disk_obj_id = raid_obj_get_container(raid_tab, obj_id);
3091 if (disk_obj_id < OBJ_NONE)
3092 return (ERR_DEVICE_INVALID);
3093
3094 disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id);
3095 if (disk_attr == NULL)
3096 return (ERR_DEVICE_INVALID);
3097
3098 controller_obj_id = obj_get_controller(raid_tab, obj_id);
3099 if (controller_obj_id < OBJ_NONE)
3100 return (ERR_DEVICE_INVALID);
3101
3102 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
3103 if (ctl_attrp == NULL) {
3104 return (ERR_DEVICE_INVALID);
3105 }
3106
3107 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3108 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3109 if ((raid_lib == NULL) || (fd == 0))
3110 return (ERR_DRIVER_CLOSED);
3111
3112 ret = raid_lib->get_attr(ctl_attrp->controller_id,
3113 disk_attr->disk_id, attr->seq_no, OBJ_TYPE_DISK_SEG, attr);
3114
3115 if (ret < SUCCESS)
3116 return (ret);
3117
3118 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
3119
3120 return (ret);
3121 }
3122
3123 static int
obj_task_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)3124 obj_task_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
3125 {
3126 task_attr_t *attr;
3127 controller_attr_t *ctl_attrp;
3128 raid_lib_t *raid_lib;
3129 int ret = SUCCESS, fd;
3130 raid_obj_id_t controller_obj_id;
3131
3132 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_TASK)
3133 return (ERR_DEVICE_TYPE);
3134
3135 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
3136 if (attr == NULL)
3137 return (ERR_DEVICE_INVALID);
3138
3139 controller_obj_id = obj_get_controller(raid_tab, obj_id);
3140 if (controller_obj_id < OBJ_NONE)
3141 return (ERR_DEVICE_INVALID);
3142
3143 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
3144 if (ctl_attrp == NULL) {
3145 return (ERR_DEVICE_INVALID);
3146 }
3147
3148 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3149 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3150 if ((raid_lib == NULL) || (fd == 0))
3151 return (ERR_DRIVER_CLOSED);
3152
3153 ret = raid_lib->get_attr(ctl_attrp->controller_id,
3154 attr->task_id, OBJ_ATTR_NONE, OBJ_TYPE_TASK, attr);
3155
3156 return (ret);
3157 }
3158
3159 static int
obj_prop_get_attr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)3160 obj_prop_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
3161 {
3162 property_attr_t *attr, *attr_new;
3163 disk_attr_t *disk_attr;
3164 controller_attr_t *ctl_attrp;
3165 raid_lib_t *raid_lib;
3166 int ret = SUCCESS, fd;
3167 raid_obj_id_t controller_obj_id, disk_obj_id;
3168
3169 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_PROP)
3170 return (ERR_DEVICE_TYPE);
3171
3172 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED)
3173 return (SUCCESS);
3174
3175 attr = raid_obj_get_data_ptr(raid_tab, obj_id);
3176 if (attr == NULL)
3177 return (ERR_DEVICE_INVALID);
3178
3179 disk_obj_id = raid_obj_get_container(raid_tab, obj_id);
3180 if (disk_obj_id < OBJ_NONE)
3181 return (ERR_DEVICE_INVALID);
3182
3183 disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id);
3184 if (disk_attr == NULL)
3185 return (ERR_DEVICE_INVALID);
3186
3187 controller_obj_id = obj_get_controller(raid_tab, obj_id);
3188 if (controller_obj_id < OBJ_NONE)
3189 return (ERR_DEVICE_INVALID);
3190
3191 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id);
3192 if (ctl_attrp == NULL) {
3193 return (ERR_DEVICE_INVALID);
3194 }
3195
3196 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3197 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3198 if ((raid_lib == NULL) || (fd == 0))
3199 return (ERR_DRIVER_CLOSED);
3200
3201 /* Get the property size at first */
3202 attr->prop_size = 0;
3203 ret = raid_lib->get_attr(ctl_attrp->controller_id,
3204 disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr);
3205
3206 if (ret < SUCCESS)
3207 return (ret);
3208
3209 /* Allocate memory for property and fill the buffer */
3210 attr_new = realloc(attr, sizeof (property_attr_t) + attr->prop_size);
3211 if (attr_new == NULL)
3212 return (ERR_NOMEM);
3213
3214 (void) raid_obj_set_data_ptr(raid_tab, obj_id, attr_new);
3215
3216 ret = raid_lib->get_attr(ctl_attrp->controller_id,
3217 disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr_new);
3218
3219 if (ret < SUCCESS)
3220 return (ret);
3221
3222 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED);
3223
3224 return (ret);
3225 }
3226
3227 static int
obj_array_create(raid_obj_tab_t * raid_tab,raid_obj_id_t array_obj_id,int num_of_comp,raid_obj_id_t * disk_list,char ** plugin_err_str)3228 obj_array_create(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id,
3229 int num_of_comp, raid_obj_id_t *disk_list, char **plugin_err_str)
3230 {
3231 controller_attr_t *controller_attr;
3232 array_attr_t *array_attr, array_attr2;
3233 disk_attr_t *disk_attr;
3234 arraypart_attr_t *arraypart_attrs;
3235 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE;
3236 raid_lib_t *raid_lib;
3237 int i, j, ret, fd;
3238 int disk_cnt = 0, disk_set_num = 0, set_num = 0, layer_cnt = 0;
3239 uint64_t min_disk_capacity = 0;
3240
3241 array_attr = raid_obj_get_data_ptr(raid_tab, array_obj_id);
3242 if (array_attr == NULL)
3243 return (ERR_DEVICE_INVALID);
3244
3245 /* Check the disk layout expression */
3246 if (disk_list[0] != OBJ_SEPARATOR_BEGIN ||
3247 disk_list[num_of_comp - 1] != OBJ_SEPARATOR_END)
3248 return (ERR_ARRAY_LAYOUT);
3249 for (i = 0; i < num_of_comp; ++i) {
3250 if (disk_list[i] == OBJ_SEPARATOR_BEGIN) {
3251 if (disk_cnt != 0)
3252 return (ERR_ARRAY_LAYOUT);
3253 ++layer_cnt;
3254 continue;
3255 }
3256 if (disk_list[i] == OBJ_SEPARATOR_END) {
3257 if (disk_set_num == 0)
3258 disk_set_num = disk_cnt;
3259 else if (disk_set_num != disk_cnt && disk_cnt != 0)
3260 return (ERR_ARRAY_LAYOUT);
3261 disk_cnt = 0;
3262 ++set_num;
3263 --layer_cnt;
3264 continue;
3265 }
3266 switch (array_attr->raid_level) {
3267 case RAID_LEVEL_0:
3268 case RAID_LEVEL_1:
3269 case RAID_LEVEL_1E:
3270 case RAID_LEVEL_5:
3271 if (layer_cnt != 1)
3272 return (ERR_ARRAY_LAYOUT);
3273 break;
3274 case RAID_LEVEL_10:
3275 case RAID_LEVEL_50:
3276 if (layer_cnt != 2)
3277 return (ERR_ARRAY_LAYOUT);
3278 break;
3279 default:
3280 return (ERR_ARRAY_LEVEL);
3281 }
3282 ++disk_cnt;
3283 }
3284
3285 if (layer_cnt != 0)
3286 return (ERR_ARRAY_LAYOUT);
3287
3288 switch (array_attr->raid_level) {
3289 case RAID_LEVEL_0:
3290 if (disk_set_num < 2 || set_num != 1)
3291 return (ERR_ARRAY_LAYOUT);
3292 break;
3293 case RAID_LEVEL_1:
3294 if (disk_set_num != 2 || set_num != 1)
3295 return (ERR_ARRAY_LAYOUT);
3296 break;
3297 case RAID_LEVEL_1E:
3298 case RAID_LEVEL_5:
3299 if (disk_set_num < 3 || set_num != 1)
3300 return (ERR_ARRAY_LAYOUT);
3301 break;
3302 case RAID_LEVEL_10:
3303 if (disk_set_num != 2 || set_num < 2)
3304 return (ERR_ARRAY_LAYOUT);
3305 break;
3306 case RAID_LEVEL_50:
3307 if (disk_set_num < 3 || set_num < 2)
3308 return (ERR_ARRAY_LAYOUT);
3309 break;
3310 default:
3311 return (ERR_ARRAY_LEVEL);
3312 }
3313
3314 arraypart_attrs = calloc(num_of_comp, sizeof (arraypart_attr_t));
3315 if (arraypart_attrs == NULL)
3316 return (ERR_NOMEM);
3317
3318 for (i = 0; i < num_of_comp; ++i) {
3319 /* Keep seperators */
3320 if (*(disk_list + i) == OBJ_SEPARATOR_BEGIN) {
3321 arraypart_attrs[i].disk_id =
3322 (uint32_t)OBJ_SEPARATOR_BEGIN;
3323 continue;
3324 }
3325
3326 if (*(disk_list + i) == OBJ_SEPARATOR_END) {
3327 arraypart_attrs[i].disk_id =
3328 (uint32_t)OBJ_SEPARATOR_END;
3329 continue;
3330 }
3331
3332 disk_cnt++;
3333 /* Check if it's a disk */
3334 if (raid_obj_get_type(raid_tab, *(disk_list + i)) !=
3335 OBJ_TYPE_DISK)
3336 return (ERR_DEVICE_TYPE);
3337
3338 /* Check if it's duplicated with other disks */
3339 for (j = 0; j < i; ++j)
3340 if (*(disk_list + j) == *(disk_list + i)) {
3341 free(arraypart_attrs);
3342 return (ERR_DEVICE_DUP);
3343 }
3344
3345 /* Check disk status */
3346 ret = obj_get_attr(raid_tab, *(disk_list + i),
3347 (void **)(&disk_attr));
3348 if (ret != SUCCESS)
3349 return (ret);
3350
3351 if (disk_attr->state != DISK_STATE_GOOD) {
3352 free(arraypart_attrs);
3353 return (ERR_DISK_STATE);
3354 }
3355
3356 /* All disks must belong to the same controller */
3357 obj_id = obj_get_controller(raid_tab, *(disk_list + i));
3358 if (obj_id <= OBJ_NONE)
3359 return (obj_id);
3360 if (controller_obj_id == OBJ_NONE) {
3361 controller_obj_id = obj_id;
3362 ret = obj_get_attr(raid_tab, controller_obj_id,
3363 (void **)(&controller_attr));
3364 } else if (obj_id != controller_obj_id) {
3365 free(arraypart_attrs);
3366 return (ERR_DRIVER_ACROSS);
3367 }
3368
3369 /* Check if the disk contains too many segments */
3370 obj_id = obj_get_comp(raid_tab, *(disk_list + i),
3371 OBJ_TYPE_DISK_SEG);
3372 j = 0;
3373 while (obj_id > OBJ_NONE) {
3374 ++j;
3375 obj_id = obj_get_sibling(raid_tab, obj_id);
3376 }
3377 if (j > controller_attr->max_seg_per_disk) {
3378 free(arraypart_attrs);
3379 return (ERR_DISK_SEG_AMOUNT);
3380 }
3381
3382 /* Check if controller is a hostraid controller */
3383 if (controller_attr->capability & RAID_CAP_DISK_TRANS) {
3384 /*
3385 * For hostraid, the first disk should
3386 * be with of minimum capacity
3387 */
3388 if (min_disk_capacity == 0) {
3389 min_disk_capacity = disk_attr->capacity;
3390
3391 /* Can not specify capacity for hostraid */
3392 if (array_attr->capacity != 0) {
3393 free(arraypart_attrs);
3394 return (ERR_OP_ILLEGAL);
3395 }
3396 } else if (min_disk_capacity > disk_attr->capacity) {
3397 free(arraypart_attrs);
3398 return (ERR_DISK_SPACE);
3399 }
3400
3401 /* Disk should not be used for hostraid */
3402 obj_id = obj_get_comp(raid_tab, *(disk_list + i),
3403 OBJ_TYPE_DISK_SEG);
3404 if (obj_id < OBJ_NONE) {
3405 free(arraypart_attrs);
3406 return (obj_id);
3407 } else if (obj_id > OBJ_NONE) {
3408 free(arraypart_attrs);
3409 return (ERR_DISK_NOT_EMPTY);
3410 }
3411 }
3412
3413 arraypart_attrs[i].disk_id = disk_attr->disk_id;
3414 arraypart_attrs[i].offset = OBJ_ATTR_NONE;
3415 arraypart_attrs[i].size = OBJ_ATTR_NONE;
3416 }
3417
3418 /* Check if array amount exceeds limit */
3419 if (controller_attr->max_array_num <=
3420 obj_controller_compnum(raid_tab, controller_obj_id,
3421 OBJ_TYPE_ARRAY))
3422 return (ERR_ARRAY_AMOUNT);
3423
3424
3425 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3426 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3427 if ((raid_lib == NULL) || (fd == 0))
3428 return (ERR_DRIVER_CLOSED);
3429
3430 /* Check if the controller can support the array RAID level */
3431 switch (array_attr->raid_level) {
3432 case RAID_LEVEL_0:
3433 if (!(controller_attr->capability & RAID_CAP_RAID0)) {
3434 free(arraypart_attrs);
3435 return (ERR_ARRAY_LEVEL);
3436 }
3437 break;
3438 case RAID_LEVEL_1:
3439 if (!(controller_attr->capability & RAID_CAP_RAID1)) {
3440 free(arraypart_attrs);
3441 return (ERR_ARRAY_LEVEL);
3442 }
3443 break;
3444 case RAID_LEVEL_1E:
3445 if (!(controller_attr->capability & RAID_CAP_RAID1E)) {
3446 free(arraypart_attrs);
3447 return (ERR_ARRAY_LEVEL);
3448 }
3449 break;
3450 case RAID_LEVEL_5:
3451 if (!(controller_attr->capability & RAID_CAP_RAID5)) {
3452 free(arraypart_attrs);
3453 return (ERR_ARRAY_LEVEL);
3454 }
3455 break;
3456 case RAID_LEVEL_10:
3457 if (!(controller_attr->capability & RAID_CAP_RAID10)) {
3458 free(arraypart_attrs);
3459 return (ERR_ARRAY_LEVEL);
3460 }
3461 break;
3462 case RAID_LEVEL_50:
3463 if (!(controller_attr->capability & RAID_CAP_RAID50)) {
3464 free(arraypart_attrs);
3465 return (ERR_ARRAY_LEVEL);
3466 }
3467 break;
3468 default:
3469 free(arraypart_attrs);
3470 return (ERR_ARRAY_LEVEL);
3471 }
3472
3473 /* Check if plug in can calculate the maximum size */
3474 (void) memcpy(&array_attr2, array_attr, sizeof (array_attr_t));
3475 array_attr2.capacity = OBJ_ATTR_NONE;
3476 ret = raid_lib->array_create(controller_attr->controller_id,
3477 &array_attr2, num_of_comp, arraypart_attrs, plugin_err_str);
3478
3479 /* If plugin/driver will not calculate space */
3480 if (ret == ERR_OP_NO_IMPL) {
3481 /* Calculate the maximum capacity */
3482 array_attr2.capacity = raid_space_noalign(raid_tab,
3483 array_attr2.raid_level, num_of_comp, disk_list,
3484 arraypart_attrs);
3485
3486 /*
3487 * If controller is capable to allocate space,
3488 * set offset and size attributes to OBJ_ATTR_NONE
3489 * and let the controller to determine these value
3490 */
3491 if (controller_attr->capability & RAID_CAP_SMART_ALLOC)
3492 for (i = 0; i < num_of_comp; ++i) {
3493 arraypart_attrs[i].offset =
3494 OBJ_ATTR_NONE;
3495 arraypart_attrs[i].size =
3496 OBJ_ATTR_NONE;
3497 }
3498
3499 /* There's no enough space for specified capacity */
3500 if (array_attr->capacity > array_attr2.capacity) {
3501 free(arraypart_attrs);
3502 return (ERR_ARRAY_SIZE);
3503 }
3504
3505 /* capacity == 0, allocate maximum space */
3506 if (array_attr->capacity == 0)
3507 array_attr->capacity = array_attr2.capacity;
3508 } else if (ret < SUCCESS) {
3509 free(arraypart_attrs);
3510 return (ret);
3511 } else if (array_attr2.capacity < array_attr->capacity) {
3512 /* Return the maximum size */
3513 array_attr->capacity = array_attr2.capacity;
3514 free(arraypart_attrs);
3515 return (ERR_ARRAY_SIZE);
3516 }
3517
3518 if (array_attr->capacity < ARRAYPART_MIN_SIZE * disk_cnt) {
3519 free(arraypart_attrs);
3520 return (ERR_ARRAY_SIZE);
3521 }
3522
3523
3524 ret = raid_lib->array_create(controller_attr->controller_id,
3525 array_attr, num_of_comp, arraypart_attrs, plugin_err_str);
3526 free(arraypart_attrs);
3527
3528 if (ret != SUCCESS)
3529 return (ret);
3530
3531 /* Add array object into device tree so that we can map the handle */
3532 (void) raid_obj_add_org(raid_tab, array_obj_id, controller_obj_id);
3533
3534 return (ret);
3535 }
3536
3537 static int
obj_array_delete(raid_obj_tab_t * raid_tab,raid_obj_id_t array_obj_id,char ** plugin_err_str)3538 obj_array_delete(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id,
3539 char **plugin_err_str)
3540 {
3541 raid_obj_id_t controller_obj_id;
3542 controller_attr_t *controller_attr;
3543 array_attr_t *array_attr;
3544 raid_lib_t *raid_lib;
3545 int ret, fd;
3546 uint32_t *disk_ids = NULL;
3547
3548 controller_obj_id = obj_get_controller(raid_tab, array_obj_id);
3549 if (controller_obj_id <= OBJ_NONE)
3550 return (controller_obj_id);
3551
3552 ret = obj_get_attr(raid_tab, controller_obj_id,
3553 (void **)(&controller_attr));
3554 if (ret < SUCCESS) {
3555 return (ret);
3556 }
3557 ret = obj_get_attr(raid_tab, array_obj_id, (void **)(&array_attr));
3558 if (ret < SUCCESS)
3559 return (ret);
3560
3561 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3562 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3563 if ((raid_lib == NULL) || (fd == 0))
3564 return (ERR_DRIVER_CLOSED);
3565
3566 ret = raid_lib->array_delete(controller_attr->controller_id,
3567 array_attr->array_id, plugin_err_str);
3568 if (ret < SUCCESS) {
3569 if (disk_ids)
3570 free(disk_ids);
3571 return (ret);
3572 }
3573
3574 if (disk_ids)
3575 free(disk_ids);
3576 return (ret);
3577 }
3578
3579 static int
obj_hsp_bind(raid_obj_tab_t * raid_tab,raid_obj_id_t * obj_ids,char ** plugin_err_str)3580 obj_hsp_bind(raid_obj_tab_t *raid_tab, raid_obj_id_t *obj_ids,
3581 char **plugin_err_str)
3582 {
3583 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE;
3584 raid_obj_id_t array_obj_id, disk_obj_id;
3585 hsp_relation_t *hsp_relation;
3586 controller_attr_t *controller_attr;
3587 array_attr_t *array_attr;
3588 arraypart_attr_t *arraypart_attr;
3589 disk_attr_t *disk_attr;
3590 diskseg_attr_t *diskseg_attr;
3591 hsp_attr_t *hsp_attr;
3592 raid_lib_t *raid_lib;
3593 int ret, fd;
3594
3595 hsp_relation = malloc(sizeof (hsp_relation_t));
3596 if (hsp_relation == NULL)
3597 return (ERR_NOMEM);
3598
3599 array_obj_id = *(obj_ids);
3600 disk_obj_id = *(obj_ids + 1);
3601
3602 if (raid_obj_get_type(raid_tab, disk_obj_id) != OBJ_TYPE_DISK ||
3603 (array_obj_id != OBJ_ATTR_NONE &&
3604 raid_obj_get_type(raid_tab, array_obj_id) !=
3605 OBJ_TYPE_ARRAY)) {
3606 free(hsp_relation);
3607 return (ERR_DEVICE_TYPE);
3608 }
3609
3610 /* Get controller attributes */
3611 if (controller_obj_id == OBJ_NONE)
3612 controller_obj_id = obj_get_controller(raid_tab,
3613 disk_obj_id);
3614 else if (controller_obj_id != obj_get_controller(raid_tab,
3615 disk_obj_id)) {
3616 free(hsp_relation);
3617 return (ERR_DRIVER_ACROSS);
3618 }
3619
3620 ret = obj_get_attr(raid_tab, controller_obj_id,
3621 (void **)(&controller_attr));
3622
3623 /* Get disk attributes */
3624 ret = obj_get_attr(raid_tab, disk_obj_id,
3625 (void **)(&disk_attr));
3626 if (disk_attr->state == DISK_STATE_FAILED) {
3627 free(hsp_relation);
3628 return (ERR_DISK_STATE);
3629 }
3630
3631 /* If it's not a hsp disk, check if there's occupied space */
3632 if (obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP) ==
3633 OBJ_NONE) {
3634 obj_id = obj_get_comp(raid_tab, disk_obj_id,
3635 OBJ_TYPE_DISK_SEG);
3636 while (obj_id != OBJ_NONE) {
3637 ret = obj_get_attr(raid_tab, obj_id,
3638 (void **)(&diskseg_attr));
3639 if (!(diskseg_attr->state &
3640 DISKSEG_STATE_RESERVED)) {
3641 free(hsp_relation);
3642 return (ERR_DISK_NOT_EMPTY);
3643 }
3644 obj_id = obj_get_sibling(raid_tab, obj_id);
3645 }
3646 }
3647
3648 if (array_obj_id != OBJ_ATTR_NONE) {
3649 /* If local hsp is supported */
3650 if (!(controller_attr->capability & RAID_CAP_L_HSP)) {
3651 free(hsp_relation);
3652 return (ERR_OP_ILLEGAL);
3653 }
3654
3655 if (raid_obj_get_type(raid_tab, array_obj_id) !=
3656 OBJ_TYPE_ARRAY) {
3657 free(hsp_relation);
3658 return (ERR_DEVICE_TYPE);
3659 }
3660
3661 /* Get array attributes */
3662 ret = obj_get_attr(raid_tab, array_obj_id,
3663 (void **)(&array_attr));
3664 /* RAID 0 array can not use hsp */
3665 if (array_attr->raid_level == RAID_LEVEL_0) {
3666 free(hsp_relation);
3667 return (ERR_ARRAY_LEVEL);
3668 }
3669
3670 /* If It's belong to another controller */
3671 if (controller_obj_id != obj_get_controller(raid_tab,
3672 array_obj_id)) {
3673 free(hsp_relation);
3674 return (ERR_DRIVER_ACROSS);
3675 }
3676
3677 /* Get an array part attributes */
3678 if ((array_attr->raid_level == RAID_LEVEL_10) ||
3679 (array_attr->raid_level == RAID_LEVEL_50))
3680 obj_id = obj_get_comp(raid_tab, array_obj_id,
3681 OBJ_TYPE_ARRAY);
3682 else
3683 obj_id = array_obj_id;
3684 obj_id = obj_get_comp(raid_tab, obj_id,
3685 OBJ_TYPE_ARRAY_PART);
3686 ret = obj_get_attr(raid_tab, obj_id,
3687 (void **)(&arraypart_attr));
3688
3689 /* Check if disk space is enough for array */
3690 if (arraypart_attr->size > disk_attr->capacity) {
3691 free(hsp_relation);
3692 return (ERR_DISK_SPACE);
3693 }
3694 if (controller_attr->capability & RAID_CAP_ARRAY_ALIGN)
3695 if ((arraypart_attr->size +
3696 arraypart_attr->offset) >
3697 disk_attr->capacity) {
3698 free(hsp_relation);
3699 return (ERR_DISK_SPACE);
3700 }
3701 } else if (!(controller_attr->capability & RAID_CAP_G_HSP)) {
3702 /* if global hsp is supported */
3703 free(hsp_relation);
3704 return (ERR_OP_ILLEGAL);
3705 }
3706
3707 /*
3708 * If the array is already associated with the
3709 * local hsp, or it's a global hsp, ignore it
3710 */
3711 obj_id = obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP);
3712 if (obj_id > OBJ_NONE) {
3713 if (obj_get_attr(raid_tab, obj_id,
3714 (void **)&hsp_attr) >= SUCCESS) {
3715 if (((hsp_attr->type == HSP_TYPE_GLOBAL) &&
3716 (array_obj_id != OBJ_ATTR_NONE)) ||
3717 ((hsp_attr->type == HSP_TYPE_LOCAL) &&
3718 (array_obj_id == OBJ_ATTR_NONE))) {
3719 free(hsp_relation);
3720 return (ERR_OP_ILLEGAL);
3721 }
3722 }
3723 }
3724
3725 if (array_obj_id != OBJ_ATTR_NONE)
3726 hsp_relation->array_id = array_attr->array_id;
3727 else
3728 hsp_relation->array_id = (uint32_t)OBJ_ATTR_NONE;
3729 hsp_relation->disk_id = disk_attr->disk_id;
3730
3731 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3732 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3733 if ((raid_lib == NULL) || (fd == 0))
3734 return (ERR_DRIVER_CLOSED);
3735
3736 if (raid_lib->hsp_bind == NULL) {
3737 free(hsp_relation);
3738 return (ERR_OP_NO_IMPL);
3739 }
3740
3741 ret = raid_lib->hsp_bind(controller_attr->controller_id,
3742 hsp_relation, plugin_err_str);
3743
3744 free(hsp_relation);
3745 return (ret);
3746 }
3747
3748 static int
obj_hsp_unbind(raid_obj_tab_t * raid_tab,raid_obj_id_t * obj_ids,char ** plugin_err_str)3749 obj_hsp_unbind(raid_obj_tab_t *raid_tab, raid_obj_id_t *obj_ids,
3750 char **plugin_err_str)
3751 {
3752 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE;
3753 raid_obj_id_t array_obj_id, disk_obj_id;
3754 hsp_relation_t *hsp_relation;
3755 controller_attr_t *controller_attr;
3756 array_attr_t *array_attr;
3757 disk_attr_t *disk_attr;
3758 hsp_attr_t *hsp_attr;
3759 raid_lib_t *raid_lib;
3760 int ret, fd;
3761
3762 hsp_relation = malloc(sizeof (hsp_relation_t));
3763 if (hsp_relation == NULL)
3764 return (ERR_NOMEM);
3765
3766 array_obj_id = *(obj_ids);
3767 disk_obj_id = *(obj_ids + 1);
3768
3769 if (raid_obj_get_type(raid_tab, disk_obj_id) != OBJ_TYPE_DISK) {
3770 free(hsp_relation);
3771 return (ERR_DEVICE_TYPE);
3772 }
3773
3774 /* Get controller attributes */
3775 if (controller_obj_id == OBJ_NONE)
3776 controller_obj_id = obj_get_controller(raid_tab,
3777 disk_obj_id);
3778 else if (controller_obj_id != obj_get_controller(raid_tab,
3779 disk_obj_id)) {
3780 free(hsp_relation);
3781 return (ERR_DRIVER_ACROSS);
3782 }
3783
3784 ret = obj_get_attr(raid_tab, controller_obj_id,
3785 (void **)(&controller_attr));
3786
3787 /* Get disk attributes */
3788 ret = obj_get_attr(raid_tab, disk_obj_id,
3789 (void **)(&disk_attr));
3790 if (disk_attr->state == DISK_STATE_FAILED) {
3791 free(hsp_relation);
3792 return (ERR_DISK_STATE);
3793 }
3794
3795 /* If it's not a hsp disk */
3796 obj_id = obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP);
3797 if (obj_id == OBJ_NONE) {
3798 free(hsp_relation);
3799 return (ERR_DISK_STATE);
3800 }
3801 ret = obj_get_attr(raid_tab, obj_id, (void **)(&hsp_attr));
3802
3803 if (array_obj_id != OBJ_ATTR_NONE) {
3804 if (raid_obj_get_type(raid_tab, array_obj_id) !=
3805 OBJ_TYPE_ARRAY) {
3806 free(hsp_relation);
3807 return (ERR_DEVICE_TYPE);
3808 }
3809
3810 /* Get array attributes */
3811 ret = obj_get_attr(raid_tab, array_obj_id,
3812 (void **)(&array_attr));
3813
3814 /* If It's belong to another controller */
3815 if (controller_obj_id != obj_get_controller(raid_tab,
3816 array_obj_id)) {
3817 free(hsp_relation);
3818 return (ERR_DRIVER_ACROSS);
3819 }
3820
3821 /* If want to remove an array from a global hsp */
3822 if (hsp_attr->type == HSP_TYPE_GLOBAL) {
3823 free(hsp_relation);
3824 return (ERR_OP_ILLEGAL);
3825 }
3826
3827 do {
3828 (void) obj_get_attr(raid_tab, obj_id,
3829 (void **)(&hsp_attr));
3830
3831 if (hsp_attr->associated_id ==
3832 array_attr->array_id ||
3833 hsp_attr->type == HSP_TYPE_GLOBAL)
3834 break;
3835
3836 obj_id = obj_get_sibling(raid_tab, obj_id);
3837 } while (obj_id > OBJ_NONE);
3838 } else if (hsp_attr->type != HSP_TYPE_GLOBAL) {
3839 /* if global hsp is supported */
3840 free(hsp_relation);
3841 return (ERR_OP_ILLEGAL);
3842 }
3843
3844 /*
3845 * If array is associated with a local hsp, or remove a
3846 * global hsp disk
3847 */
3848 if ((obj_id && (array_obj_id != OBJ_ATTR_NONE)) ||
3849 (array_obj_id == OBJ_ATTR_NONE)) {
3850 if (array_obj_id != OBJ_ATTR_NONE)
3851 hsp_relation->array_id = array_attr->array_id;
3852 else
3853 hsp_relation->array_id =
3854 (uint32_t)OBJ_ATTR_NONE;
3855 hsp_relation->disk_id = disk_attr->disk_id;
3856 } else {
3857 free(hsp_relation);
3858 return (ERR_OP_ILLEGAL);
3859 }
3860
3861 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id);
3862 fd = raid_obj_get_fd(raid_tab, controller_obj_id);
3863 if ((raid_lib == NULL) || (fd == 0))
3864 return (ERR_DRIVER_CLOSED);
3865
3866 if (raid_lib->hsp_unbind == NULL) {
3867 free(hsp_relation);
3868 return (ERR_OP_NO_IMPL);
3869 }
3870
3871 ret = raid_lib->hsp_unbind(controller_attr->controller_id,
3872 hsp_relation, plugin_err_str);
3873
3874 free(hsp_relation);
3875 return (ret);
3876 }
3877
3878 /*
3879 * Object maintennance routines
3880 */
3881 static int
raid_obj_create_system_obj(raid_obj_tab_t * raid_tab)3882 raid_obj_create_system_obj(raid_obj_tab_t *raid_tab)
3883 {
3884 raid_obj_t *raid_obj;
3885 int ret;
3886
3887 raid_obj = calloc(1, sizeof (raid_obj_t));
3888 if (raid_obj == NULL)
3889 return (ERR_NOMEM);
3890
3891 raid_obj->obj_id = OBJ_SYSTEM;
3892 raid_obj->obj_type_id = OBJ_TYPE_SYSTEM;
3893 raid_obj->data = NULL;
3894
3895 ret = raid_obj_tab_insert(raid_tab, raid_obj->obj_id, raid_obj);
3896 if (ret == ERR_DEVICE_DUP) {
3897 free(raid_obj);
3898 return (ERR_DEVICE_UNCLEAN);
3899 }
3900
3901 return (SUCCESS);
3902 }
3903
3904 static raid_obj_id_t
raid_obj_id_new(raid_obj_tab_t * raid_tab)3905 raid_obj_id_new(raid_obj_tab_t *raid_tab)
3906 {
3907 ++ raid_tab->obj_id_cnt;
3908 if (raid_tab->obj_id_cnt <= 0)
3909 return (ERR_DEVICE_OVERFLOW);
3910
3911 return (raid_tab->obj_id_cnt);
3912 }
3913
3914 static void *
raid_obj_attr_new(raid_obj_type_id_t obj_type)3915 raid_obj_attr_new(raid_obj_type_id_t obj_type)
3916 {
3917 void *obj_attr = NULL;
3918
3919 switch (obj_type) {
3920 case OBJ_TYPE_CONTROLLER:
3921 obj_attr = calloc(1, sizeof (controller_attr_t));
3922 break;
3923 case OBJ_TYPE_ARRAY:
3924 obj_attr = calloc(1, sizeof (array_attr_t));
3925 break;
3926 case OBJ_TYPE_DISK:
3927 obj_attr = calloc(1, sizeof (disk_attr_t));
3928 break;
3929 case OBJ_TYPE_HSP:
3930 obj_attr = calloc(1, sizeof (hsp_attr_t));
3931 break;
3932 case OBJ_TYPE_ARRAY_PART:
3933 obj_attr = calloc(1, sizeof (arraypart_attr_t));
3934 break;
3935 case OBJ_TYPE_DISK_SEG:
3936 obj_attr = calloc(1, sizeof (diskseg_attr_t));
3937 break;
3938 case OBJ_TYPE_TASK:
3939 obj_attr = calloc(1, sizeof (task_attr_t));
3940 break;
3941 case OBJ_TYPE_PROP:
3942 obj_attr = calloc(1, sizeof (property_attr_t));
3943 break;
3944 default:
3945 break;
3946 }
3947
3948 return (obj_attr);
3949 }
3950
3951 static raid_obj_id_t
raid_obj_create(raid_obj_tab_t * raid_tab,raid_obj_type_id_t obj_type)3952 raid_obj_create(raid_obj_tab_t *raid_tab, raid_obj_type_id_t obj_type)
3953 {
3954 raid_obj_t *raid_obj;
3955 int ret;
3956 void *data_ptr;
3957
3958 raid_obj = calloc(1, sizeof (raid_obj_t));
3959 if (raid_obj == NULL)
3960 return (ERR_NOMEM);
3961
3962 raid_obj->obj_id = raid_obj_id_new(raid_tab);
3963 if (raid_obj->obj_id < OBJ_NONE)
3964 return (ERR_DEVICE_OVERFLOW);
3965
3966 ret = raid_obj_tab_insert(raid_tab, raid_obj->obj_id, raid_obj);
3967 if (ret == ERR_DEVICE_DUP) {
3968 free(raid_obj);
3969 return (ERR_DEVICE_DUP);
3970 }
3971
3972 data_ptr = raid_obj_attr_new(obj_type);
3973 if (data_ptr == NULL) {
3974 (void) raid_obj_delete(raid_tab, raid_obj->obj_id);
3975 return (ERR_NOMEM);
3976 }
3977
3978 (void) raid_obj_set_data_ptr(raid_tab, raid_obj->obj_id, data_ptr);
3979
3980 (void) raid_obj_set_type(raid_tab, raid_obj->obj_id, obj_type);
3981 return (raid_obj->obj_id);
3982 }
3983
3984 static int
raid_obj_delete(raid_obj_tab_t * raid_tab,raid_obj_id_t raid_obj_id)3985 raid_obj_delete(raid_obj_tab_t *raid_tab, raid_obj_id_t raid_obj_id)
3986 {
3987 raid_obj_t *obj;
3988
3989 obj = raid_obj_tab_remove(raid_tab, raid_obj_id);
3990 if (obj != NULL) {
3991 free(obj->data);
3992 free(obj);
3993 return (SUCCESS);
3994 }
3995
3996 return (ERR_DEVICE_NOENT);
3997 }
3998
3999 static int
raid_obj_add_org(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_id_t container_id)4000 raid_obj_add_org(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4001 raid_obj_id_t container_id)
4002 {
4003 raid_obj_id_t tmp, tmp1;
4004
4005 tmp = raid_obj_get_comp(raid_tab, container_id);
4006 if (tmp < OBJ_NONE)
4007 return (ERR_DEVICE_NOENT);
4008
4009 if (tmp == OBJ_NONE) {
4010 (void) raid_obj_set_container(raid_tab, obj_id, container_id);
4011 (void) raid_obj_set_comp(raid_tab, container_id, obj_id);
4012 return (SUCCESS);
4013 }
4014
4015 while ((tmp1 = raid_obj_get_sibling(raid_tab, tmp)) != OBJ_NONE)
4016 tmp = tmp1;
4017
4018 if (raid_obj_set_sibling(raid_tab, tmp, obj_id) < SUCCESS)
4019 return (ERR_DEVICE_NOENT);
4020 (void) raid_obj_set_container(raid_tab, obj_id, container_id);
4021
4022 return (SUCCESS);
4023 }
4024
4025 static raid_obj_type_id_t
raid_obj_get_type(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4026 raid_obj_get_type(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4027 {
4028 raid_obj_t *obj;
4029
4030 obj = raid_obj_tab_find(raid_tab, obj_id);
4031 if (obj == NULL)
4032 return (ERR_DEVICE_NOENT);
4033
4034 if ((obj->obj_type_id < OBJ_TYPE_SYSTEM) ||
4035 (obj->obj_type_id >= OBJ_TYPE_ALL))
4036 return (ERR_DEVICE_INVALID);
4037
4038 return (obj->obj_type_id);
4039 }
4040
4041 static int
raid_obj_set_type(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_type_id_t type)4042 raid_obj_set_type(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4043 raid_obj_type_id_t type)
4044 {
4045 raid_obj_t *obj;
4046
4047 obj = raid_obj_tab_find(raid_tab, obj_id);
4048 if (obj == NULL)
4049 return (ERR_DEVICE_NOENT);
4050
4051 if ((type < OBJ_TYPE_SYSTEM) || (type >= OBJ_TYPE_ALL))
4052 return (ERR_DEVICE_TYPE);
4053
4054 obj->obj_type_id = type;
4055 return (SUCCESS);
4056 }
4057
4058 static raid_obj_status_t
raid_obj_get_status(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4059 raid_obj_get_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4060 {
4061 raid_obj_t *obj;
4062
4063 obj = raid_obj_tab_find(raid_tab, obj_id);
4064 if (obj == NULL)
4065 return (ERR_DEVICE_NOENT);
4066
4067 return (obj->status);
4068 }
4069
4070 static int
raid_obj_set_status(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_status_t status)4071 raid_obj_set_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4072 raid_obj_status_t status)
4073 {
4074 raid_obj_t *obj;
4075
4076 obj = raid_obj_tab_find(raid_tab, obj_id);
4077 if (obj == NULL)
4078 return (ERR_DEVICE_NOENT);
4079
4080 obj->status = obj->status | status;
4081
4082 return (SUCCESS);
4083 }
4084
4085 static int
raid_obj_clear_status(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_status_t status)4086 raid_obj_clear_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4087 raid_obj_status_t status)
4088 {
4089 raid_obj_t *obj;
4090
4091 obj = raid_obj_tab_find(raid_tab, obj_id);
4092 if (obj == NULL)
4093 return (ERR_DEVICE_NOENT);
4094
4095 obj->status = obj->status & ~status;
4096
4097 return (SUCCESS);
4098 }
4099
4100 static raid_obj_id_t
raid_obj_get_container(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4101 raid_obj_get_container(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4102 {
4103 raid_obj_t *obj;
4104
4105 obj = raid_obj_tab_find(raid_tab, obj_id);
4106 if (obj == NULL)
4107 return (ERR_DEVICE_NOENT);
4108
4109 return (obj->container);
4110 }
4111
4112 static int
raid_obj_set_container(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_id_t container_id)4113 raid_obj_set_container(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4114 raid_obj_id_t container_id)
4115 {
4116 raid_obj_t *obj;
4117
4118 obj = raid_obj_tab_find(raid_tab, obj_id);
4119 if (obj == NULL)
4120 return (ERR_DEVICE_NOENT);
4121
4122 obj->container = container_id;
4123 return (SUCCESS);
4124 }
4125
4126 static raid_obj_id_t
raid_obj_get_comp(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4127 raid_obj_get_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4128 {
4129 raid_obj_t *obj;
4130
4131 obj = raid_obj_tab_find(raid_tab, obj_id);
4132 if (obj == NULL)
4133 return (ERR_DEVICE_NOENT);
4134
4135 return (obj->component);
4136 }
4137
4138 static int
raid_obj_set_comp(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_id_t comp)4139 raid_obj_set_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4140 raid_obj_id_t comp)
4141 {
4142 raid_obj_t *obj;
4143
4144 obj = raid_obj_tab_find(raid_tab, obj_id);
4145 if (obj == NULL)
4146 return (ERR_DEVICE_NOENT);
4147
4148 obj->component = comp;
4149 return (SUCCESS);
4150 }
4151
4152 static raid_obj_id_t
raid_obj_get_sibling(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4153 raid_obj_get_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4154 {
4155 raid_obj_t *obj;
4156
4157 obj = raid_obj_tab_find(raid_tab, obj_id);
4158 if (obj == NULL)
4159 return (ERR_DEVICE_NOENT);
4160
4161 return (obj->sibling);
4162 }
4163
4164 static int
raid_obj_set_sibling(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_id_t sibling)4165 raid_obj_set_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4166 raid_obj_id_t sibling)
4167 {
4168 raid_obj_t *obj;
4169
4170 obj = raid_obj_tab_find(raid_tab, obj_id);
4171 if (obj == NULL)
4172 return (ERR_DEVICE_NOENT);
4173
4174 obj->sibling = sibling;
4175
4176 return (SUCCESS);
4177 }
4178
4179 static void *
raid_obj_get_data_ptr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4180 raid_obj_get_data_ptr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4181 {
4182 raid_obj_t *obj;
4183
4184 obj = raid_obj_tab_find(raid_tab, obj_id);
4185 if (obj == NULL)
4186 return (NULL);
4187
4188 return (obj->data);
4189 }
4190
4191 static int
raid_obj_set_data_ptr(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,void * data)4192 raid_obj_set_data_ptr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4193 void *data)
4194 {
4195 raid_obj_t *obj;
4196
4197 obj = raid_obj_tab_find(raid_tab, obj_id);
4198 if (obj == NULL)
4199 return (ERR_DEVICE_NOENT);
4200
4201 obj->data = data;
4202
4203 return (SUCCESS);
4204 }
4205
4206 static raid_obj_handle_t
raid_obj_get_handle(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id)4207 raid_obj_get_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id)
4208 {
4209 raid_obj_t *obj;
4210
4211 obj = raid_obj_tab_find(raid_tab, obj_id);
4212 if (obj == NULL)
4213 return (ERR_DEVICE_NOENT);
4214
4215 return (obj->handle);
4216 }
4217
4218 static int
raid_obj_set_handle(raid_obj_tab_t * raid_tab,raid_obj_id_t obj_id,raid_obj_handle_t handle)4219 raid_obj_set_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id,
4220 raid_obj_handle_t handle)
4221 {
4222 raid_obj_t *obj;
4223
4224 obj = raid_obj_tab_find(raid_tab, obj_id);
4225 if (obj == NULL)
4226 return (ERR_DEVICE_NOENT);
4227
4228 obj->handle = handle;
4229 return (SUCCESS);
4230 }
4231 /*
4232 * Object list maintennance routines
4233 */
4234 static void
raid_list_create(raid_list_t * list,size_t offset)4235 raid_list_create(raid_list_t *list, size_t offset)
4236 {
4237 list->head = NULL;
4238 list->tail = NULL;
4239 list->offset = offset;
4240 }
4241
4242 static void *
raid_list_head(raid_list_t * list)4243 raid_list_head(raid_list_t *list)
4244 {
4245 return (list->head);
4246 }
4247
4248 static void *
raid_list_next(raid_list_t * list,void * obj)4249 raid_list_next(raid_list_t *list, void *obj)
4250 {
4251 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj);
4252
4253 return (el->next);
4254 }
4255
4256 static void
raid_list_insert_tail(raid_list_t * list,void * obj)4257 raid_list_insert_tail(raid_list_t *list, void *obj)
4258 {
4259 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj), *el1;
4260
4261 el->prev = list->tail;
4262 list->tail = obj;
4263
4264 el->next = NULL;
4265
4266 if (list->head == NULL)
4267 list->head = obj;
4268
4269 if (el->prev != NULL) {
4270 el1 = LIST_OBJ_TO_EL(list, el->prev);
4271 el1->next = obj;
4272 }
4273 }
4274
4275 static void
raid_list_remove(raid_list_t * list,void * obj)4276 raid_list_remove(raid_list_t *list, void *obj)
4277 {
4278 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj), *el1;
4279
4280 if (list->head == obj)
4281 list->head = el->next;
4282
4283 if (list->tail == obj)
4284 list->tail = el->prev;
4285
4286 if (el->next != NULL) {
4287 el1 = LIST_OBJ_TO_EL(list, el->next);
4288 el1->prev = el->prev;
4289 }
4290
4291 if (el->prev != NULL) {
4292 el1 = LIST_OBJ_TO_EL(list, el->prev);
4293 el1->next = el->next;
4294 }
4295
4296 el->prev = el->next = NULL;
4297 }
4298
4299 static void *
raid_list_remove_head(raid_list_t * list)4300 raid_list_remove_head(raid_list_t *list)
4301 {
4302 void *obj = list->head;
4303
4304 if (obj != NULL)
4305 raid_list_remove(list, obj);
4306
4307 return (obj);
4308 }
4309
4310 static void *
raid_list_find(raid_list_t * list,raid_obj_id_t obj_id)4311 raid_list_find(raid_list_t *list, raid_obj_id_t obj_id)
4312 {
4313 raid_obj_t *obj;
4314
4315 for (obj = raid_list_head(list); obj != NULL;
4316 obj = raid_list_next(list, obj))
4317 if (obj->obj_id == obj_id)
4318 break;
4319
4320 return (obj);
4321 }
4322
4323 static int
raid_obj_tab_create(raid_obj_tab_t * tab,size_t hash_slots)4324 raid_obj_tab_create(raid_obj_tab_t *tab, size_t hash_slots)
4325 {
4326 unsigned i;
4327
4328 if (hash_slots == 0)
4329 return (ERR_OP_ILLEGAL);
4330
4331 tab->slots = hash_slots;
4332
4333 if ((tab->table = calloc(hash_slots, sizeof (raid_list_t))) == NULL)
4334 return (ERR_NOMEM);
4335
4336 for (i = 0; i < hash_slots; i++)
4337 raid_list_create(&tab->table[i], offsetof(raid_obj_t, el));
4338
4339 return (SUCCESS);
4340 }
4341
4342 static void
raid_obj_tab_destroy(raid_obj_tab_t * tab)4343 raid_obj_tab_destroy(raid_obj_tab_t *tab)
4344 {
4345 unsigned i;
4346
4347 for (i = 0; i < tab->slots; i++) {
4348 struct raid_obj_t *obj;
4349
4350 while ((obj = raid_list_remove_head(&tab->table[i])) != NULL)
4351 free(obj);
4352
4353 raid_list_destroy(&tab->table[i]);
4354 }
4355
4356 if (tab->table)
4357 free(tab->table);
4358
4359 tab->table = NULL;
4360 tab->slots = 0;
4361 tab->obj_id_cnt = 0;
4362 }
4363
4364 static int
raid_obj_tab_insert(raid_obj_tab_t * tab,raid_obj_id_t id,void * obj)4365 raid_obj_tab_insert(raid_obj_tab_t *tab, raid_obj_id_t id, void *obj)
4366 {
4367 raid_list_t *list;
4368
4369 list = OBJ_TAB_SLOT(tab, id);
4370
4371 if (raid_list_find(list, id) != NULL)
4372 return (ERR_DEVICE_DUP);
4373
4374 raid_list_insert_tail(list, obj);
4375
4376 return (SUCCESS);
4377 }
4378
4379 static void *
raid_obj_tab_remove(raid_obj_tab_t * tab,raid_obj_id_t id)4380 raid_obj_tab_remove(raid_obj_tab_t *tab, raid_obj_id_t id)
4381 {
4382 raid_list_t *list;
4383 raid_obj_t *obj;
4384
4385 list = OBJ_TAB_SLOT(tab, id);
4386
4387 if ((obj = raid_list_find(list, id)) != NULL)
4388 raid_list_remove(list, obj);
4389
4390 return (obj);
4391 }
4392
4393 static void *
raid_obj_tab_find(raid_obj_tab_t * tab,raid_obj_id_t id)4394 raid_obj_tab_find(raid_obj_tab_t *tab, raid_obj_id_t id)
4395 {
4396 raid_list_t *list;
4397 raid_obj_t *obj;
4398
4399 list = OBJ_TAB_SLOT(tab, id);
4400 obj = raid_list_find(list, id);
4401
4402 return (obj);
4403 }
4404
4405 static void
raid_list_destroy(raid_list_t * list)4406 raid_list_destroy(raid_list_t *list)
4407 {
4408 list->head = NULL;
4409 list->tail = NULL;
4410 list->offset = 0;
4411 }
4412
4413 /*
4414 * Plug-in maintennance routines
4415 */
4416 static int
controller_id_to_path(uint32_t controller_id,char * path)4417 controller_id_to_path(uint32_t controller_id, char *path)
4418 {
4419 int fd;
4420 char buf[MAX_PATH_LEN] = {0}, buf1[MAX_PATH_LEN] = {0}, *colon;
4421
4422 (void) snprintf(buf, MAX_PATH_LEN, "%s/c%d", CFGDIR, controller_id);
4423 if (readlink(buf, buf1, sizeof (buf1)) < 0)
4424 return (ERR_DRIVER_NOT_FOUND);
4425
4426 if (buf1[0] != '/')
4427 (void) snprintf(buf, sizeof (buf), "%s/", CFGDIR);
4428 else
4429 buf[0] = 0;
4430 (void) strlcat(buf, buf1, MAX_PATH_LEN);
4431
4432 colon = strrchr(buf, ':');
4433 if (colon == NULL)
4434 return (ERR_DRIVER_NOT_FOUND);
4435 else
4436 *colon = 0;
4437
4438 (void) snprintf(path, MAX_PATH_LEN, "%s:devctl", buf);
4439
4440 fd = open(path, O_RDONLY | O_NDELAY);
4441
4442 if (fd < 0)
4443 return (ERR_DRIVER_NOT_FOUND);
4444
4445 (void) close(fd);
4446
4447 return (SUCCESS);
4448 }
4449
4450 static char *
controller_id_to_driver_name(uint32_t controller_id)4451 controller_id_to_driver_name(uint32_t controller_id)
4452 {
4453 char buf[MAX_PATH_LEN];
4454 di_node_t di_node;
4455 char *name, *tmp;
4456 int ret;
4457
4458 ret = controller_id_to_path(controller_id, buf);
4459 if (ret < SUCCESS)
4460 return (NULL);
4461
4462 tmp = strrchr(buf, ':');
4463 if (tmp != NULL)
4464 *tmp = 0;
4465
4466 tmp = strstr(buf, "pci");
4467 if (tmp == NULL)
4468 return (NULL);
4469
4470 di_node = di_init(tmp, DINFOPROP);
4471 if (di_node == DI_NODE_NIL)
4472 return (NULL);
4473
4474 name = di_driver_name(di_node);
4475
4476 return (name);
4477 }
4478
4479 static void
raid_plugin_init()4480 raid_plugin_init()
4481 {
4482 raid_lib_t *raid_lib = raid_lib_sys;
4483
4484 while (raid_lib) {
4485 raid_lib_sys = raid_lib->next;
4486 (void) dlclose(raid_lib->lib_handle);
4487 free(raid_lib);
4488 raid_lib = raid_lib_sys;
4489 }
4490 }
4491
4492 static raid_lib_t *
raid_plugin_load(char * driver_name)4493 raid_plugin_load(char *driver_name)
4494 {
4495 char buf[MAX_PATH_LEN] = {0};
4496 raid_lib_t *supplib;
4497 void *sym;
4498
4499 supplib = calloc(1, sizeof (raid_lib_t));
4500 if (supplib == NULL)
4501 return (NULL);
4502
4503 (void) snprintf(buf, MAX_PATH_LEN, "%s/%s.so.1",
4504 SUPP_PLUGIN_DIR, driver_name);
4505
4506 supplib->lib_handle = dlopen(buf, RTLD_LAZY);
4507 if (supplib->lib_handle == NULL) {
4508 free(supplib);
4509 return (NULL);
4510 }
4511
4512 supplib->name = driver_name;
4513
4514 if ((sym = dlsym(supplib->lib_handle, "rdcfg_version")) == NULL)
4515 supplib->version = RDCFG_PLUGIN_V1;
4516 else {
4517 supplib->version = *((uint32_t *)sym);
4518 if (supplib->version != RDCFG_PLUGIN_V1) {
4519 (void) dlclose(supplib->lib_handle);
4520 free(supplib);
4521 return (NULL);
4522 }
4523 }
4524
4525 if ((sym = dlsym(supplib->lib_handle, "rdcfg_open_controller")) ==
4526 NULL) {
4527 (void) dlclose(supplib->lib_handle);
4528 free(supplib);
4529 return (NULL);
4530 } else
4531 supplib->open_controller = (int(*)(uint32_t, char **))sym;
4532
4533 if ((sym = dlsym(supplib->lib_handle, "rdcfg_close_controller")) ==
4534 NULL) {
4535 (void) dlclose(supplib->lib_handle);
4536 free(supplib);
4537 return (NULL);
4538 } else
4539 supplib->close_controller = (int (*)(uint32_t, char **))sym;
4540
4541 if ((sym = dlsym(supplib->lib_handle, "rdcfg_compnum")) == NULL) {
4542 (void) dlclose(supplib->lib_handle);
4543 free(supplib);
4544 return (NULL);
4545 } else
4546 supplib->compnum = (int (*)(uint32_t, uint32_t,
4547 raid_obj_type_id_t, raid_obj_type_id_t))sym;
4548
4549 if ((sym = dlsym(supplib->lib_handle, "rdcfg_complist")) == NULL) {
4550 (void) dlclose(supplib->lib_handle);
4551 free(supplib);
4552 return (NULL);
4553 } else
4554 supplib->complist = (int (*)(uint32_t, uint32_t,
4555 raid_obj_type_id_t, raid_obj_type_id_t, int, void *))sym;
4556
4557 if ((sym = dlsym(supplib->lib_handle, "rdcfg_get_attr")) == NULL) {
4558 (void) dlclose(supplib->lib_handle);
4559 free(supplib);
4560 return (NULL);
4561 } else
4562 supplib->get_attr = (int (*)(uint32_t, uint32_t, uint32_t,
4563 raid_obj_type_id_t, void*))sym;
4564
4565 if ((sym = dlsym(supplib->lib_handle, "rdcfg_array_create")) == NULL) {
4566 (void) dlclose(supplib->lib_handle);
4567 free(supplib);
4568 return (NULL);
4569 } else
4570 supplib->array_create = (int (*)(uint32_t, array_attr_t *, int,
4571 arraypart_attr_t *, char **))sym;
4572
4573 if ((sym = dlsym(supplib->lib_handle, "rdcfg_array_delete")) == NULL) {
4574 (void) dlclose(supplib->lib_handle);
4575 free(supplib);
4576 return (NULL);
4577 } else
4578 supplib->array_delete =
4579 (int (*)(uint32_t, uint32_t, char **))sym;
4580
4581 supplib->hsp_bind = (int (*)(uint32_t, hsp_relation_t *,
4582 char **))dlsym(supplib->lib_handle, "rdcfg_hsp_bind");
4583 supplib->hsp_unbind = (int (*)(uint32_t, hsp_relation_t *,
4584 char **))dlsym(supplib->lib_handle, "rdcfg_hsp_unbind");
4585 supplib->set_attr = (int (*)(uint32_t, uint32_t, uint32_t, uint32_t *,
4586 char **))dlsym(supplib->lib_handle, "rdcfg_set_attr");
4587 supplib->flash_fw = (int (*)(uint32_t, char *, uint32_t, char **))
4588 dlsym(supplib->lib_handle, "rdcfg_flash_fw");
4589
4590 supplib->next = raid_lib_sys;
4591 raid_lib_sys = supplib;
4592 return (supplib);
4593 }
4594
4595 static raid_lib_t *
raid_find_lib(raid_obj_tab_t * raid_tab,raid_obj_id_t controller_obj_id)4596 raid_find_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t controller_obj_id)
4597 {
4598 controller_attr_t *controller_attr;
4599 raid_lib_t *raid_lib;
4600 char *driver_name;
4601 raid_obj_handle_t handle;
4602
4603 /* Check if it's mapped to handle structure */
4604 handle = raid_obj_to_handle(raid_tab, controller_obj_id);
4605 if (raid_handle_sys.handles[handle].raid_lib != NULL)
4606 return (raid_handle_sys.handles[handle].raid_lib);
4607
4608 (void) obj_get_attr(raid_tab, controller_obj_id,
4609 (void **)(&controller_attr));
4610
4611 /* Check if the plugin module is already loaded */
4612 driver_name = controller_id_to_driver_name(
4613 controller_attr->controller_id);
4614 if (driver_name == NULL)
4615 return (NULL);
4616
4617 raid_lib = raid_lib_sys;
4618 while (raid_lib != NULL) {
4619 if (raid_lib->name != NULL &&
4620 strcmp(driver_name, raid_lib->name) == 0)
4621 return (raid_lib);
4622
4623 raid_lib = raid_lib->next;
4624 }
4625
4626 /* Loading the plugin module */
4627 raid_lib = raid_plugin_load(driver_name);
4628
4629 return (raid_lib);
4630 }
4631