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.
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.
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]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
29 #include <sys/types.h>
39 #include <sys/mnttab.h>
40 #include <config_admin.h>
41 #include <sys/param.h>
43 #include <libdevinfo.h>
49 #define TEXT_DOMAIN "SYS_TEST"
53 #define HANDLER_SLOTS 256
58 #define OBJ_STATUS_CMD_CLEAN -1
59 #define OBJ_STATUS_OPENED 1
60 #define OBJ_STATUS_SCANCOMP 1 << 1
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"
67 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg"
73 typedef int raid_obj_id_t
;
74 typedef int raid_obj_status_t
;
77 * Data structures used for object maintennance
82 size_t offset
; /* offset of double-linked element (raid_list_el_t) */
83 /* in the linked data structures (objects) */
92 raid_obj_id_t obj_id_cnt
; /* id 0 is reserved */
93 size_t slots
; /* How many lists linked by *table */
98 * Object type structure containing function pointers;
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
*,
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 *,
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 **);
116 * Common object data structure
119 raid_list_el_t el
; /* double-links */
121 raid_obj_type_id_t obj_type_id
;
122 raid_obj_id_t obj_id
;
123 raid_obj_status_t status
;
125 raid_obj_id_t container
;
126 raid_obj_id_t sibling
;
127 raid_obj_id_t component
;
129 void *data
; /* Pointer to attribute structure */
130 raid_obj_handle_t handle
;
134 * Definition about handle
139 uint32_t controller_id
;
145 uint32_t fd
; /* Only for controller */
146 raid_lib_t
*raid_lib
; /* Only for controller */
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))
154 #pragma init(raidcfg_init)
155 #pragma fini(raidcfg_fini)
158 * Function prototypes
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
*,
170 static raid_obj_handle_t
raid_obj_to_handle(raid_obj_tab_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
,
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
,
186 static raid_obj_id_t
obj_locate_hsp(raid_obj_tab_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,
191 static raid_obj_id_t
obj_locate_diskseg(raid_obj_tab_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,
196 static raid_obj_id_t
obj_get_controller(raid_obj_tab_t
*, raid_obj_id_t
);
198 static int obj_sys_compnum(raid_obj_tab_t
*, raid_obj_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
,
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
,
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
,
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 **);
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
,
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
,
244 static int raid_obj_clear_status(raid_obj_tab_t
*, raid_obj_id_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
,
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
,
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
*,
258 static int raid_obj_set_handle(raid_obj_tab_t
*, raid_obj_id_t
,
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
*);
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
);
281 /* Global object table */
282 static raid_obj_tab_t raid_tab_sys
= {0, 0, NULL
};
284 /* Plug-in modules maintenance data structures */
285 static raid_lib_t
*raid_lib_sys
= NULL
;
287 /* Handle table definition */
292 handle_attr_t
*handles
;
293 } raid_handle_sys
= {0, 0, 0, NULL
};
296 * RAID object method table definition
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 */
321 * Mutex for multithread safe
323 static mutex_t raidcfg_mp
;
326 * RaidCfg library APIs
329 raidcfg_errstr(int err_code
)
333 (void) mutex_lock(&raidcfg_mp
);
336 ret_val
= dgettext(TEXT_DOMAIN
, "Operation succeeded.\n");
339 ret_val
= dgettext(TEXT_DOMAIN
,
340 "Request standard IOCTL service.\n");
342 case ERR_DRIVER_NOT_FOUND
:
343 ret_val
= dgettext(TEXT_DOMAIN
,
344 "Controller device can not be found.\n");
346 case ERR_DRIVER_OPEN
:
347 ret_val
= dgettext(TEXT_DOMAIN
, "Can not open controller.\n");
349 case ERR_DRIVER_LOCK
:
350 ret_val
= dgettext(TEXT_DOMAIN
, "Controller is locked.\n");
352 case ERR_DRIVER_CLOSED
:
353 ret_val
= dgettext(TEXT_DOMAIN
, "Controller is not opened.\n");
355 case ERR_DRIVER_ACROSS
:
356 ret_val
= dgettext(TEXT_DOMAIN
,
357 "Operation across multiple controllers.\n");
359 case ERR_ARRAY_LEVEL
:
360 ret_val
= dgettext(TEXT_DOMAIN
,
361 "Operation not support with volume of this level.\n");
364 ret_val
= dgettext(TEXT_DOMAIN
,
365 "Capacity of array out of range.\n");
367 case ERR_ARRAY_STRIPE_SIZE
:
368 ret_val
= dgettext(TEXT_DOMAIN
, "Illegal stripe size.\n");
370 case ERR_ARRAY_CACHE_POLICY
:
371 ret_val
= dgettext(TEXT_DOMAIN
,
372 "Illegal cache-write policy.\n");
374 case ERR_ARRAY_IN_USE
:
375 ret_val
= dgettext(TEXT_DOMAIN
, "Array or disk in use.\n");
378 ret_val
= dgettext(TEXT_DOMAIN
, "Array has background task.\n");
380 case ERR_ARRAY_CONFIG
:
381 ret_val
= dgettext(TEXT_DOMAIN
,
382 "Configuration over device node failed.\n");
384 case ERR_ARRAY_DISKNUM
:
385 ret_val
= dgettext(TEXT_DOMAIN
, "Incorrect number of disks.\n");
387 case ERR_ARRAY_LAYOUT
:
388 ret_val
= dgettext(TEXT_DOMAIN
, "Illegal array layout.\n");
390 case ERR_ARRAY_AMOUNT
:
391 ret_val
= dgettext(TEXT_DOMAIN
, "Too many arrays.\n");
394 ret_val
= dgettext(TEXT_DOMAIN
,
395 "Incorrect disk status for current operation.\n");
398 ret_val
= dgettext(TEXT_DOMAIN
, "No enough disk space.\n");
400 case ERR_DISK_SEG_AMOUNT
:
401 ret_val
= dgettext(TEXT_DOMAIN
, "Too many disk segments.\n");
403 case ERR_DISK_NOT_EMPTY
:
404 ret_val
= dgettext(TEXT_DOMAIN
, "Disk has occupied space.\n");
407 ret_val
= dgettext(TEXT_DOMAIN
, "Disk has background task.\n");
410 ret_val
= dgettext(TEXT_DOMAIN
,
411 "Incorrect task state for current operation.\n");
414 ret_val
= dgettext(TEXT_DOMAIN
, "Illegal operation.\n");
417 ret_val
= dgettext(TEXT_DOMAIN
,
418 "Operation is not implemented.\n");
421 ret_val
= dgettext(TEXT_DOMAIN
, "Operation failed.\n");
423 case ERR_DEVICE_NOENT
:
424 ret_val
= dgettext(TEXT_DOMAIN
, "Device not found.\n");
426 case ERR_DEVICE_TYPE
:
427 ret_val
= dgettext(TEXT_DOMAIN
, "Illegal type of device.\n");
430 ret_val
= dgettext(TEXT_DOMAIN
, "Device record duplicated.\n");
432 case ERR_DEVICE_OVERFLOW
:
433 ret_val
= dgettext(TEXT_DOMAIN
, "Too many devices.\n");
435 case ERR_DEVICE_UNCLEAN
:
436 ret_val
= dgettext(TEXT_DOMAIN
, "Device pool is not clean.\n");
438 case ERR_DEVICE_INVALID
:
439 ret_val
= dgettext(TEXT_DOMAIN
, "Device record is invalid.\n");
442 ret_val
= dgettext(TEXT_DOMAIN
,
443 "Can not allocate more memory space.\n");
446 ret_val
= dgettext(TEXT_DOMAIN
, "No privilege.\n");
449 ret_val
= dgettext(TEXT_DOMAIN
, "Undefined error.\n");
451 (void) mutex_unlock(&raidcfg_mp
);
457 raidcfg_get_controller(uint32_t controller_id
)
459 raid_obj_id_t obj_id
;
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
);
470 if (obj_id
== OBJ_NONE
) {
471 (void) mutex_unlock(&raidcfg_mp
);
472 return (ERR_DEVICE_NOENT
);
474 ret_val
= raid_obj_to_handle(&raid_tab_sys
, obj_id
);
475 (void) mutex_unlock(&raidcfg_mp
);
481 raidcfg_get_array(int controller_handle
, uint64_t target_id
, uint64_t lun
)
483 raid_obj_id_t obj_id
;
484 raidcfg_array_t
*attr
;
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
);
495 obj_id
= obj_get_comp(&raid_tab_sys
, obj_id
, OBJ_TYPE_ARRAY
);
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
)
503 obj_id
= obj_get_sibling(&raid_tab_sys
, obj_id
);
506 if (obj_id
< OBJ_NONE
) {
507 (void) mutex_unlock(&raidcfg_mp
);
510 if (obj_id
== OBJ_NONE
) {
511 (void) mutex_unlock(&raidcfg_mp
);
512 return (ERR_DEVICE_NOENT
);
514 ret_val
= raid_obj_to_handle(&raid_tab_sys
, obj_id
);
515 (void) mutex_unlock(&raidcfg_mp
);
521 raidcfg_get_disk(int controller_handle
, disk_tag_t tag
)
523 raid_obj_id_t obj_id
;
524 raidcfg_disk_t
*attr
;
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
);
535 obj_id
= obj_get_comp(&raid_tab_sys
, obj_id
, OBJ_TYPE_DISK
);
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
)
544 obj_id
= obj_get_sibling(&raid_tab_sys
, obj_id
);
547 if (obj_id
< OBJ_NONE
) {
548 (void) mutex_unlock(&raidcfg_mp
);
551 if (obj_id
== OBJ_NONE
) {
552 (void) mutex_unlock(&raidcfg_mp
);
553 return (ERR_DEVICE_NOENT
);
555 ret_val
= raid_obj_to_handle(&raid_tab_sys
, obj_id
);
556 (void) mutex_unlock(&raidcfg_mp
);
562 raidcfg_open_controller(int handle
, char **plugin_err_str
)
564 raid_obj_id_t obj_id
;
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
);
576 ret
= obj_controller_act(&raid_tab_sys
, obj_id
,
577 ACT_CONTROLLER_OPEN
, NULL
, plugin_err_str
);
579 (void) mutex_unlock(&raidcfg_mp
);
582 (void) mutex_unlock(&raidcfg_mp
);
588 raidcfg_close_controller(int handle
, char **plugin_err_str
)
590 raid_obj_id_t obj_id
;
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
);
602 ret
= obj_controller_act(&raid_tab_sys
, obj_id
,
603 ACT_CONTROLLER_CLOSE
, NULL
, plugin_err_str
);
605 (void) mutex_unlock(&raidcfg_mp
);
608 (void) mutex_unlock(&raidcfg_mp
);
614 raidcfg_get_type(int handle
)
616 raid_obj_id_t obj_id
;
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
);
627 ret_val
= raid_obj_get_type(&raid_tab_sys
, obj_id
);
628 (void) mutex_unlock(&raidcfg_mp
);
634 raidcfg_get_attr(int handle
, void *attr
)
636 raid_obj_id_t obj_id
;
637 raid_obj_type_id_t type
;
641 (void) mutex_lock(&raidcfg_mp
);
642 (void) obj_rescan(&raid_tab_sys
);
644 (void) mutex_unlock(&raidcfg_mp
);
645 return (ERR_DEVICE_INVALID
);
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
);
655 type
= raid_obj_get_type(&raid_tab_sys
, obj_id
);
656 ret
= obj_get_attr(&raid_tab_sys
, obj_id
, &data
);
658 (void) mutex_unlock(&raidcfg_mp
);
663 case OBJ_TYPE_CONTROLLER
:
664 size
= sizeof (controller_attr_t
);
667 size
= sizeof (array_attr_t
);
671 raidcfg_hsp_t
*dst
= attr
;
672 hsp_attr_t
*src
= data
;
673 controller_attr_t
*ctlr_attr
;
674 array_attr_t
*array_attr
;
676 dst
->associated_id
= src
->associated_id
;
677 dst
->type
= src
->type
;
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
));
683 (void) mutex_unlock(&raidcfg_mp
);
687 if (src
->type
== HSP_TYPE_LOCAL
) {
688 obj_id
= obj_locate_array(&raid_tab_sys
,
689 ctlr_attr
->controller_id
,
691 ret
= obj_get_attr(&raid_tab_sys
, obj_id
,
692 (void **)(&array_attr
));
694 (void) mutex_unlock(&raidcfg_mp
);
698 dst
->tag
.idl
.target_id
=
699 array_attr
->tag
.idl
.target_id
;
700 dst
->tag
.idl
.lun
= array_attr
->tag
.idl
.lun
;
703 (void) mutex_unlock(&raidcfg_mp
);
706 size
= sizeof (disk_attr_t
);
708 case OBJ_TYPE_ARRAY_PART
:
710 raidcfg_arraypart_t
*dst
= attr
;
711 arraypart_attr_t
*src
= data
;
712 controller_attr_t
*ctlr_attr
;
713 disk_attr_t
*disk_attr
;
715 dst
->disk_id
= src
->disk_id
;
716 dst
->offset
= src
->offset
;
717 dst
->size
= src
->size
;
718 dst
->state
= src
->state
;
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
));
724 (void) mutex_unlock(&raidcfg_mp
);
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
);
739 ret
= obj_get_attr(&raid_tab_sys
, obj_id
,
740 (void **)(&disk_attr
));
742 (void) mutex_unlock(&raidcfg_mp
);
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
;
750 (void) mutex_unlock(&raidcfg_mp
);
752 case OBJ_TYPE_DISK_SEG
:
753 size
= sizeof (diskseg_attr_t
);
756 size
= sizeof (task_attr_t
);
760 property_attr_t
*src
= data
, *dst
= attr
;
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
);
770 if (dst
->prop_size
< src
->prop_size
)
771 size
= dst
->prop_size
;
773 size
= src
->prop_size
;
775 (void) memcpy(dst
->prop
, src
->prop
, size
);
776 (void) mutex_unlock(&raidcfg_mp
);
780 (void) mutex_unlock(&raidcfg_mp
);
781 return (ERR_DEVICE_TYPE
);
784 (void) memcpy(attr
, data
, size
);
786 (void) mutex_unlock(&raidcfg_mp
);
791 raidcfg_get_container(int handle
)
793 raid_obj_id_t obj_id
;
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
);
805 obj_id
= raid_obj_get_container(&raid_tab_sys
, obj_id
);
806 if (obj_id
< OBJ_NONE
) {
807 (void) mutex_unlock(&raidcfg_mp
);
810 ret_val
= raid_obj_to_handle(&raid_tab_sys
, obj_id
);
811 (void) mutex_unlock(&raidcfg_mp
);
817 raidcfg_list_head(int handle
, raid_obj_type_id_t type
)
819 raid_obj_id_t obj_id
;
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
);
831 obj_id
= obj_get_comp(&raid_tab_sys
, obj_id
, type
);
832 if (obj_id
< OBJ_NONE
) {
833 (void) mutex_unlock(&raidcfg_mp
);
836 ret_val
= raid_obj_to_handle(&raid_tab_sys
, obj_id
);
837 (void) mutex_unlock(&raidcfg_mp
);
843 raidcfg_list_next(int handle
)
845 raid_obj_id_t obj_id
;
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
);
857 obj_id
= obj_get_sibling(&raid_tab_sys
, obj_id
);
858 if (obj_id
< OBJ_NONE
) {
859 (void) mutex_unlock(&raidcfg_mp
);
862 ret_val
= raid_obj_to_handle(&raid_tab_sys
, obj_id
);
863 (void) mutex_unlock(&raidcfg_mp
);
869 raidcfg_set_attr(int handle
, uint32_t set_cmd
, void *value
,
870 char **plugin_err_str
)
872 raid_obj_id_t obj_id
;
873 raid_obj_type_id_t type
;
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
);
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
);
891 ret
= raid_obj_op_sys
[type
].set_attr(&raid_tab_sys
,
892 obj_id
, set_cmd
, value
, plugin_err_str
);
894 (void) mutex_unlock(&raidcfg_mp
);
899 raidcfg_update_fw(int handle
, char *file
, char **plugin_err_str
)
901 raid_obj_id_t obj_id
;
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
);
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
);
918 ret
= raid_obj_op_sys
[OBJ_TYPE_CONTROLLER
].act(&raid_tab_sys
,
919 obj_id
, ACT_CONTROLLER_FLASH_FW
, file
, plugin_err_str
);
921 (void) mutex_unlock(&raidcfg_mp
);
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
)
930 raid_obj_id_t
*disk_obj_ids
, obj_id
;
931 array_attr_t
*array_attr
;
932 raid_obj_handle_t array_handle
;
935 (void) mutex_lock(&raidcfg_mp
);
936 (void) obj_rescan(&raid_tab_sys
);
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
);
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
);
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
)) !=
957 (void) obj_rescan(&raid_tab_sys
);
958 (void) mutex_unlock(&raidcfg_mp
);
959 return (ERR_DEVICE_TYPE
);
963 /* Create an empty array object */
964 obj_id
= raid_obj_create(&raid_tab_sys
, OBJ_TYPE_ARRAY
);
965 if (obj_id
< OBJ_NONE
) {
967 (void) obj_rescan(&raid_tab_sys
);
968 (void) mutex_unlock(&raidcfg_mp
);
971 (void) raid_obj_clear_status(&raid_tab_sys
, obj_id
,
972 OBJ_STATUS_CMD_CLEAN
);
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
;
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
);
987 (void) obj_rescan(&raid_tab_sys
);
988 (void) mutex_unlock(&raidcfg_mp
);
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
);
995 (void) obj_rescan(&raid_tab_sys
);
996 (void) mutex_unlock(&raidcfg_mp
);
997 return (array_handle
);
1001 raidcfg_delete_array(int array_handle
, char **plugin_err_str
)
1003 raid_obj_id_t array_obj_id
;
1006 (void) mutex_lock(&raidcfg_mp
);
1007 (void) obj_rescan(&raid_tab_sys
);
1009 if (raidcfg_get_type(array_handle
) != OBJ_TYPE_ARRAY
) {
1010 (void) mutex_unlock(&raidcfg_mp
);
1011 return (ERR_DEVICE_TYPE
);
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
);
1019 if (array_obj_id
== OBJ_NONE
) {
1020 (void) mutex_unlock(&raidcfg_mp
);
1021 return (ERR_DEVICE_INVALID
);
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
);
1028 (void) mutex_unlock(&raidcfg_mp
);
1033 raidcfg_set_hsp(raidcfg_hsp_relation_t
*hsp_relations
,
1034 char **plugin_err_str
)
1036 raid_obj_id_t disk_obj_id
, array_obj_id
;
1037 raid_obj_id_t
*hsp_relation_objs
;
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
);
1047 hsp_relation_objs
= malloc(2 * sizeof (raid_obj_id_t
));
1048 if (hsp_relation_objs
== NULL
) {
1049 (void) mutex_unlock(&raidcfg_mp
);
1053 (void) obj_rescan(&raid_tab_sys
);
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
);
1063 if (array_obj_id
== OBJ_NONE
) {
1064 (void) free(hsp_relation_objs
);
1065 (void) mutex_unlock(&raidcfg_mp
);
1066 return (ERR_DEVICE_NOENT
);
1068 if (raidcfg_get_type(hsp_relations
->array_handle
) !=
1070 free(hsp_relation_objs
);
1071 (void) mutex_unlock(&raidcfg_mp
);
1072 return (ERR_DEVICE_TYPE
);
1075 array_obj_id
= OBJ_ATTR_NONE
;
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
);
1084 if (disk_obj_id
== OBJ_NONE
) {
1085 free(hsp_relation_objs
);
1086 (void) mutex_unlock(&raidcfg_mp
);
1087 return (ERR_DEVICE_NOENT
);
1089 if (raidcfg_get_type(hsp_relations
->disk_handle
) !=
1091 free(hsp_relation_objs
);
1092 (void) mutex_unlock(&raidcfg_mp
);
1093 return (ERR_DEVICE_TYPE
);
1096 hsp_relation_objs
[0] = array_obj_id
;
1097 hsp_relation_objs
[1] = disk_obj_id
;
1099 ret
= raid_obj_op_sys
[OBJ_TYPE_HSP
].bind_obj(&raid_tab_sys
,
1100 hsp_relation_objs
, plugin_err_str
);
1102 (void) obj_rescan(&raid_tab_sys
);
1103 free(hsp_relation_objs
);
1104 (void) mutex_unlock(&raidcfg_mp
);
1110 raidcfg_unset_hsp(raidcfg_hsp_relation_t
*hsp_relations
,
1111 char **plugin_err_str
)
1113 raid_obj_id_t disk_obj_id
, array_obj_id
;
1114 raid_obj_id_t
*hsp_relation_objs
;
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
);
1124 hsp_relation_objs
= malloc(2 * sizeof (raid_obj_id_t
));
1125 if (hsp_relation_objs
== NULL
) {
1126 (void) mutex_unlock(&raidcfg_mp
);
1130 (void) obj_rescan(&raid_tab_sys
);
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
);
1140 if (array_obj_id
== OBJ_NONE
) {
1141 free(hsp_relation_objs
);
1142 (void) mutex_unlock(&raidcfg_mp
);
1143 return (ERR_DEVICE_NOENT
);
1145 if (raidcfg_get_type(hsp_relations
->array_handle
) !=
1147 free(hsp_relation_objs
);
1148 (void) mutex_unlock(&raidcfg_mp
);
1149 return (ERR_DEVICE_TYPE
);
1152 array_obj_id
= OBJ_ATTR_NONE
;
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
);
1161 if (disk_obj_id
== OBJ_NONE
) {
1162 free(hsp_relation_objs
);
1163 (void) mutex_unlock(&raidcfg_mp
);
1164 return (ERR_DEVICE_NOENT
);
1166 if (raidcfg_get_type(hsp_relations
->disk_handle
) !=
1168 free(hsp_relation_objs
);
1169 (void) mutex_unlock(&raidcfg_mp
);
1170 return (ERR_DEVICE_TYPE
);
1173 hsp_relation_objs
[0] = array_obj_id
;
1174 hsp_relation_objs
[1] = disk_obj_id
;
1176 ret
= raid_obj_op_sys
[OBJ_TYPE_HSP
].unbind_obj(&raid_tab_sys
,
1177 hsp_relation_objs
, plugin_err_str
);
1179 (void) obj_rescan(&raid_tab_sys
);
1180 free(hsp_relation_objs
);
1181 (void) mutex_unlock(&raidcfg_mp
);
1187 * RaidCfg lib routines
1192 (void) mutex_init(&raidcfg_mp
, 0, NULL
);
1194 (void) raid_handle_init();
1195 (void) obj_rescan(&raid_tab_sys
);
1202 * Need to close all opened controllers before destroying object table
1204 (void) obj_rescan(&raid_tab_sys
);
1206 raid_obj_tab_destroy(&raid_tab_sys
);
1208 (void) mutex_destroy(&raidcfg_mp
);
1215 intcompare(const void *p1
, const void *p2
)
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
)
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
;
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
))
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
],
1243 if (obj_id
== OBJ_NONE
) {
1244 arraypart_attrs
[i
].offset
= 0;
1245 arraypart_attrs
[i
].size
= disk_attr
->capacity
;
1249 (void) obj_get_attr(raid_tab
, obj_id
, (void **)
1251 arraypart_attrs
[i
].offset
= 0;
1252 arraypart_attrs
[i
].size
= diskseg_attr
->offset
;
1253 offset
= diskseg_attr
->offset
+ diskseg_attr
->size
;
1255 while ((obj_id
= obj_get_sibling(raid_tab
, obj_id
)) !=
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
-
1266 offset
= diskseg_attr
->offset
+ diskseg_attr
->size
;
1269 if ((disk_attr
->capacity
- offset
) > arraypart_attrs
[i
].size
) {
1270 arraypart_attrs
[i
].offset
= offset
;
1271 arraypart_attrs
[i
].size
= disk_attr
->capacity
-
1276 capacity
= OBJ_ATTR_NONE
;
1280 for (i
= 0; i
< num
; ++i
) {
1281 if (disk_objs
[i
] == OBJ_SEPARATOR_BEGIN
) {
1285 if (disk_objs
[i
] == OBJ_SEPARATOR_END
) {
1287 if (disk_layer
!= 0)
1292 if (capacity
> arraypart_attrs
[i
].size
)
1293 capacity
= arraypart_attrs
[i
].size
;
1297 switch (raid_level
) {
1299 capacity
= capacity
* disk_num
;
1302 capacity
= capacity
* disk_num
/ 2;
1305 capacity
= capacity
* disk_num
/ 2;
1308 capacity
= capacity
* (disk_num
- 1);
1311 capacity
= capacity
* disk_num
/ 2;
1314 capacity
= capacity
* (disk_num
- sub_array_num
);
1317 return (ERR_ARRAY_LEVEL
);
1324 * Raid handle maintenance routines
1332 raid_handle_sys
.handle_num
+= HANDLER_SLOTS
;
1333 ptr
= reallocarray(raid_handle_sys
.handles
,
1334 raid_handle_sys
.handle_num
, sizeof (handle_attr_t
));
1337 raid_handle_sys
.handles
= ptr
;
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;
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;
1360 raid_obj_handle_t i
;
1362 i
= raid_handle_sys
.used
;
1364 /* Close all opened controllers */
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
;
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
;
1382 static raid_obj_handle_t
1383 raid_handle_new(raid_obj_type_id_t type
)
1387 if (raid_handle_sys
.unused
== raid_handle_sys
.handle_num
- 1) {
1388 ret
= raid_handle_init();
1393 ret
= raid_handle_sys
.unused
;
1394 raid_handle_sys
.unused
= raid_handle_sys
.handles
[ret
].next
;
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
;
1404 raid_handle_delete(raid_obj_handle_t handle
)
1406 int i
= raid_handle_sys
.used
, j
= 0;
1411 while (i
!= 0 && i
!= handle
) {
1413 i
= raid_handle_sys
.handles
[i
].next
;
1418 raid_handle_sys
.handles
[j
].next
=
1419 raid_handle_sys
.handles
[i
].next
;
1421 raid_handle_sys
.used
=
1422 raid_handle_sys
.handles
[i
].next
;
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
;
1432 raid_handle_delete_controller_comp(uint32_t controller_id
)
1434 int i
= raid_handle_sys
.used
, j
;
1438 i
= raid_handle_sys
.handles
[i
].next
;
1439 if ((raid_handle_sys
.handles
[j
].controller_id
==
1441 (raid_handle_sys
.handles
[j
].type
!=
1442 OBJ_TYPE_CONTROLLER
))
1443 raid_handle_delete(j
);
1447 static raid_obj_id_t
1448 raid_handle_to_obj(raid_obj_tab_t
*raid_tab
, raid_obj_handle_t handle
)
1450 handle_attr_t
*handle_attr
;
1451 raid_obj_id_t obj_id
;
1453 if (handle
== OBJ_SYSTEM
)
1454 return (OBJ_SYSTEM
);
1456 handle_attr
= raid_handle_sys
.handles
+ handle
;
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
);
1465 case OBJ_TYPE_ARRAY
:
1466 obj_id
= obj_locate_array(raid_tab
,
1467 handle_attr
->controller_id
, handle_attr
->array_id
);
1470 obj_id
= obj_locate_hsp(raid_tab
,
1471 handle_attr
->controller_id
, handle_attr
->disk_id
,
1472 handle_attr
->array_id
);
1475 obj_id
= obj_locate_disk(raid_tab
,
1476 handle_attr
->controller_id
, handle_attr
->disk_id
);
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
);
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
);
1489 obj_id
= obj_locate_task(raid_tab
,
1490 handle_attr
->controller_id
, handle_attr
->task_id
);
1493 obj_id
= obj_locate_prop(raid_tab
,
1494 handle_attr
->controller_id
, handle_attr
->disk_id
,
1495 handle_attr
->prop_id
);
1498 return (ERR_DEVICE_INVALID
);
1501 if (obj_id
< OBJ_NONE
)
1503 if (obj_id
== OBJ_NONE
)
1504 return (ERR_DEVICE_NOENT
);
1506 (void) raid_obj_set_handle(raid_tab
, obj_id
, handle
);
1510 static raid_obj_handle_t
1511 raid_obj_to_handle(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
1525 if (obj_id
== OBJ_SYSTEM
)
1526 return (OBJ_SYSTEM
);
1528 /* If the object mapped by a handle */
1529 handle
= raid_obj_get_handle(raid_tab
, obj_id
);
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
)
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
;
1549 case OBJ_TYPE_SYSTEM
:
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
;
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
;
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
;
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
;
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
;
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
=
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
;
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
;
1618 prop_attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
1619 raid_handle_sys
.handles
[handle
].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
;
1630 return (ERR_DEVICE_INVALID
);
1633 (void) raid_obj_set_handle(raid_tab
, obj_id_backup
, handle
);
1638 raid_obj_get_lib(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
1640 raid_obj_handle_t handle
;
1641 controller_attr_t
*attr
;
1643 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
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
;
1656 return (raid_handle_sys
.handles
[handle
].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
)
1663 raid_obj_handle_t handle
;
1664 controller_attr_t
*attr
;
1666 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
1667 return (ERR_DEVICE_TYPE
);
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
;
1677 return (ERR_DEVICE_NOENT
);
1679 raid_handle_sys
.handles
[handle
].raid_lib
= raid_lib
;
1684 raid_obj_get_fd(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
1686 raid_obj_handle_t handle
;
1687 controller_attr_t
*attr
;
1689 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
1690 return (ERR_DEVICE_TYPE
);
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
;
1700 return (ERR_DEVICE_NOENT
);
1702 return (raid_handle_sys
.handles
[handle
].fd
);
1706 raid_obj_set_fd(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
, int fd
)
1708 raid_obj_handle_t handle
;
1709 controller_attr_t
*attr
;
1711 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
1712 return (ERR_DEVICE_TYPE
);
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
;
1722 return (ERR_DEVICE_NOENT
);
1724 raid_handle_sys
.handles
[handle
].fd
= fd
;
1729 * Raid object maintenance routines
1732 obj_scan_comp(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
1739 status
= raid_obj_get_status(raid_tab
, obj_id
);
1740 if (status
< SUCCESS
)
1743 if (status
& OBJ_STATUS_SCANCOMP
)
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
);
1751 for (obj_type_cnt
= OBJ_SYSTEM
; obj_type_cnt
< OBJ_TYPE_ALL
;
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
);
1759 if (comp_num
< SUCCESS
)
1764 comp_list
= calloc(comp_num
, sizeof (raid_obj_id_t
));
1765 if (comp_list
== NULL
)
1768 for (i
= 0; i
< comp_num
; ++i
) {
1769 *(comp_list
+ i
) = raid_obj_create(raid_tab
,
1771 if (*(comp_list
+ i
) < SUCCESS
) {
1772 ret
= *(comp_list
+ i
);
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
),
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
);
1789 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_SCANCOMP
);
1794 obj_rescan(raid_obj_tab_t
*raid_tab
)
1798 raid_obj_tab_destroy(raid_tab
);
1800 if (raid_obj_tab_create(raid_tab
, HASH_SLOTS
) != SUCCESS
)
1803 if ((ret
= raid_obj_create_system_obj(raid_tab
)) != SUCCESS
) {
1804 raid_obj_tab_destroy(raid_tab
);
1811 static raid_obj_id_t
1812 obj_get_comp(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
1813 raid_obj_type_id_t obj_type
)
1816 raid_obj_type_id_t type
;
1817 raid_obj_status_t status
;
1820 if ((obj_type
< OBJ_TYPE_SYSTEM
) || (obj_type
> OBJ_TYPE_ALL
))
1821 return (ERR_DEVICE_TYPE
);
1823 status
= raid_obj_get_status(raid_tab
, obj_id
);
1824 if (status
< SUCCESS
)
1827 if (!(status
& OBJ_STATUS_SCANCOMP
)) {
1828 ret
= obj_scan_comp(raid_tab
, obj_id
);
1833 id
= raid_obj_get_comp(raid_tab
, obj_id
);
1837 type
= raid_obj_get_type(raid_tab
, id
);
1838 if (type
< OBJ_TYPE_SYSTEM
)
1841 if (type
== obj_type
)
1844 while (id
> OBJ_NONE
) {
1845 id
= raid_obj_get_sibling(raid_tab
, id
);
1849 type
= raid_obj_get_type(raid_tab
, id
);
1850 if (type
< OBJ_TYPE_SYSTEM
)
1853 if (type
== obj_type
)
1860 static raid_obj_id_t
1861 obj_get_sibling(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
1864 raid_obj_type_id_t type
, obj_type
;
1867 obj_type
= raid_obj_get_type(raid_tab
, id
);
1868 if (obj_type
< OBJ_TYPE_SYSTEM
)
1872 id
= raid_obj_get_sibling(raid_tab
, id
);
1876 type
= raid_obj_get_type(raid_tab
, id
);
1877 if (type
< OBJ_TYPE_SYSTEM
)
1879 } while ((type
!= obj_type
) && (id
!= OBJ_NONE
));
1885 obj_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
, void **data
)
1887 raid_obj_type_id_t type
;
1888 raid_obj_status_t status
;
1892 status
= raid_obj_get_status(raid_tab
, obj_id
);
1893 if (status
< SUCCESS
)
1896 type
= raid_obj_get_type(raid_tab
, obj_id
);
1897 if (type
< OBJ_TYPE_SYSTEM
)
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
,
1905 ret
= raid_obj_op_sys
[type
].get_attr(raid_tab
, obj_id
);
1910 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
1911 if (attr
== NULL
&& type
!= OBJ_TYPE_SYSTEM
)
1912 return (ERR_DEVICE_INVALID
);
1918 static raid_obj_id_t
1919 obj_locate_controller(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
)
1921 raid_obj_id_t obj_id
;
1922 controller_attr_t
*attr
;
1924 obj_id
= obj_get_comp(raid_tab
, OBJ_SYSTEM
, OBJ_TYPE_CONTROLLER
);
1925 if (obj_id
<= OBJ_NONE
)
1929 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
1931 return (ERR_DEVICE_INVALID
);
1933 if (attr
->controller_id
== controller_id
)
1935 } while ((obj_id
= obj_get_sibling(raid_tab
, obj_id
)) != OBJ_NONE
);
1940 static raid_obj_id_t
1941 obj_locate_array(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
1944 raid_obj_id_t obj_id
;
1946 obj_id
= obj_locate_controller(raid_tab
, controller_id
);
1947 if (obj_id
< OBJ_NONE
)
1950 obj_id
= obj_locate_array_recur(raid_tab
, obj_id
, array_id
);
1955 static raid_obj_id_t
1956 obj_locate_array_recur(raid_obj_tab_t
*raid_tab
,
1957 raid_obj_id_t container_obj_id
, uint32_t array_id
)
1959 raid_obj_id_t obj_id
, ret
;
1962 obj_id
= obj_get_comp(raid_tab
, container_obj_id
, OBJ_TYPE_ARRAY
);
1963 if (obj_id
<= OBJ_NONE
)
1967 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
1969 return (ERR_DEVICE_INVALID
);
1971 if (attr
->array_id
== array_id
)
1974 ret
= obj_locate_array_recur(raid_tab
, obj_id
, array_id
);
1975 if (ret
!= OBJ_NONE
)
1978 } while ((obj_id
= obj_get_sibling(raid_tab
, obj_id
)) > OBJ_NONE
);
1983 static raid_obj_id_t
1984 obj_locate_hsp(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
1985 uint32_t disk_id
, uint32_t array_id
)
1987 raid_obj_id_t obj_id
;
1988 hsp_attr_t
*hsp_attr
;
1990 obj_id
= obj_locate_disk(raid_tab
, controller_id
, disk_id
);
1991 if (obj_id
<= OBJ_NONE
)
1994 obj_id
= obj_get_comp(raid_tab
, obj_id
, OBJ_TYPE_HSP
);
1995 if (obj_id
<= OBJ_NONE
)
1999 (void) obj_get_attr(raid_tab
, obj_id
, (void **)(&hsp_attr
));
2000 if (hsp_attr
->associated_id
== array_id
)
2003 obj_id
= obj_get_sibling(raid_tab
, obj_id
);
2004 if (obj_id
< OBJ_NONE
)
2006 } while (obj_id
> OBJ_NONE
);
2011 static raid_obj_id_t
2012 obj_locate_disk(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
2015 raid_obj_id_t obj_id
;
2018 obj_id
= obj_locate_controller(raid_tab
, controller_id
);
2019 if (obj_id
<= OBJ_NONE
)
2022 obj_id
= obj_get_comp(raid_tab
, obj_id
, OBJ_TYPE_DISK
);
2023 if (obj_id
<= OBJ_NONE
)
2027 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2029 return (ERR_DEVICE_INVALID
);
2031 if (attr
->disk_id
== disk_id
)
2033 } while ((obj_id
= obj_get_sibling(raid_tab
, obj_id
)) > OBJ_NONE
);
2038 static raid_obj_id_t
2039 obj_locate_arraypart(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
2040 uint32_t array_id
, uint32_t disk_id
)
2042 raid_obj_id_t obj_id
;
2044 arraypart_attr_t
*attr
;
2046 obj_id
= obj_locate_array(raid_tab
, controller_id
, array_id
);
2047 if (obj_id
<= OBJ_NONE
)
2050 obj_id
= obj_get_comp(raid_tab
, obj_id
, OBJ_TYPE_ARRAY_PART
);
2051 if (obj_id
<= OBJ_NONE
)
2055 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2057 return (ERR_DEVICE_INVALID
);
2059 if (attr
->disk_id
== disk_id
)
2061 } while ((obj_id
= obj_get_sibling(raid_tab
, obj_id
)) >
2067 static raid_obj_id_t
2068 obj_locate_diskseg(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
2069 uint32_t disk_id
, uint32_t seq_no
)
2071 raid_obj_id_t obj_id
;
2072 diskseg_attr_t
*attr
;
2074 obj_id
= obj_locate_disk(raid_tab
, controller_id
, disk_id
);
2075 if (obj_id
<= OBJ_NONE
)
2078 obj_id
= obj_get_comp(raid_tab
, obj_id
, OBJ_TYPE_DISK_SEG
);
2079 if (obj_id
<= OBJ_NONE
)
2083 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2085 return (ERR_DEVICE_INVALID
);
2087 if (attr
->seq_no
== seq_no
)
2089 } while ((obj_id
= obj_get_sibling(raid_tab
, obj_id
)) > OBJ_NONE
);
2094 static raid_obj_id_t
2095 obj_locate_task(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
2098 raid_obj_id_t obj_id
, obj_id2
, task_obj_id
;
2101 obj_id
= obj_locate_controller(raid_tab
, controller_id
);
2102 if (obj_id
<= OBJ_NONE
)
2105 obj_id
= obj_get_comp(raid_tab
, obj_id
, OBJ_TYPE_ARRAY
);
2106 if (obj_id
< OBJ_NONE
)
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
,
2115 if (task_obj_id
< OBJ_NONE
)
2116 return (task_obj_id
);
2118 if (task_obj_id
== OBJ_NONE
) {
2119 obj_id2
= obj_get_sibling(raid_tab
, obj_id2
);
2123 attr
= raid_obj_get_data_ptr(raid_tab
, task_obj_id
);
2125 return (ERR_DEVICE_INVALID
);
2127 if (attr
->task_id
== task_id
)
2128 return (task_obj_id
);
2130 obj_id2
= obj_get_sibling(raid_tab
, obj_id2
);
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
);
2137 if (task_obj_id
== OBJ_NONE
)
2140 attr
= raid_obj_get_data_ptr(raid_tab
, task_obj_id
);
2142 return (ERR_DEVICE_INVALID
);
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
);
2148 if (obj_id
< OBJ_NONE
)
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
)
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
);
2161 if (task_obj_id
== OBJ_NONE
)
2164 attr
= raid_obj_get_data_ptr(raid_tab
, task_obj_id
);
2166 return (ERR_DEVICE_INVALID
);
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
);
2175 static raid_obj_id_t
2176 obj_locate_prop(raid_obj_tab_t
*raid_tab
, uint32_t controller_id
,
2177 uint32_t disk_id
, uint32_t prop_id
)
2179 raid_obj_id_t obj_id
;
2180 property_attr_t
*prop_attr
;
2182 obj_id
= obj_locate_disk(raid_tab
, controller_id
, disk_id
);
2183 if (obj_id
< OBJ_NONE
)
2186 obj_id
= obj_get_comp(raid_tab
, obj_id
, OBJ_TYPE_PROP
);
2187 if (obj_id
<= OBJ_NONE
)
2191 (void) obj_get_attr(raid_tab
, obj_id
, (void **)(&prop_attr
));
2192 if (prop_attr
->prop_id
== prop_id
)
2195 obj_id
= obj_get_sibling(raid_tab
, obj_id
);
2196 if (obj_id
< OBJ_NONE
)
2198 } while (obj_id
> OBJ_NONE
);
2203 static raid_obj_id_t
2204 obj_get_controller(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
2206 raid_obj_id_t id
= obj_id
;
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
);
2218 * Raid object operation routines
2221 obj_sys_compnum(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
2222 raid_obj_type_id_t comp_type
)
2228 if ((raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_SYSTEM
))
2229 return (ERR_DEVICE_TYPE
);
2231 if (comp_type
!= OBJ_TYPE_CONTROLLER
)
2234 if ((dir
= opendir(CFGDIR
)) == NULL
)
2235 return (ERR_DRIVER_NOT_FOUND
);
2237 while ((dp
= readdir(dir
)) != NULL
) {
2238 uint32_t controller_id
;
2239 char path
[MAX_PATH_LEN
];
2241 if (strcmp(dp
->d_name
, ".") == 0 ||
2242 strcmp(dp
->d_name
, "..") == 0)
2245 if (sscanf(dp
->d_name
, "c%u", &controller_id
) != 1)
2248 if (controller_id_to_path(controller_id
, path
) == SUCCESS
)
2252 (void) closedir(dir
);
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
)
2262 controller_attr_t
*attr
;
2263 uint32_t controller_id
;
2265 char path
[MAX_PATH_LEN
];
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
);
2273 if (comp_type
!= OBJ_TYPE_CONTROLLER
)
2276 if ((dir
= opendir(CFGDIR
)) == NULL
)
2277 return (ERR_DRIVER_NOT_FOUND
);
2278 tmplist
= calloc(num
, sizeof (uint32_t));
2279 if (tmplist
== NULL
) {
2282 while ((dp
= readdir(dir
)) != NULL
) {
2283 if (strcmp(dp
->d_name
, ".") == 0 ||
2284 strcmp(dp
->d_name
, "..") == 0)
2287 if (sscanf(dp
->d_name
, "c%u", &controller_id
) != 1)
2290 if (controller_id_to_path(controller_id
, path
) == SUCCESS
) {
2291 tmplist
[i
] = controller_id
;
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
,
2302 return (ERR_DEVICE_INVALID
);
2305 attr
->controller_id
= tmplist
[i
];
2308 (void) closedir(dir
);
2313 obj_controller_compnum(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
2314 raid_obj_type_id_t comp_type
)
2316 raid_lib_t
*raid_lib
;
2317 int ret
= SUCCESS
, fd
;
2318 controller_attr_t
*ctl_attrp
;
2320 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
2321 return (ERR_DEVICE_TYPE
);
2323 if ((comp_type
!= OBJ_TYPE_ARRAY
) && (comp_type
!= OBJ_TYPE_DISK
))
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
);
2332 ret
= raid_lib
->compnum(ctl_attrp
->controller_id
, 0,
2333 OBJ_TYPE_CONTROLLER
, 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
)
2342 raid_lib_t
*raid_lib
;
2343 controller_attr_t
*ctl_attrp
;
2347 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
2348 return (ERR_DEVICE_TYPE
);
2350 if ((comp_type
!= OBJ_TYPE_ARRAY
) && (comp_type
!= OBJ_TYPE_DISK
))
2353 if ((comp_num
<= 0) || (comp_list
== NULL
))
2354 return (ERR_OP_ILLEGAL
);
2356 for (i
= 0; i
< comp_num
; ++i
)
2357 if (raid_obj_get_type(raid_tab
, *(comp_list
+ i
)) !=
2359 return (ERR_DEVICE_TYPE
);
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
);
2367 ids
= malloc(comp_num
* sizeof (uint32_t));
2371 ret
= raid_lib
->complist(ctl_attrp
->controller_id
, 0,
2372 OBJ_TYPE_CONTROLLER
, comp_type
, comp_num
, ids
);
2373 if (ret
< SUCCESS
) {
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
;
2383 attr_buf
= raid_obj_get_data_ptr(raid_tab
, *(comp_list
+ i
));
2384 if (attr_buf
== NULL
) {
2386 return (ERR_DEVICE_INVALID
);
2389 switch (comp_type
) {
2390 case OBJ_TYPE_ARRAY
:
2391 array_attr
= attr_buf
;
2392 array_attr
->array_id
= *(ids
+ i
);
2395 disk_attr
= attr_buf
;
2396 disk_attr
->disk_id
= *(ids
+ i
);
2400 return (ERR_DEVICE_INVALID
);
2409 obj_controller_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
2411 controller_attr_t
*attr
;
2412 raid_lib_t
*raid_lib
;
2413 int ret
= SUCCESS
, fd
;
2415 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
2416 return (ERR_DEVICE_TYPE
);
2418 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
2421 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2423 return (ERR_DEVICE_INVALID
);
2425 raid_lib
= raid_obj_get_lib(raid_tab
, obj_id
);
2426 fd
= raid_obj_get_fd(raid_tab
, obj_id
);
2429 * For a controller, even it's not opened, we can still
2430 * get the driver name
2436 if (raid_lib
== NULL
) {
2440 ret
= raid_lib
->get_attr(attr
->controller_id
, OBJ_ATTR_NONE
,
2441 OBJ_ATTR_NONE
, OBJ_TYPE_CONTROLLER
, attr
);
2445 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_OPENED
);
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
)
2454 controller_attr_t
*attr
;
2455 raid_lib_t
*raid_lib
;
2458 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_CONTROLLER
)
2459 return (ERR_DEVICE_TYPE
);
2461 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2463 raid_lib
= raid_obj_get_lib(raid_tab
, obj_id
);
2464 fd
= raid_obj_get_fd(raid_tab
, obj_id
);
2467 case ACT_CONTROLLER_OPEN
:
2468 /* Check if already opened */
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
);
2480 ret
= raid_lib
->open_controller(attr
->controller_id
,
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);
2487 case ACT_CONTROLLER_CLOSE
:
2492 if (raid_lib
== NULL
) {
2495 ret
= raid_lib
->close_controller(attr
->controller_id
,
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
);
2503 case ACT_CONTROLLER_FLASH_FW
:
2508 struct stat statbuf
;
2510 if (prop_list
== NULL
)
2511 return (ERR_OP_ILLEGAL
);
2513 /* Open firmware image file */
2514 image_fd
= open((const char *)prop_list
,
2515 O_RDONLY
| O_NDELAY
);
2517 return (ERR_OP_FAILED
);
2519 if (fstat(image_fd
, &statbuf
) != 0) {
2520 (void) close(image_fd
);
2521 return (ERR_OP_FAILED
);
2524 filebuf
= malloc(statbuf
.st_size
);
2525 if (filebuf
== NULL
) {
2526 (void) close(image_fd
);
2530 size
= read(image_fd
, filebuf
, statbuf
.st_size
);
2531 if (size
!= statbuf
.st_size
) {
2532 (void) close(image_fd
);
2534 return (ERR_OP_FAILED
);
2538 (void) close(image_fd
);
2540 return (ERR_DRIVER_CLOSED
);
2543 if (raid_lib
== NULL
) {
2544 (void) close(image_fd
);
2546 return (ERR_DRIVER_CLOSED
);
2548 if (raid_lib
->flash_fw
== NULL
) {
2549 (void) close(image_fd
);
2551 return (ERR_OP_NO_IMPL
);
2554 ret
= raid_lib
->flash_fw(attr
->controller_id
,
2555 filebuf
, size
, plugin_err_str
);
2559 return (ERR_OP_ILLEGAL
);
2566 obj_array_compnum(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
2567 raid_obj_type_id_t comp_type
)
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
;
2575 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_ARRAY
)
2576 return (ERR_DEVICE_TYPE
);
2578 if (comp_type
!= OBJ_TYPE_ARRAY_PART
&&
2579 comp_type
!= OBJ_TYPE_ARRAY
&&
2580 comp_type
!= OBJ_TYPE_TASK
)
2583 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2585 return (ERR_DEVICE_INVALID
);
2587 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2588 if (controller_obj_id
< OBJ_NONE
)
2589 return (ERR_DEVICE_INVALID
);
2591 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2592 if (ctl_attrp
== NULL
) {
2593 return (ERR_DEVICE_INVALID
);
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
);
2601 ret
= raid_lib
->compnum(ctl_attrp
->controller_id
, attr
->array_id
,
2602 OBJ_TYPE_ARRAY
, 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
)
2612 controller_attr_t
*ctl_attrp
;
2613 raid_obj_id_t controller_obj_id
;
2614 raid_lib_t
*raid_lib
;
2618 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_ARRAY
)
2619 return (ERR_DEVICE_TYPE
);
2621 if (comp_type
!= OBJ_TYPE_ARRAY_PART
&&
2622 comp_type
!= OBJ_TYPE_ARRAY
&&
2623 comp_type
!= OBJ_TYPE_TASK
)
2626 if (comp_num
<= 0 || comp_list
== NULL
)
2627 return (ERR_OP_ILLEGAL
);
2629 for (i
= 0; i
< comp_num
; ++i
)
2630 if (raid_obj_get_type(raid_tab
, *(comp_list
+ i
)) !=
2632 return (ERR_DEVICE_TYPE
);
2634 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2636 return (ERR_DEVICE_INVALID
);
2638 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2639 if (controller_obj_id
< OBJ_NONE
)
2640 return (ERR_DEVICE_INVALID
);
2642 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2643 if (ctl_attrp
== NULL
) {
2644 return (ERR_DEVICE_INVALID
);
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
);
2652 ids
= malloc(comp_num
* sizeof (uint32_t));
2656 ret
= raid_lib
->complist(ctl_attrp
->controller_id
,
2657 attr
->array_id
, OBJ_TYPE_ARRAY
, comp_type
, comp_num
, ids
);
2659 if (ret
< SUCCESS
) {
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
;
2670 attr_buf
= raid_obj_get_data_ptr(raid_tab
, *(comp_list
+ i
));
2671 if (attr_buf
== NULL
) {
2673 return (ERR_DEVICE_INVALID
);
2676 switch (comp_type
) {
2677 case OBJ_TYPE_ARRAY
:
2678 array_attr
= attr_buf
;
2679 array_attr
->array_id
= *(ids
+ i
);
2681 case OBJ_TYPE_ARRAY_PART
:
2682 arraypart_attr
= attr_buf
;
2683 arraypart_attr
->disk_id
= *(ids
+ i
);
2686 task_attr
= attr_buf
;
2687 task_attr
->task_id
= *(ids
+ i
);
2691 return (ERR_DEVICE_INVALID
);
2701 obj_array_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
2709 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_ARRAY
)
2710 return (ERR_DEVICE_TYPE
);
2712 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
2715 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2717 return (ERR_DEVICE_INVALID
);
2719 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2720 if (controller_obj_id
< OBJ_NONE
)
2721 return (ERR_DEVICE_INVALID
);
2723 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2724 if (ctl_attrp
== NULL
) {
2725 return (ERR_DEVICE_INVALID
);
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
);
2733 ret
= raid_lib
->get_attr(ctl_attrp
->controller_id
,
2734 attr
->array_id
, 0, OBJ_TYPE_ARRAY
, attr
);
2739 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_OPENED
);
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
)
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
;
2754 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_ARRAY
)
2755 return (ERR_DEVICE_TYPE
);
2758 case SET_CACHE_WR_PLY
:
2759 if (*value
!= CACHE_WR_OFF
&&
2760 *value
!= CACHE_WR_ON
)
2761 return (ERR_OP_ILLEGAL
);
2763 case SET_CACHE_RD_PLY
:
2764 if (*value
!= CACHE_RD_OFF
&&
2765 *value
!= CACHE_RD_ON
)
2766 return (ERR_OP_ILLEGAL
);
2768 case SET_ACTIVATION_PLY
:
2769 if (*value
!= ARRAY_ACT_ACTIVATE
)
2770 return (ERR_OP_ILLEGAL
);
2773 return (ERR_OP_ILLEGAL
);
2776 (void) obj_get_attr(raid_tab
, obj_id
, (void **)(&attr
));
2778 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2779 if (controller_obj_id
< OBJ_NONE
)
2780 return (ERR_DEVICE_INVALID
);
2782 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2783 if (ctl_attrp
== NULL
) {
2784 return (ERR_DEVICE_INVALID
);
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
);
2792 if (raid_lib
->set_attr
== NULL
)
2793 return (ERR_OP_NO_IMPL
);
2795 ret
= raid_lib
->set_attr(ctl_attrp
->controller_id
,
2796 attr
->array_id
, sub_cmd
, value
, plugin_err_str
);
2802 obj_disk_compnum(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
2803 raid_obj_type_id_t comp_type
)
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
;
2811 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_DISK
)
2812 return (ERR_DEVICE_TYPE
);
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
)
2819 ret
= obj_get_attr(raid_tab
, obj_id
, (void **)(&attr
));
2820 if ((ret
!= SUCCESS
) || (attr
== NULL
)) {
2821 return (ERR_DEVICE_INVALID
);
2823 if (attr
->state
== DISK_STATE_FAILED
) {
2827 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2828 if (controller_obj_id
< OBJ_NONE
)
2829 return (ERR_DEVICE_INVALID
);
2831 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2832 if (ctl_attrp
== NULL
) {
2833 return (ERR_DEVICE_INVALID
);
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
);
2841 ret
= raid_lib
->compnum(ctl_attrp
->controller_id
,
2842 attr
->disk_id
, OBJ_TYPE_DISK
, 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
)
2852 controller_attr_t
*ctl_attrp
;
2853 raid_obj_id_t controller_obj_id
;
2854 raid_lib_t
*raid_lib
;
2858 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_DISK
)
2859 return (ERR_DEVICE_TYPE
);
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
)
2867 if (comp_num
<= 0 || comp_list
== NULL
)
2868 return (ERR_OP_ILLEGAL
);
2870 for (i
= 0; i
< comp_num
; ++i
)
2871 if (raid_obj_get_type(raid_tab
, *(comp_list
+ i
)) !=
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
);
2878 if (attr
->state
== DISK_STATE_FAILED
) {
2882 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2883 if (controller_obj_id
< OBJ_NONE
)
2884 return (ERR_DEVICE_INVALID
);
2886 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2887 if (ctl_attrp
== NULL
) {
2888 return (ERR_DEVICE_INVALID
);
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
);
2896 ids
= malloc(comp_num
* sizeof (uint32_t));
2900 ret
= raid_lib
->complist(ctl_attrp
->controller_id
,
2901 attr
->disk_id
, OBJ_TYPE_DISK
, comp_type
, comp_num
, ids
);
2903 if (ret
< SUCCESS
) {
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
;
2915 attr_buf
= raid_obj_get_data_ptr(raid_tab
, *(comp_list
+ i
));
2916 if (attr_buf
== NULL
) {
2918 return (ERR_DEVICE_INVALID
);
2921 switch (comp_type
) {
2922 case OBJ_TYPE_DISK_SEG
:
2923 diskseg_attr
= attr_buf
;
2924 diskseg_attr
->seq_no
= *(ids
+ i
);
2927 hsp_attr
= attr_buf
;
2928 hsp_attr
->associated_id
= *(ids
+ i
);
2931 task_attr
= attr_buf
;
2932 task_attr
->task_id
= *(ids
+ i
);
2935 prop_attr
= attr_buf
;
2936 prop_attr
->prop_id
= *(ids
+ i
);
2940 return (ERR_DEVICE_INVALID
);
2950 obj_disk_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
2958 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_DISK
)
2959 return (ERR_DEVICE_TYPE
);
2961 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
2964 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
2966 return (ERR_DEVICE_INVALID
);
2968 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
2969 if (controller_obj_id
< OBJ_NONE
)
2970 return (ERR_DEVICE_INVALID
);
2972 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
2973 if (ctl_attrp
== NULL
) {
2974 return (ERR_DEVICE_INVALID
);
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
);
2982 ret
= raid_lib
->get_attr(ctl_attrp
->controller_id
,
2983 attr
->disk_id
, 0, OBJ_TYPE_DISK
, attr
);
2988 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_OPENED
);
2994 obj_hsp_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
2998 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_HSP
)
2999 return (ERR_DEVICE_TYPE
);
3001 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
3004 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
3006 return (ERR_DEVICE_INVALID
);
3008 if (attr
->associated_id
== (uint32_t)OBJ_ATTR_NONE
)
3009 attr
->type
= HSP_TYPE_GLOBAL
;
3011 attr
->type
= HSP_TYPE_LOCAL
;
3017 obj_arraypart_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
3026 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_ARRAY_PART
)
3027 return (ERR_DEVICE_TYPE
);
3029 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
3032 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
3034 return (ERR_DEVICE_INVALID
);
3036 array_obj_id
= raid_obj_get_container(raid_tab
, obj_id
);
3037 if (array_obj_id
< OBJ_NONE
)
3038 return (ERR_DEVICE_INVALID
);
3040 array_attr
= raid_obj_get_data_ptr(raid_tab
, array_obj_id
);
3041 if (array_attr
== NULL
)
3042 return (ERR_DEVICE_INVALID
);
3044 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
3045 if (controller_obj_id
< OBJ_NONE
)
3046 return (ERR_DEVICE_INVALID
);
3048 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
3049 if (ctl_attrp
== NULL
) {
3050 return (ERR_DEVICE_INVALID
);
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
);
3058 ret
= raid_lib
->get_attr(ctl_attrp
->controller_id
,
3059 array_attr
->array_id
, attr
->disk_id
,
3060 OBJ_TYPE_ARRAY_PART
, attr
);
3065 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_OPENED
);
3071 obj_diskseg_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
3080 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_DISK_SEG
)
3081 return (ERR_DEVICE_TYPE
);
3083 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
3086 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
3088 return (ERR_DEVICE_INVALID
);
3090 disk_obj_id
= raid_obj_get_container(raid_tab
, obj_id
);
3091 if (disk_obj_id
< OBJ_NONE
)
3092 return (ERR_DEVICE_INVALID
);
3094 disk_attr
= raid_obj_get_data_ptr(raid_tab
, disk_obj_id
);
3095 if (disk_attr
== NULL
)
3096 return (ERR_DEVICE_INVALID
);
3098 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
3099 if (controller_obj_id
< OBJ_NONE
)
3100 return (ERR_DEVICE_INVALID
);
3102 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
3103 if (ctl_attrp
== NULL
) {
3104 return (ERR_DEVICE_INVALID
);
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
);
3112 ret
= raid_lib
->get_attr(ctl_attrp
->controller_id
,
3113 disk_attr
->disk_id
, attr
->seq_no
, OBJ_TYPE_DISK_SEG
, attr
);
3118 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_OPENED
);
3124 obj_task_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
3132 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_TASK
)
3133 return (ERR_DEVICE_TYPE
);
3135 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
3137 return (ERR_DEVICE_INVALID
);
3139 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
3140 if (controller_obj_id
< OBJ_NONE
)
3141 return (ERR_DEVICE_INVALID
);
3143 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
3144 if (ctl_attrp
== NULL
) {
3145 return (ERR_DEVICE_INVALID
);
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
);
3153 ret
= raid_lib
->get_attr(ctl_attrp
->controller_id
,
3154 attr
->task_id
, OBJ_ATTR_NONE
, OBJ_TYPE_TASK
, attr
);
3160 obj_prop_get_attr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
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
;
3169 if (raid_obj_get_type(raid_tab
, obj_id
) != OBJ_TYPE_PROP
)
3170 return (ERR_DEVICE_TYPE
);
3172 if (raid_obj_get_status(raid_tab
, obj_id
) & OBJ_STATUS_OPENED
)
3175 attr
= raid_obj_get_data_ptr(raid_tab
, obj_id
);
3177 return (ERR_DEVICE_INVALID
);
3179 disk_obj_id
= raid_obj_get_container(raid_tab
, obj_id
);
3180 if (disk_obj_id
< OBJ_NONE
)
3181 return (ERR_DEVICE_INVALID
);
3183 disk_attr
= raid_obj_get_data_ptr(raid_tab
, disk_obj_id
);
3184 if (disk_attr
== NULL
)
3185 return (ERR_DEVICE_INVALID
);
3187 controller_obj_id
= obj_get_controller(raid_tab
, obj_id
);
3188 if (controller_obj_id
< OBJ_NONE
)
3189 return (ERR_DEVICE_INVALID
);
3191 ctl_attrp
= raid_obj_get_data_ptr(raid_tab
, controller_obj_id
);
3192 if (ctl_attrp
== NULL
) {
3193 return (ERR_DEVICE_INVALID
);
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
);
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
);
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
)
3214 (void) raid_obj_set_data_ptr(raid_tab
, obj_id
, attr_new
);
3216 ret
= raid_lib
->get_attr(ctl_attrp
->controller_id
,
3217 disk_attr
->disk_id
, OBJ_ATTR_NONE
, OBJ_TYPE_PROP
, attr_new
);
3222 (void) raid_obj_set_status(raid_tab
, obj_id
, OBJ_STATUS_OPENED
);
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
)
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
;
3238 int disk_cnt
= 0, disk_set_num
= 0, set_num
= 0, layer_cnt
= 0;
3239 uint64_t min_disk_capacity
= 0;
3241 array_attr
= raid_obj_get_data_ptr(raid_tab
, array_obj_id
);
3242 if (array_attr
== NULL
)
3243 return (ERR_DEVICE_INVALID
);
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
) {
3252 return (ERR_ARRAY_LAYOUT
);
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
);
3266 switch (array_attr
->raid_level
) {
3272 return (ERR_ARRAY_LAYOUT
);
3277 return (ERR_ARRAY_LAYOUT
);
3280 return (ERR_ARRAY_LEVEL
);
3286 return (ERR_ARRAY_LAYOUT
);
3288 switch (array_attr
->raid_level
) {
3290 if (disk_set_num
< 2 || set_num
!= 1)
3291 return (ERR_ARRAY_LAYOUT
);
3294 if (disk_set_num
!= 2 || set_num
!= 1)
3295 return (ERR_ARRAY_LAYOUT
);
3299 if (disk_set_num
< 3 || set_num
!= 1)
3300 return (ERR_ARRAY_LAYOUT
);
3303 if (disk_set_num
!= 2 || set_num
< 2)
3304 return (ERR_ARRAY_LAYOUT
);
3307 if (disk_set_num
< 3 || set_num
< 2)
3308 return (ERR_ARRAY_LAYOUT
);
3311 return (ERR_ARRAY_LEVEL
);
3314 arraypart_attrs
= calloc(num_of_comp
, sizeof (arraypart_attr_t
));
3315 if (arraypart_attrs
== NULL
)
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
;
3326 if (*(disk_list
+ i
) == OBJ_SEPARATOR_END
) {
3327 arraypart_attrs
[i
].disk_id
=
3328 (uint32_t)OBJ_SEPARATOR_END
;
3333 /* Check if it's a disk */
3334 if (raid_obj_get_type(raid_tab
, *(disk_list
+ i
)) !=
3336 return (ERR_DEVICE_TYPE
);
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
);
3345 /* Check disk status */
3346 ret
= obj_get_attr(raid_tab
, *(disk_list
+ i
),
3347 (void **)(&disk_attr
));
3351 if (disk_attr
->state
!= DISK_STATE_GOOD
) {
3352 free(arraypart_attrs
);
3353 return (ERR_DISK_STATE
);
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
)
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
);
3369 /* Check if the disk contains too many segments */
3370 obj_id
= obj_get_comp(raid_tab
, *(disk_list
+ i
),
3373 while (obj_id
> OBJ_NONE
) {
3375 obj_id
= obj_get_sibling(raid_tab
, obj_id
);
3377 if (j
> controller_attr
->max_seg_per_disk
) {
3378 free(arraypart_attrs
);
3379 return (ERR_DISK_SEG_AMOUNT
);
3382 /* Check if controller is a hostraid controller */
3383 if (controller_attr
->capability
& RAID_CAP_DISK_TRANS
) {
3385 * For hostraid, the first disk should
3386 * be with of minimum capacity
3388 if (min_disk_capacity
== 0) {
3389 min_disk_capacity
= disk_attr
->capacity
;
3391 /* Can not specify capacity for hostraid */
3392 if (array_attr
->capacity
!= 0) {
3393 free(arraypart_attrs
);
3394 return (ERR_OP_ILLEGAL
);
3396 } else if (min_disk_capacity
> disk_attr
->capacity
) {
3397 free(arraypart_attrs
);
3398 return (ERR_DISK_SPACE
);
3401 /* Disk should not be used for hostraid */
3402 obj_id
= obj_get_comp(raid_tab
, *(disk_list
+ i
),
3404 if (obj_id
< OBJ_NONE
) {
3405 free(arraypart_attrs
);
3407 } else if (obj_id
> OBJ_NONE
) {
3408 free(arraypart_attrs
);
3409 return (ERR_DISK_NOT_EMPTY
);
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
;
3418 /* Check if array amount exceeds limit */
3419 if (controller_attr
->max_array_num
<=
3420 obj_controller_compnum(raid_tab
, controller_obj_id
,
3422 return (ERR_ARRAY_AMOUNT
);
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
);
3430 /* Check if the controller can support the array RAID level */
3431 switch (array_attr
->raid_level
) {
3433 if (!(controller_attr
->capability
& RAID_CAP_RAID0
)) {
3434 free(arraypart_attrs
);
3435 return (ERR_ARRAY_LEVEL
);
3439 if (!(controller_attr
->capability
& RAID_CAP_RAID1
)) {
3440 free(arraypart_attrs
);
3441 return (ERR_ARRAY_LEVEL
);
3445 if (!(controller_attr
->capability
& RAID_CAP_RAID1E
)) {
3446 free(arraypart_attrs
);
3447 return (ERR_ARRAY_LEVEL
);
3451 if (!(controller_attr
->capability
& RAID_CAP_RAID5
)) {
3452 free(arraypart_attrs
);
3453 return (ERR_ARRAY_LEVEL
);
3457 if (!(controller_attr
->capability
& RAID_CAP_RAID10
)) {
3458 free(arraypart_attrs
);
3459 return (ERR_ARRAY_LEVEL
);
3463 if (!(controller_attr
->capability
& RAID_CAP_RAID50
)) {
3464 free(arraypart_attrs
);
3465 return (ERR_ARRAY_LEVEL
);
3469 free(arraypart_attrs
);
3470 return (ERR_ARRAY_LEVEL
);
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
);
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
,
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
3491 if (controller_attr
->capability
& RAID_CAP_SMART_ALLOC
)
3492 for (i
= 0; i
< num_of_comp
; ++i
) {
3493 arraypart_attrs
[i
].offset
=
3495 arraypart_attrs
[i
].size
=
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
);
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
);
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
);
3518 if (array_attr
->capacity
< ARRAYPART_MIN_SIZE
* disk_cnt
) {
3519 free(arraypart_attrs
);
3520 return (ERR_ARRAY_SIZE
);
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
);
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
);
3538 obj_array_delete(raid_obj_tab_t
*raid_tab
, raid_obj_id_t array_obj_id
,
3539 char **plugin_err_str
)
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
;
3546 uint32_t *disk_ids
= NULL
;
3548 controller_obj_id
= obj_get_controller(raid_tab
, array_obj_id
);
3549 if (controller_obj_id
<= OBJ_NONE
)
3550 return (controller_obj_id
);
3552 ret
= obj_get_attr(raid_tab
, controller_obj_id
,
3553 (void **)(&controller_attr
));
3554 if (ret
< SUCCESS
) {
3557 ret
= obj_get_attr(raid_tab
, array_obj_id
, (void **)(&array_attr
));
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
);
3566 ret
= raid_lib
->array_delete(controller_attr
->controller_id
,
3567 array_attr
->array_id
, plugin_err_str
);
3568 if (ret
< SUCCESS
) {
3578 obj_hsp_bind(raid_obj_tab_t
*raid_tab
, raid_obj_id_t
*obj_ids
,
3579 char **plugin_err_str
)
3581 raid_obj_id_t obj_id
, controller_obj_id
= OBJ_NONE
;
3582 raid_obj_id_t array_obj_id
, disk_obj_id
;
3583 hsp_relation_t
*hsp_relation
;
3584 controller_attr_t
*controller_attr
;
3585 array_attr_t
*array_attr
;
3586 arraypart_attr_t
*arraypart_attr
;
3587 disk_attr_t
*disk_attr
;
3588 diskseg_attr_t
*diskseg_attr
;
3589 hsp_attr_t
*hsp_attr
;
3590 raid_lib_t
*raid_lib
;
3593 hsp_relation
= malloc(sizeof (hsp_relation_t
));
3594 if (hsp_relation
== NULL
)
3597 array_obj_id
= *(obj_ids
);
3598 disk_obj_id
= *(obj_ids
+ 1);
3600 if (raid_obj_get_type(raid_tab
, disk_obj_id
) != OBJ_TYPE_DISK
||
3601 (array_obj_id
!= OBJ_ATTR_NONE
&&
3602 raid_obj_get_type(raid_tab
, array_obj_id
) !=
3605 return (ERR_DEVICE_TYPE
);
3608 /* Get controller attributes */
3609 if (controller_obj_id
== OBJ_NONE
)
3610 controller_obj_id
= obj_get_controller(raid_tab
,
3612 else if (controller_obj_id
!= obj_get_controller(raid_tab
,
3615 return (ERR_DRIVER_ACROSS
);
3618 ret
= obj_get_attr(raid_tab
, controller_obj_id
,
3619 (void **)(&controller_attr
));
3621 /* Get disk attributes */
3622 ret
= obj_get_attr(raid_tab
, disk_obj_id
,
3623 (void **)(&disk_attr
));
3624 if (disk_attr
->state
== DISK_STATE_FAILED
) {
3626 return (ERR_DISK_STATE
);
3629 /* If it's not a hsp disk, check if there's occupied space */
3630 if (obj_get_comp(raid_tab
, disk_obj_id
, OBJ_TYPE_HSP
) ==
3632 obj_id
= obj_get_comp(raid_tab
, disk_obj_id
,
3634 while (obj_id
!= OBJ_NONE
) {
3635 ret
= obj_get_attr(raid_tab
, obj_id
,
3636 (void **)(&diskseg_attr
));
3637 if (!(diskseg_attr
->state
&
3638 DISKSEG_STATE_RESERVED
)) {
3640 return (ERR_DISK_NOT_EMPTY
);
3642 obj_id
= obj_get_sibling(raid_tab
, obj_id
);
3646 if (array_obj_id
!= OBJ_ATTR_NONE
) {
3647 /* If local hsp is supported */
3648 if (!(controller_attr
->capability
& RAID_CAP_L_HSP
)) {
3650 return (ERR_OP_ILLEGAL
);
3653 if (raid_obj_get_type(raid_tab
, array_obj_id
) !=
3656 return (ERR_DEVICE_TYPE
);
3659 /* Get array attributes */
3660 ret
= obj_get_attr(raid_tab
, array_obj_id
,
3661 (void **)(&array_attr
));
3662 /* RAID 0 array can not use hsp */
3663 if (array_attr
->raid_level
== RAID_LEVEL_0
) {
3665 return (ERR_ARRAY_LEVEL
);
3668 /* If It's belong to another controller */
3669 if (controller_obj_id
!= obj_get_controller(raid_tab
,
3672 return (ERR_DRIVER_ACROSS
);
3675 /* Get an array part attributes */
3676 if ((array_attr
->raid_level
== RAID_LEVEL_10
) ||
3677 (array_attr
->raid_level
== RAID_LEVEL_50
))
3678 obj_id
= obj_get_comp(raid_tab
, array_obj_id
,
3681 obj_id
= array_obj_id
;
3682 obj_id
= obj_get_comp(raid_tab
, obj_id
,
3683 OBJ_TYPE_ARRAY_PART
);
3684 ret
= obj_get_attr(raid_tab
, obj_id
,
3685 (void **)(&arraypart_attr
));
3687 /* Check if disk space is enough for array */
3688 if (arraypart_attr
->size
> disk_attr
->capacity
) {
3690 return (ERR_DISK_SPACE
);
3692 if (controller_attr
->capability
& RAID_CAP_ARRAY_ALIGN
)
3693 if ((arraypart_attr
->size
+
3694 arraypart_attr
->offset
) >
3695 disk_attr
->capacity
) {
3697 return (ERR_DISK_SPACE
);
3699 } else if (!(controller_attr
->capability
& RAID_CAP_G_HSP
)) {
3700 /* if global hsp is supported */
3702 return (ERR_OP_ILLEGAL
);
3706 * If the array is already associated with the
3707 * local hsp, or it's a global hsp, ignore it
3709 obj_id
= obj_get_comp(raid_tab
, disk_obj_id
, OBJ_TYPE_HSP
);
3710 if (obj_id
> OBJ_NONE
) {
3711 if (obj_get_attr(raid_tab
, obj_id
,
3712 (void **)&hsp_attr
) >= SUCCESS
) {
3713 if (((hsp_attr
->type
== HSP_TYPE_GLOBAL
) &&
3714 (array_obj_id
!= OBJ_ATTR_NONE
)) ||
3715 ((hsp_attr
->type
== HSP_TYPE_LOCAL
) &&
3716 (array_obj_id
== OBJ_ATTR_NONE
))) {
3718 return (ERR_OP_ILLEGAL
);
3723 if (array_obj_id
!= OBJ_ATTR_NONE
)
3724 hsp_relation
->array_id
= array_attr
->array_id
;
3726 hsp_relation
->array_id
= (uint32_t)OBJ_ATTR_NONE
;
3727 hsp_relation
->disk_id
= disk_attr
->disk_id
;
3729 raid_lib
= raid_obj_get_lib(raid_tab
, controller_obj_id
);
3730 fd
= raid_obj_get_fd(raid_tab
, controller_obj_id
);
3731 if ((raid_lib
== NULL
) || (fd
== 0))
3732 return (ERR_DRIVER_CLOSED
);
3734 if (raid_lib
->hsp_bind
== NULL
) {
3736 return (ERR_OP_NO_IMPL
);
3739 ret
= raid_lib
->hsp_bind(controller_attr
->controller_id
,
3740 hsp_relation
, plugin_err_str
);
3747 obj_hsp_unbind(raid_obj_tab_t
*raid_tab
, raid_obj_id_t
*obj_ids
,
3748 char **plugin_err_str
)
3750 raid_obj_id_t obj_id
, controller_obj_id
= OBJ_NONE
;
3751 raid_obj_id_t array_obj_id
, disk_obj_id
;
3752 hsp_relation_t
*hsp_relation
;
3753 controller_attr_t
*controller_attr
;
3754 array_attr_t
*array_attr
;
3755 disk_attr_t
*disk_attr
;
3756 hsp_attr_t
*hsp_attr
;
3757 raid_lib_t
*raid_lib
;
3760 hsp_relation
= malloc(sizeof (hsp_relation_t
));
3761 if (hsp_relation
== NULL
)
3764 array_obj_id
= *(obj_ids
);
3765 disk_obj_id
= *(obj_ids
+ 1);
3767 if (raid_obj_get_type(raid_tab
, disk_obj_id
) != OBJ_TYPE_DISK
) {
3769 return (ERR_DEVICE_TYPE
);
3772 /* Get controller attributes */
3773 if (controller_obj_id
== OBJ_NONE
)
3774 controller_obj_id
= obj_get_controller(raid_tab
,
3776 else if (controller_obj_id
!= obj_get_controller(raid_tab
,
3779 return (ERR_DRIVER_ACROSS
);
3782 ret
= obj_get_attr(raid_tab
, controller_obj_id
,
3783 (void **)(&controller_attr
));
3785 /* Get disk attributes */
3786 ret
= obj_get_attr(raid_tab
, disk_obj_id
,
3787 (void **)(&disk_attr
));
3788 if (disk_attr
->state
== DISK_STATE_FAILED
) {
3790 return (ERR_DISK_STATE
);
3793 /* If it's not a hsp disk */
3794 obj_id
= obj_get_comp(raid_tab
, disk_obj_id
, OBJ_TYPE_HSP
);
3795 if (obj_id
== OBJ_NONE
) {
3797 return (ERR_DISK_STATE
);
3799 ret
= obj_get_attr(raid_tab
, obj_id
, (void **)(&hsp_attr
));
3801 if (array_obj_id
!= OBJ_ATTR_NONE
) {
3802 if (raid_obj_get_type(raid_tab
, array_obj_id
) !=
3805 return (ERR_DEVICE_TYPE
);
3808 /* Get array attributes */
3809 ret
= obj_get_attr(raid_tab
, array_obj_id
,
3810 (void **)(&array_attr
));
3812 /* If It's belong to another controller */
3813 if (controller_obj_id
!= obj_get_controller(raid_tab
,
3816 return (ERR_DRIVER_ACROSS
);
3819 /* If want to remove an array from a global hsp */
3820 if (hsp_attr
->type
== HSP_TYPE_GLOBAL
) {
3822 return (ERR_OP_ILLEGAL
);
3826 (void) obj_get_attr(raid_tab
, obj_id
,
3827 (void **)(&hsp_attr
));
3829 if (hsp_attr
->associated_id
==
3830 array_attr
->array_id
||
3831 hsp_attr
->type
== HSP_TYPE_GLOBAL
)
3834 obj_id
= obj_get_sibling(raid_tab
, obj_id
);
3835 } while (obj_id
> OBJ_NONE
);
3836 } else if (hsp_attr
->type
!= HSP_TYPE_GLOBAL
) {
3837 /* if global hsp is supported */
3839 return (ERR_OP_ILLEGAL
);
3843 * If array is associated with a local hsp, or remove a
3846 if ((obj_id
&& (array_obj_id
!= OBJ_ATTR_NONE
)) ||
3847 (array_obj_id
== OBJ_ATTR_NONE
)) {
3848 if (array_obj_id
!= OBJ_ATTR_NONE
)
3849 hsp_relation
->array_id
= array_attr
->array_id
;
3851 hsp_relation
->array_id
=
3852 (uint32_t)OBJ_ATTR_NONE
;
3853 hsp_relation
->disk_id
= disk_attr
->disk_id
;
3856 return (ERR_OP_ILLEGAL
);
3859 raid_lib
= raid_obj_get_lib(raid_tab
, controller_obj_id
);
3860 fd
= raid_obj_get_fd(raid_tab
, controller_obj_id
);
3861 if ((raid_lib
== NULL
) || (fd
== 0))
3862 return (ERR_DRIVER_CLOSED
);
3864 if (raid_lib
->hsp_unbind
== NULL
) {
3866 return (ERR_OP_NO_IMPL
);
3869 ret
= raid_lib
->hsp_unbind(controller_attr
->controller_id
,
3870 hsp_relation
, plugin_err_str
);
3877 * Object maintennance routines
3880 raid_obj_create_system_obj(raid_obj_tab_t
*raid_tab
)
3882 raid_obj_t
*raid_obj
;
3885 raid_obj
= calloc(1, sizeof (raid_obj_t
));
3886 if (raid_obj
== NULL
)
3889 raid_obj
->obj_id
= OBJ_SYSTEM
;
3890 raid_obj
->obj_type_id
= OBJ_TYPE_SYSTEM
;
3891 raid_obj
->data
= NULL
;
3893 ret
= raid_obj_tab_insert(raid_tab
, raid_obj
->obj_id
, raid_obj
);
3894 if (ret
== ERR_DEVICE_DUP
) {
3896 return (ERR_DEVICE_UNCLEAN
);
3902 static raid_obj_id_t
3903 raid_obj_id_new(raid_obj_tab_t
*raid_tab
)
3905 ++ raid_tab
->obj_id_cnt
;
3906 if (raid_tab
->obj_id_cnt
<= 0)
3907 return (ERR_DEVICE_OVERFLOW
);
3909 return (raid_tab
->obj_id_cnt
);
3913 raid_obj_attr_new(raid_obj_type_id_t obj_type
)
3915 void *obj_attr
= NULL
;
3918 case OBJ_TYPE_CONTROLLER
:
3919 obj_attr
= calloc(1, sizeof (controller_attr_t
));
3921 case OBJ_TYPE_ARRAY
:
3922 obj_attr
= calloc(1, sizeof (array_attr_t
));
3925 obj_attr
= calloc(1, sizeof (disk_attr_t
));
3928 obj_attr
= calloc(1, sizeof (hsp_attr_t
));
3930 case OBJ_TYPE_ARRAY_PART
:
3931 obj_attr
= calloc(1, sizeof (arraypart_attr_t
));
3933 case OBJ_TYPE_DISK_SEG
:
3934 obj_attr
= calloc(1, sizeof (diskseg_attr_t
));
3937 obj_attr
= calloc(1, sizeof (task_attr_t
));
3940 obj_attr
= calloc(1, sizeof (property_attr_t
));
3949 static raid_obj_id_t
3950 raid_obj_create(raid_obj_tab_t
*raid_tab
, raid_obj_type_id_t obj_type
)
3952 raid_obj_t
*raid_obj
;
3956 raid_obj
= calloc(1, sizeof (raid_obj_t
));
3957 if (raid_obj
== NULL
)
3960 raid_obj
->obj_id
= raid_obj_id_new(raid_tab
);
3961 if (raid_obj
->obj_id
< OBJ_NONE
)
3962 return (ERR_DEVICE_OVERFLOW
);
3964 ret
= raid_obj_tab_insert(raid_tab
, raid_obj
->obj_id
, raid_obj
);
3965 if (ret
== ERR_DEVICE_DUP
) {
3967 return (ERR_DEVICE_DUP
);
3970 data_ptr
= raid_obj_attr_new(obj_type
);
3971 if (data_ptr
== NULL
) {
3972 (void) raid_obj_delete(raid_tab
, raid_obj
->obj_id
);
3976 (void) raid_obj_set_data_ptr(raid_tab
, raid_obj
->obj_id
, data_ptr
);
3978 (void) raid_obj_set_type(raid_tab
, raid_obj
->obj_id
, obj_type
);
3979 return (raid_obj
->obj_id
);
3983 raid_obj_delete(raid_obj_tab_t
*raid_tab
, raid_obj_id_t raid_obj_id
)
3987 obj
= raid_obj_tab_remove(raid_tab
, raid_obj_id
);
3994 return (ERR_DEVICE_NOENT
);
3998 raid_obj_add_org(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
3999 raid_obj_id_t container_id
)
4001 raid_obj_id_t tmp
, tmp1
;
4003 tmp
= raid_obj_get_comp(raid_tab
, container_id
);
4005 return (ERR_DEVICE_NOENT
);
4007 if (tmp
== OBJ_NONE
) {
4008 (void) raid_obj_set_container(raid_tab
, obj_id
, container_id
);
4009 (void) raid_obj_set_comp(raid_tab
, container_id
, obj_id
);
4013 while ((tmp1
= raid_obj_get_sibling(raid_tab
, tmp
)) != OBJ_NONE
)
4016 if (raid_obj_set_sibling(raid_tab
, tmp
, obj_id
) < SUCCESS
)
4017 return (ERR_DEVICE_NOENT
);
4018 (void) raid_obj_set_container(raid_tab
, obj_id
, container_id
);
4023 static raid_obj_type_id_t
4024 raid_obj_get_type(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4028 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4030 return (ERR_DEVICE_NOENT
);
4032 if ((obj
->obj_type_id
< OBJ_TYPE_SYSTEM
) ||
4033 (obj
->obj_type_id
>= OBJ_TYPE_ALL
))
4034 return (ERR_DEVICE_INVALID
);
4036 return (obj
->obj_type_id
);
4040 raid_obj_set_type(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4041 raid_obj_type_id_t type
)
4045 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4047 return (ERR_DEVICE_NOENT
);
4049 if ((type
< OBJ_TYPE_SYSTEM
) || (type
>= OBJ_TYPE_ALL
))
4050 return (ERR_DEVICE_TYPE
);
4052 obj
->obj_type_id
= type
;
4056 static raid_obj_status_t
4057 raid_obj_get_status(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4061 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4063 return (ERR_DEVICE_NOENT
);
4065 return (obj
->status
);
4069 raid_obj_set_status(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4070 raid_obj_status_t status
)
4074 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4076 return (ERR_DEVICE_NOENT
);
4078 obj
->status
= obj
->status
| status
;
4084 raid_obj_clear_status(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4085 raid_obj_status_t status
)
4089 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4091 return (ERR_DEVICE_NOENT
);
4093 obj
->status
= obj
->status
& ~status
;
4098 static raid_obj_id_t
4099 raid_obj_get_container(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4103 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4105 return (ERR_DEVICE_NOENT
);
4107 return (obj
->container
);
4111 raid_obj_set_container(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4112 raid_obj_id_t container_id
)
4116 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4118 return (ERR_DEVICE_NOENT
);
4120 obj
->container
= container_id
;
4124 static raid_obj_id_t
4125 raid_obj_get_comp(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4129 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4131 return (ERR_DEVICE_NOENT
);
4133 return (obj
->component
);
4137 raid_obj_set_comp(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4142 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4144 return (ERR_DEVICE_NOENT
);
4146 obj
->component
= comp
;
4150 static raid_obj_id_t
4151 raid_obj_get_sibling(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4155 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4157 return (ERR_DEVICE_NOENT
);
4159 return (obj
->sibling
);
4163 raid_obj_set_sibling(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4164 raid_obj_id_t sibling
)
4168 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4170 return (ERR_DEVICE_NOENT
);
4172 obj
->sibling
= sibling
;
4178 raid_obj_get_data_ptr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4182 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4190 raid_obj_set_data_ptr(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4195 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4197 return (ERR_DEVICE_NOENT
);
4204 static raid_obj_handle_t
4205 raid_obj_get_handle(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
)
4209 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4211 return (ERR_DEVICE_NOENT
);
4213 return (obj
->handle
);
4217 raid_obj_set_handle(raid_obj_tab_t
*raid_tab
, raid_obj_id_t obj_id
,
4218 raid_obj_handle_t handle
)
4222 obj
= raid_obj_tab_find(raid_tab
, obj_id
);
4224 return (ERR_DEVICE_NOENT
);
4226 obj
->handle
= handle
;
4230 * Object list maintennance routines
4233 raid_list_create(raid_list_t
*list
, size_t offset
)
4237 list
->offset
= offset
;
4241 raid_list_head(raid_list_t
*list
)
4243 return (list
->head
);
4247 raid_list_next(raid_list_t
*list
, void *obj
)
4249 raid_list_el_t
*el
= LIST_OBJ_TO_EL(list
, obj
);
4255 raid_list_insert_tail(raid_list_t
*list
, void *obj
)
4257 raid_list_el_t
*el
= LIST_OBJ_TO_EL(list
, obj
), *el1
;
4259 el
->prev
= list
->tail
;
4264 if (list
->head
== NULL
)
4267 if (el
->prev
!= NULL
) {
4268 el1
= LIST_OBJ_TO_EL(list
, el
->prev
);
4274 raid_list_remove(raid_list_t
*list
, void *obj
)
4276 raid_list_el_t
*el
= LIST_OBJ_TO_EL(list
, obj
), *el1
;
4278 if (list
->head
== obj
)
4279 list
->head
= el
->next
;
4281 if (list
->tail
== obj
)
4282 list
->tail
= el
->prev
;
4284 if (el
->next
!= NULL
) {
4285 el1
= LIST_OBJ_TO_EL(list
, el
->next
);
4286 el1
->prev
= el
->prev
;
4289 if (el
->prev
!= NULL
) {
4290 el1
= LIST_OBJ_TO_EL(list
, el
->prev
);
4291 el1
->next
= el
->next
;
4294 el
->prev
= el
->next
= NULL
;
4298 raid_list_remove_head(raid_list_t
*list
)
4300 void *obj
= list
->head
;
4303 raid_list_remove(list
, obj
);
4309 raid_list_find(raid_list_t
*list
, raid_obj_id_t obj_id
)
4313 for (obj
= raid_list_head(list
); obj
!= NULL
;
4314 obj
= raid_list_next(list
, obj
))
4315 if (obj
->obj_id
== obj_id
)
4322 raid_obj_tab_create(raid_obj_tab_t
*tab
, size_t hash_slots
)
4326 if (hash_slots
== 0)
4327 return (ERR_OP_ILLEGAL
);
4329 tab
->slots
= hash_slots
;
4331 if ((tab
->table
= calloc(hash_slots
, sizeof (raid_list_t
))) == NULL
)
4334 for (i
= 0; i
< hash_slots
; i
++)
4335 raid_list_create(&tab
->table
[i
], offsetof(raid_obj_t
, el
));
4341 raid_obj_tab_destroy(raid_obj_tab_t
*tab
)
4345 for (i
= 0; i
< tab
->slots
; i
++) {
4346 struct raid_obj_t
*obj
;
4348 while ((obj
= raid_list_remove_head(&tab
->table
[i
])) != NULL
)
4351 raid_list_destroy(&tab
->table
[i
]);
4358 tab
->obj_id_cnt
= 0;
4362 raid_obj_tab_insert(raid_obj_tab_t
*tab
, raid_obj_id_t id
, void *obj
)
4366 list
= OBJ_TAB_SLOT(tab
, id
);
4368 if (raid_list_find(list
, id
) != NULL
)
4369 return (ERR_DEVICE_DUP
);
4371 raid_list_insert_tail(list
, obj
);
4377 raid_obj_tab_remove(raid_obj_tab_t
*tab
, raid_obj_id_t id
)
4382 list
= OBJ_TAB_SLOT(tab
, id
);
4384 if ((obj
= raid_list_find(list
, id
)) != NULL
)
4385 raid_list_remove(list
, obj
);
4391 raid_obj_tab_find(raid_obj_tab_t
*tab
, raid_obj_id_t id
)
4396 list
= OBJ_TAB_SLOT(tab
, id
);
4397 obj
= raid_list_find(list
, id
);
4403 raid_list_destroy(raid_list_t
*list
)
4411 * Plug-in maintennance routines
4414 controller_id_to_path(uint32_t controller_id
, char *path
)
4417 char buf
[MAX_PATH_LEN
] = {0}, buf1
[MAX_PATH_LEN
] = {0}, *colon
;
4419 (void) snprintf(buf
, MAX_PATH_LEN
, "%s/c%d", CFGDIR
, controller_id
);
4420 if (readlink(buf
, buf1
, sizeof (buf1
)) < 0)
4421 return (ERR_DRIVER_NOT_FOUND
);
4424 (void) snprintf(buf
, sizeof (buf
), "%s/", CFGDIR
);
4427 (void) strlcat(buf
, buf1
, MAX_PATH_LEN
);
4429 colon
= strrchr(buf
, ':');
4431 return (ERR_DRIVER_NOT_FOUND
);
4435 (void) snprintf(path
, MAX_PATH_LEN
, "%s:devctl", buf
);
4437 fd
= open(path
, O_RDONLY
| O_NDELAY
);
4440 return (ERR_DRIVER_NOT_FOUND
);
4448 controller_id_to_driver_name(uint32_t controller_id
)
4450 char buf
[MAX_PATH_LEN
];
4455 ret
= controller_id_to_path(controller_id
, buf
);
4459 tmp
= strrchr(buf
, ':');
4463 tmp
= strstr(buf
, "pci");
4467 di_node
= di_init(tmp
, DINFOPROP
);
4468 if (di_node
== DI_NODE_NIL
)
4471 name
= di_driver_name(di_node
);
4479 raid_lib_t
*raid_lib
= raid_lib_sys
;
4482 raid_lib_sys
= raid_lib
->next
;
4483 (void) dlclose(raid_lib
->lib_handle
);
4485 raid_lib
= raid_lib_sys
;
4490 raid_plugin_load(char *driver_name
)
4492 char buf
[MAX_PATH_LEN
] = {0};
4493 raid_lib_t
*supplib
;
4496 supplib
= calloc(1, sizeof (raid_lib_t
));
4497 if (supplib
== NULL
)
4500 (void) snprintf(buf
, MAX_PATH_LEN
, "%s/%s.so.1",
4501 SUPP_PLUGIN_DIR
, driver_name
);
4503 supplib
->lib_handle
= dlopen(buf
, RTLD_LAZY
);
4504 if (supplib
->lib_handle
== NULL
) {
4509 supplib
->name
= driver_name
;
4511 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_version")) == NULL
)
4512 supplib
->version
= RDCFG_PLUGIN_V1
;
4514 supplib
->version
= *((uint32_t *)sym
);
4515 if (supplib
->version
!= RDCFG_PLUGIN_V1
) {
4516 (void) dlclose(supplib
->lib_handle
);
4522 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_open_controller")) ==
4524 (void) dlclose(supplib
->lib_handle
);
4528 supplib
->open_controller
= (int(*)(uint32_t, char **))sym
;
4530 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_close_controller")) ==
4532 (void) dlclose(supplib
->lib_handle
);
4536 supplib
->close_controller
= (int (*)(uint32_t, char **))sym
;
4538 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_compnum")) == NULL
) {
4539 (void) dlclose(supplib
->lib_handle
);
4543 supplib
->compnum
= (int (*)(uint32_t, uint32_t,
4544 raid_obj_type_id_t
, raid_obj_type_id_t
))sym
;
4546 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_complist")) == NULL
) {
4547 (void) dlclose(supplib
->lib_handle
);
4551 supplib
->complist
= (int (*)(uint32_t, uint32_t,
4552 raid_obj_type_id_t
, raid_obj_type_id_t
, int, void *))sym
;
4554 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_get_attr")) == NULL
) {
4555 (void) dlclose(supplib
->lib_handle
);
4559 supplib
->get_attr
= (int (*)(uint32_t, uint32_t, uint32_t,
4560 raid_obj_type_id_t
, void*))sym
;
4562 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_array_create")) == NULL
) {
4563 (void) dlclose(supplib
->lib_handle
);
4567 supplib
->array_create
= (int (*)(uint32_t, array_attr_t
*, int,
4568 arraypart_attr_t
*, char **))sym
;
4570 if ((sym
= dlsym(supplib
->lib_handle
, "rdcfg_array_delete")) == NULL
) {
4571 (void) dlclose(supplib
->lib_handle
);
4575 supplib
->array_delete
=
4576 (int (*)(uint32_t, uint32_t, char **))sym
;
4578 supplib
->hsp_bind
= (int (*)(uint32_t, hsp_relation_t
*,
4579 char **))dlsym(supplib
->lib_handle
, "rdcfg_hsp_bind");
4580 supplib
->hsp_unbind
= (int (*)(uint32_t, hsp_relation_t
*,
4581 char **))dlsym(supplib
->lib_handle
, "rdcfg_hsp_unbind");
4582 supplib
->set_attr
= (int (*)(uint32_t, uint32_t, uint32_t, uint32_t *,
4583 char **))dlsym(supplib
->lib_handle
, "rdcfg_set_attr");
4584 supplib
->flash_fw
= (int (*)(uint32_t, char *, uint32_t, char **))
4585 dlsym(supplib
->lib_handle
, "rdcfg_flash_fw");
4587 supplib
->next
= raid_lib_sys
;
4588 raid_lib_sys
= supplib
;
4593 raid_find_lib(raid_obj_tab_t
*raid_tab
, raid_obj_id_t controller_obj_id
)
4595 controller_attr_t
*controller_attr
;
4596 raid_lib_t
*raid_lib
;
4598 raid_obj_handle_t handle
;
4600 /* Check if it's mapped to handle structure */
4601 handle
= raid_obj_to_handle(raid_tab
, controller_obj_id
);
4602 if (raid_handle_sys
.handles
[handle
].raid_lib
!= NULL
)
4603 return (raid_handle_sys
.handles
[handle
].raid_lib
);
4605 (void) obj_get_attr(raid_tab
, controller_obj_id
,
4606 (void **)(&controller_attr
));
4608 /* Check if the plugin module is already loaded */
4609 driver_name
= controller_id_to_driver_name(
4610 controller_attr
->controller_id
);
4611 if (driver_name
== NULL
)
4614 raid_lib
= raid_lib_sys
;
4615 while (raid_lib
!= NULL
) {
4616 if (raid_lib
->name
!= NULL
&&
4617 strcmp(driver_name
, raid_lib
->name
) == 0)
4620 raid_lib
= raid_lib
->next
;
4623 /* Loading the plugin module */
4624 raid_lib
= raid_plugin_load(driver_name
);