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