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