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