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 *, int, raid_obj_id_t *, char **); 111 int (*unbind_obj)(raid_obj_tab_t *, int, 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 *, int, raid_obj_id_t *, char **); 229 static int obj_hsp_unbind(raid_obj_tab_t *, int, 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(int num, 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, i; 1039 1040 (void) mutex_lock(&raidcfg_mp); 1041 (void) obj_rescan(&raid_tab_sys); 1042 if ((num == 0) || (hsp_relations == NULL)) { 1043 (void) mutex_unlock(&raidcfg_mp); 1044 return (ERR_OP_ILLEGAL); 1045 } 1046 1047 hsp_relation_objs = malloc(2 * num * 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 for (i = 0; i < num; ++ i) { 1056 if (hsp_relations->array_handle != OBJ_ATTR_NONE) { 1057 array_obj_id = raid_handle_to_obj(&raid_tab_sys, 1058 hsp_relations[i].array_handle); 1059 if (array_obj_id < OBJ_NONE) { 1060 free(hsp_relation_objs); 1061 (void) mutex_unlock(&raidcfg_mp); 1062 return (array_obj_id); 1063 } 1064 if (array_obj_id == OBJ_NONE) { 1065 (void) free(hsp_relation_objs); 1066 (void) mutex_unlock(&raidcfg_mp); 1067 return (ERR_DEVICE_NOENT); 1068 } 1069 if (raidcfg_get_type(hsp_relations[i].array_handle) != 1070 OBJ_TYPE_ARRAY) { 1071 free(hsp_relation_objs); 1072 (void) mutex_unlock(&raidcfg_mp); 1073 return (ERR_DEVICE_TYPE); 1074 } 1075 } else 1076 array_obj_id = OBJ_ATTR_NONE; 1077 1078 disk_obj_id = raid_handle_to_obj(&raid_tab_sys, 1079 hsp_relations[i].disk_handle); 1080 if (disk_obj_id < OBJ_NONE) { 1081 free(hsp_relation_objs); 1082 (void) mutex_unlock(&raidcfg_mp); 1083 return (disk_obj_id); 1084 } 1085 if (disk_obj_id == OBJ_NONE) { 1086 free(hsp_relation_objs); 1087 (void) mutex_unlock(&raidcfg_mp); 1088 return (ERR_DEVICE_NOENT); 1089 } 1090 if (raidcfg_get_type(hsp_relations[i].disk_handle) != 1091 OBJ_TYPE_DISK) { 1092 free(hsp_relation_objs); 1093 (void) mutex_unlock(&raidcfg_mp); 1094 return (ERR_DEVICE_TYPE); 1095 } 1096 1097 hsp_relation_objs[2 * i] = array_obj_id; 1098 hsp_relation_objs[2 * i + 1] = disk_obj_id; 1099 } 1100 1101 ret = raid_obj_op_sys[OBJ_TYPE_HSP].bind_obj(&raid_tab_sys, num, 1102 hsp_relation_objs, plugin_err_str); 1103 1104 (void) obj_rescan(&raid_tab_sys); 1105 free(hsp_relation_objs); 1106 (void) mutex_unlock(&raidcfg_mp); 1107 1108 return (ret); 1109 } 1110 1111 int 1112 raidcfg_unset_hsp(int num, raidcfg_hsp_relation_t *hsp_relations, 1113 char **plugin_err_str) 1114 { 1115 raid_obj_id_t disk_obj_id, array_obj_id; 1116 raid_obj_id_t *hsp_relation_objs; 1117 int ret, i; 1118 1119 (void) mutex_lock(&raidcfg_mp); 1120 (void) obj_rescan(&raid_tab_sys); 1121 if ((num == 0) || (hsp_relations == NULL)) { 1122 (void) mutex_unlock(&raidcfg_mp); 1123 return (ERR_OP_ILLEGAL); 1124 } 1125 1126 hsp_relation_objs = malloc(2 * num * sizeof (raid_obj_id_t)); 1127 if (hsp_relation_objs == NULL) { 1128 (void) mutex_unlock(&raidcfg_mp); 1129 return (ERR_NOMEM); 1130 } 1131 1132 (void) obj_rescan(&raid_tab_sys); 1133 1134 for (i = 0; i < num; ++ i) { 1135 if (hsp_relations->array_handle != OBJ_ATTR_NONE) { 1136 array_obj_id = raid_handle_to_obj(&raid_tab_sys, 1137 hsp_relations[i].array_handle); 1138 if (array_obj_id < OBJ_NONE) { 1139 free(hsp_relation_objs); 1140 (void) mutex_unlock(&raidcfg_mp); 1141 return (array_obj_id); 1142 } 1143 if (array_obj_id == OBJ_NONE) { 1144 free(hsp_relation_objs); 1145 (void) mutex_unlock(&raidcfg_mp); 1146 return (ERR_DEVICE_NOENT); 1147 } 1148 if (raidcfg_get_type(hsp_relations[i].array_handle) != 1149 OBJ_TYPE_ARRAY) { 1150 free(hsp_relation_objs); 1151 (void) mutex_unlock(&raidcfg_mp); 1152 return (ERR_DEVICE_TYPE); 1153 } 1154 } else 1155 array_obj_id = OBJ_ATTR_NONE; 1156 1157 disk_obj_id = raid_handle_to_obj(&raid_tab_sys, 1158 hsp_relations[i].disk_handle); 1159 if (disk_obj_id < OBJ_NONE) { 1160 free(hsp_relation_objs); 1161 (void) mutex_unlock(&raidcfg_mp); 1162 return (disk_obj_id); 1163 } 1164 if (disk_obj_id == OBJ_NONE) { 1165 free(hsp_relation_objs); 1166 (void) mutex_unlock(&raidcfg_mp); 1167 return (ERR_DEVICE_NOENT); 1168 } 1169 if (raidcfg_get_type(hsp_relations[i].disk_handle) != 1170 OBJ_TYPE_DISK) { 1171 free(hsp_relation_objs); 1172 (void) mutex_unlock(&raidcfg_mp); 1173 return (ERR_DEVICE_TYPE); 1174 } 1175 1176 hsp_relation_objs[2 * i] = array_obj_id; 1177 hsp_relation_objs[2 * i + 1] = disk_obj_id; 1178 } 1179 1180 ret = raid_obj_op_sys[OBJ_TYPE_HSP].unbind_obj(&raid_tab_sys, 1181 num, hsp_relation_objs, plugin_err_str); 1182 1183 (void) obj_rescan(&raid_tab_sys); 1184 free(hsp_relation_objs); 1185 (void) mutex_unlock(&raidcfg_mp); 1186 1187 return (ret); 1188 } 1189 1190 /* 1191 * RaidCfg lib routines 1192 */ 1193 void 1194 raidcfg_init(void) 1195 { 1196 (void) mutex_init(&raidcfg_mp, NULL, NULL); 1197 raid_plugin_init(); 1198 (void) raid_handle_init(); 1199 (void) obj_rescan(&raid_tab_sys); 1200 } 1201 1202 void 1203 raidcfg_fini(void) 1204 { 1205 /* 1206 * Need to close all opened controllers before destroying object table 1207 */ 1208 (void) obj_rescan(&raid_tab_sys); 1209 raid_handle_fini(); 1210 raid_obj_tab_destroy(&raid_tab_sys); 1211 raid_plugin_init(); 1212 (void) mutex_destroy(&raidcfg_mp); 1213 } 1214 1215 /* 1216 * Support routines 1217 */ 1218 static int 1219 intcompare(const void *p1, const void *p2) 1220 { 1221 int i, j; 1222 i = *((int *)p1); 1223 j = *((int *)p2); 1224 return (i - j); 1225 } 1226 1227 static uint64_t 1228 raid_space_noalign(raid_obj_tab_t *raid_tab, uint32_t raid_level, int num, 1229 raid_obj_id_t *disk_objs, arraypart_attr_t *arraypart_attrs) 1230 { 1231 disk_attr_t *disk_attr; 1232 diskseg_attr_t *diskseg_attr; 1233 raid_obj_id_t obj_id; 1234 uint64_t offset, capacity; 1235 int i, disk_num, sub_array_num, disk_layer; 1236 1237 /* Find out the maximum available space for all disks */ 1238 for (i = 0; i < num; ++i) { 1239 if ((disk_objs[i] == OBJ_SEPARATOR_BEGIN) || 1240 (disk_objs[i] == OBJ_SEPARATOR_END)) 1241 continue; 1242 1243 (void) obj_get_attr(raid_tab, disk_objs[i], 1244 (void **)(&disk_attr)); 1245 obj_id = obj_get_comp(raid_tab, disk_objs[i], 1246 OBJ_TYPE_DISK_SEG); 1247 if (obj_id == OBJ_NONE) { 1248 arraypart_attrs[i].offset = 0; 1249 arraypart_attrs[i].size = disk_attr->capacity; 1250 continue; 1251 } 1252 1253 (void) obj_get_attr(raid_tab, obj_id, (void **) 1254 (&diskseg_attr)); 1255 arraypart_attrs[i].offset = 0; 1256 arraypart_attrs[i].size = diskseg_attr->offset; 1257 offset = diskseg_attr->offset + diskseg_attr->size; 1258 1259 while ((obj_id = obj_get_sibling(raid_tab, obj_id)) != 1260 OBJ_NONE) { 1261 (void) obj_get_attr(raid_tab, obj_id, 1262 (void **)(&diskseg_attr)); 1263 if ((diskseg_attr->offset - offset) > 1264 arraypart_attrs[i].size) { 1265 arraypart_attrs[i].offset = offset; 1266 arraypart_attrs[i].size = diskseg_attr->offset - 1267 offset; 1268 } 1269 1270 offset = diskseg_attr->offset + diskseg_attr->size; 1271 } 1272 1273 if ((disk_attr->capacity - offset) > arraypart_attrs[i].size) { 1274 arraypart_attrs[i].offset = offset; 1275 arraypart_attrs[i].size = disk_attr->capacity - 1276 offset; 1277 } 1278 } 1279 1280 capacity = OBJ_ATTR_NONE; 1281 disk_num = 0; 1282 disk_layer = 0; 1283 sub_array_num = 0; 1284 for (i = 0; i < num; ++i) { 1285 if (disk_objs[i] == OBJ_SEPARATOR_BEGIN) { 1286 ++ disk_layer; 1287 continue; 1288 } 1289 if (disk_objs[i] == OBJ_SEPARATOR_END) { 1290 -- disk_layer; 1291 if (disk_layer != 0) 1292 ++ sub_array_num; 1293 continue; 1294 } 1295 1296 if (capacity > arraypart_attrs[i].size) 1297 capacity = arraypart_attrs[i].size; 1298 ++disk_num; 1299 } 1300 1301 switch (raid_level) { 1302 case RAID_LEVEL_0: 1303 capacity = capacity * disk_num; 1304 break; 1305 case RAID_LEVEL_1: 1306 capacity = capacity * disk_num / 2; 1307 break; 1308 case RAID_LEVEL_1E: 1309 capacity = capacity * disk_num / 2; 1310 break; 1311 case RAID_LEVEL_5: 1312 capacity = capacity * (disk_num - 1); 1313 break; 1314 case RAID_LEVEL_10: 1315 capacity = capacity * disk_num / 2; 1316 break; 1317 case RAID_LEVEL_50: 1318 capacity = capacity * (disk_num - sub_array_num); 1319 break; 1320 default: 1321 return (ERR_ARRAY_LEVEL); 1322 break; 1323 } 1324 1325 return (capacity); 1326 } 1327 1328 /* 1329 * Raid handle maintenance routines 1330 */ 1331 static int 1332 raid_handle_init() 1333 { 1334 int i; 1335 void *ptr; 1336 1337 raid_handle_sys.handle_num += HANDLER_SLOTS; 1338 ptr = realloc(raid_handle_sys.handles, 1339 raid_handle_sys.handle_num * sizeof (handle_attr_t)); 1340 if (ptr == NULL) 1341 return (ERR_NOMEM); 1342 raid_handle_sys.handles = ptr; 1343 1344 /* Clean up the new allocated handles */ 1345 for (i = raid_handle_sys.handle_num - HANDLER_SLOTS; 1346 i < raid_handle_sys.handle_num; ++i) { 1347 raid_handle_sys.handles[i].type = OBJ_TYPE_ALL; 1348 raid_handle_sys.handles[i].next = i + 1; 1349 } 1350 1351 /* For the first time of allocation, set up the system object handle */ 1352 if (raid_handle_sys.handle_num == HANDLER_SLOTS) { 1353 raid_handle_sys.handles[0].type = OBJ_TYPE_SYSTEM; 1354 raid_handle_sys.handles[0].next = 0; 1355 raid_handle_sys.unused = 1; 1356 raid_handle_sys.used = 0; 1357 } 1358 return (SUCCESS); 1359 } 1360 1361 static void 1362 raid_handle_fini() 1363 { 1364 raid_obj_handle_t i; 1365 1366 i = raid_handle_sys.used; 1367 1368 /* Close all opened controllers */ 1369 while (i != 0) { 1370 if ((raid_handle_sys.handles[i].type == OBJ_TYPE_CONTROLLER) && 1371 (raid_handle_sys.handles[i].fd != 0) && 1372 (raid_handle_sys.handles[i].raid_lib != NULL)) 1373 raid_handle_sys.handles[i].raid_lib->close_controller( 1374 raid_handle_sys.handles[i].controller_id, NULL); 1375 i = raid_handle_sys.handles[i].next; 1376 } 1377 1378 /* Clean up handle space */ 1379 raid_handle_sys.handle_num = 0; 1380 raid_handle_sys.unused = 0; 1381 raid_handle_sys.used = 0; 1382 free(raid_handle_sys.handles); 1383 raid_handle_sys.handles = NULL; 1384 } 1385 1386 static raid_obj_handle_t 1387 raid_handle_new(raid_obj_type_id_t type) 1388 { 1389 int ret; 1390 1391 if (raid_handle_sys.unused == raid_handle_sys.handle_num - 1) { 1392 ret = raid_handle_init(); 1393 if (ret < SUCCESS) 1394 return (ret); 1395 } 1396 1397 ret = raid_handle_sys.unused; 1398 raid_handle_sys.unused = raid_handle_sys.handles[ret].next; 1399 1400 raid_handle_sys.handles[ret].next = raid_handle_sys.used; 1401 raid_handle_sys.used = ret; 1402 raid_handle_sys.handles[ret].type = type; 1403 1404 return (ret); 1405 } 1406 1407 static void 1408 raid_handle_delete(raid_obj_handle_t handle) 1409 { 1410 int i = raid_handle_sys.used, j = 0; 1411 1412 if (handle == 0) 1413 return; 1414 1415 while (i != 0 && i != handle) { 1416 j = i; 1417 i = raid_handle_sys.handles[i].next; 1418 } 1419 1420 if (i == handle) { 1421 if (j != 0) 1422 raid_handle_sys.handles[j].next = 1423 raid_handle_sys.handles[i].next; 1424 else 1425 raid_handle_sys.used = 1426 raid_handle_sys.handles[i].next; 1427 1428 raid_handle_sys.handles[i].type = OBJ_TYPE_ALL; 1429 raid_handle_sys.handles[i].next = 1430 raid_handle_sys.unused; 1431 raid_handle_sys.unused = i; 1432 } 1433 } 1434 1435 static void 1436 raid_handle_delete_controller_comp(uint32_t controller_id) 1437 { 1438 int i = raid_handle_sys.used, j; 1439 1440 while (i != 0) { 1441 j = i; 1442 i = raid_handle_sys.handles[i].next; 1443 if ((raid_handle_sys.handles[j].controller_id == 1444 controller_id) && 1445 (raid_handle_sys.handles[j].type != 1446 OBJ_TYPE_CONTROLLER)) 1447 raid_handle_delete(j); 1448 } 1449 } 1450 1451 static raid_obj_id_t 1452 raid_handle_to_obj(raid_obj_tab_t *raid_tab, raid_obj_handle_t handle) 1453 { 1454 handle_attr_t *handle_attr; 1455 raid_obj_id_t obj_id; 1456 1457 if (handle == OBJ_SYSTEM) 1458 return (OBJ_SYSTEM); 1459 1460 handle_attr = raid_handle_sys.handles + handle; 1461 1462 switch (handle_attr->type) { 1463 case OBJ_TYPE_SYSTEM: 1464 return (OBJ_SYSTEM); 1465 case OBJ_TYPE_CONTROLLER: 1466 obj_id = obj_locate_controller(raid_tab, 1467 handle_attr->controller_id); 1468 break; 1469 case OBJ_TYPE_ARRAY: 1470 obj_id = obj_locate_array(raid_tab, 1471 handle_attr->controller_id, handle_attr->array_id); 1472 break; 1473 case OBJ_TYPE_HSP: 1474 obj_id = obj_locate_hsp(raid_tab, 1475 handle_attr->controller_id, handle_attr->disk_id, 1476 handle_attr->array_id); 1477 break; 1478 case OBJ_TYPE_DISK: 1479 obj_id = obj_locate_disk(raid_tab, 1480 handle_attr->controller_id, handle_attr->disk_id); 1481 break; 1482 case OBJ_TYPE_ARRAY_PART: 1483 obj_id = obj_locate_arraypart(raid_tab, 1484 handle_attr->controller_id, handle_attr->array_id, 1485 handle_attr->disk_id); 1486 break; 1487 case OBJ_TYPE_DISK_SEG: 1488 obj_id = obj_locate_diskseg(raid_tab, 1489 handle_attr->controller_id, 1490 handle_attr->disk_id, handle_attr->seq_id); 1491 break; 1492 case OBJ_TYPE_TASK: 1493 obj_id = obj_locate_task(raid_tab, 1494 handle_attr->controller_id, handle_attr->task_id); 1495 break; 1496 case OBJ_TYPE_PROP: 1497 obj_id = obj_locate_prop(raid_tab, 1498 handle_attr->controller_id, handle_attr->disk_id, 1499 handle_attr->prop_id); 1500 break; 1501 default: 1502 return (ERR_DEVICE_INVALID); 1503 } 1504 1505 if (obj_id < OBJ_NONE) 1506 return (obj_id); 1507 if (obj_id == OBJ_NONE) 1508 return (ERR_DEVICE_NOENT); 1509 1510 (void) raid_obj_set_handle(raid_tab, obj_id, handle); 1511 return (obj_id); 1512 } 1513 1514 static raid_obj_handle_t 1515 raid_obj_to_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1516 { 1517 raid_obj_id_t obj_id_backup = obj_id; 1518 raid_obj_type_id_t type; 1519 raid_obj_handle_t handle; 1520 controller_attr_t *controller_attr; 1521 array_attr_t *array_attr; 1522 hsp_attr_t *hsp_attr; 1523 disk_attr_t *disk_attr; 1524 arraypart_attr_t *arraypart_attr; 1525 diskseg_attr_t *diskseg_attr; 1526 task_attr_t *task_attr; 1527 property_attr_t *prop_attr; 1528 1529 if (obj_id == OBJ_SYSTEM) 1530 return (OBJ_SYSTEM); 1531 1532 /* If the object mapped by a handle */ 1533 handle = raid_obj_get_handle(raid_tab, obj_id); 1534 if (handle != 0) 1535 return (handle); 1536 1537 /* Search for existing handles */ 1538 for (handle = raid_handle_sys.used; handle != 0; 1539 handle = raid_handle_sys.handles[handle].next) 1540 if (raid_handle_to_obj(raid_tab, handle) == obj_id) 1541 break; 1542 1543 if (handle != 0) 1544 return (handle); 1545 1546 /* Allocate new handle for this object */ 1547 type = raid_obj_get_type(raid_tab, obj_id); 1548 handle = raid_handle_new(type); 1549 (void) raid_obj_set_handle(raid_tab, obj_id, handle); 1550 raid_handle_sys.handles[handle].type = type; 1551 1552 switch (type) { 1553 case OBJ_TYPE_SYSTEM: 1554 break; 1555 case OBJ_TYPE_CONTROLLER: 1556 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1557 raid_handle_sys.handles[handle].controller_id = 1558 controller_attr->controller_id; 1559 break; 1560 case OBJ_TYPE_ARRAY: 1561 array_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1562 raid_handle_sys.handles[handle].array_id = array_attr->array_id; 1563 obj_id = obj_get_controller(raid_tab, obj_id); 1564 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1565 raid_handle_sys.handles[handle].controller_id = 1566 controller_attr->controller_id; 1567 break; 1568 case OBJ_TYPE_HSP: 1569 hsp_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1570 raid_handle_sys.handles[handle].array_id = 1571 hsp_attr->associated_id; 1572 obj_id = raid_obj_get_container(raid_tab, obj_id); 1573 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1574 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id; 1575 obj_id = obj_get_controller(raid_tab, obj_id); 1576 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1577 raid_handle_sys.handles[handle].controller_id = 1578 controller_attr->controller_id; 1579 break; 1580 case OBJ_TYPE_DISK: 1581 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1582 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id; 1583 obj_id = obj_get_controller(raid_tab, obj_id); 1584 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1585 raid_handle_sys.handles[handle].controller_id = 1586 controller_attr->controller_id; 1587 break; 1588 case OBJ_TYPE_ARRAY_PART: 1589 arraypart_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1590 raid_handle_sys.handles[handle].disk_id = 1591 arraypart_attr->disk_id; 1592 obj_id = raid_obj_get_container(raid_tab, obj_id); 1593 array_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1594 raid_handle_sys.handles[handle].array_id = 1595 array_attr->array_id; 1596 obj_id = obj_get_controller(raid_tab, obj_id); 1597 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1598 raid_handle_sys.handles[handle].controller_id = 1599 controller_attr->controller_id; 1600 break; 1601 case OBJ_TYPE_DISK_SEG: 1602 diskseg_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1603 raid_handle_sys.handles[handle].seq_id = diskseg_attr->seq_no; 1604 obj_id = raid_obj_get_container(raid_tab, obj_id); 1605 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1606 raid_handle_sys.handles[handle].disk_id = 1607 disk_attr->disk_id; 1608 obj_id = obj_get_controller(raid_tab, obj_id); 1609 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1610 raid_handle_sys.handles[handle].controller_id = 1611 controller_attr->controller_id; 1612 break; 1613 case OBJ_TYPE_TASK: 1614 task_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1615 raid_handle_sys.handles[handle].task_id = task_attr->task_id; 1616 obj_id = obj_get_controller(raid_tab, obj_id); 1617 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1618 raid_handle_sys.handles[handle].controller_id = 1619 controller_attr->controller_id; 1620 break; 1621 case OBJ_TYPE_PROP: 1622 prop_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1623 raid_handle_sys.handles[handle].prop_id = 1624 prop_attr->prop_id; 1625 obj_id = raid_obj_get_container(raid_tab, obj_id); 1626 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1627 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id; 1628 obj_id = obj_get_controller(raid_tab, obj_id); 1629 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1630 raid_handle_sys.handles[handle].controller_id = 1631 controller_attr->controller_id; 1632 break; 1633 default: 1634 return (ERR_DEVICE_INVALID); 1635 } 1636 1637 (void) raid_obj_set_handle(raid_tab, obj_id_backup, handle); 1638 return (handle); 1639 } 1640 1641 static raid_lib_t * 1642 raid_obj_get_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1643 { 1644 raid_obj_handle_t handle; 1645 controller_attr_t *attr; 1646 1647 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1648 return (NULL); 1649 1650 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1651 handle = raid_handle_sys.used; 1652 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1653 raid_handle_sys.handles[handle].controller_id != 1654 attr->controller_id) 1655 handle = raid_handle_sys.handles[handle].next; 1656 1657 if (handle == 0) 1658 return (NULL); 1659 1660 return (raid_handle_sys.handles[handle].raid_lib); 1661 } 1662 1663 static int 1664 raid_obj_set_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 1665 raid_lib_t *raid_lib) 1666 { 1667 raid_obj_handle_t handle; 1668 controller_attr_t *attr; 1669 1670 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1671 return (ERR_DEVICE_TYPE); 1672 1673 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1674 handle = raid_handle_sys.used; 1675 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1676 raid_handle_sys.handles[handle].controller_id != 1677 attr->controller_id) 1678 handle = raid_handle_sys.handles[handle].next; 1679 1680 if (handle == 0) 1681 return (ERR_DEVICE_NOENT); 1682 1683 raid_handle_sys.handles[handle].raid_lib = raid_lib; 1684 return (SUCCESS); 1685 } 1686 1687 static int 1688 raid_obj_get_fd(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1689 { 1690 raid_obj_handle_t handle; 1691 controller_attr_t *attr; 1692 1693 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1694 return (ERR_DEVICE_TYPE); 1695 1696 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1697 handle = raid_handle_sys.used; 1698 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1699 raid_handle_sys.handles[handle].controller_id != 1700 attr->controller_id) 1701 handle = raid_handle_sys.handles[handle].next; 1702 1703 if (handle == 0) 1704 return (ERR_DEVICE_NOENT); 1705 1706 return (raid_handle_sys.handles[handle].fd); 1707 } 1708 1709 static int 1710 raid_obj_set_fd(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, int fd) 1711 { 1712 raid_obj_handle_t handle; 1713 controller_attr_t *attr; 1714 1715 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1716 return (ERR_DEVICE_TYPE); 1717 1718 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1719 handle = raid_handle_sys.used; 1720 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1721 raid_handle_sys.handles[handle].controller_id != 1722 attr->controller_id) 1723 handle = raid_handle_sys.handles[handle].next; 1724 1725 if (handle == 0) 1726 return (ERR_DEVICE_NOENT); 1727 1728 raid_handle_sys.handles[handle].fd = fd; 1729 return (SUCCESS); 1730 } 1731 1732 /* 1733 * Raid object maintenance routines 1734 */ 1735 static int 1736 obj_scan_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1737 { 1738 raid_obj_status_t status; 1739 raid_obj_type_id_t type; 1740 int ret, i, obj_type_cnt, comp_num; 1741 raid_obj_id_t *comp_list; 1742 1743 status = raid_obj_get_status(raid_tab, obj_id); 1744 if (status < SUCCESS) 1745 return (status); 1746 1747 if (status & OBJ_STATUS_SCANCOMP) 1748 return (SUCCESS); 1749 1750 type = raid_obj_get_type(raid_tab, obj_id); 1751 if (type < OBJ_TYPE_SYSTEM || type > OBJ_TYPE_ALL) 1752 return (ERR_DEVICE_INVALID); 1753 1754 for (obj_type_cnt = OBJ_SYSTEM; obj_type_cnt < OBJ_TYPE_ALL; 1755 ++obj_type_cnt) { 1756 if (raid_obj_op_sys[type].compnum != NULL) 1757 comp_num = raid_obj_op_sys[type].compnum( 1758 raid_tab, obj_id, obj_type_cnt); 1759 else 1760 comp_num = 0; 1761 1762 if (comp_num < SUCCESS) 1763 return (comp_num); 1764 if (comp_num == 0) 1765 continue; 1766 1767 comp_list = calloc(comp_num, sizeof (raid_obj_id_t)); 1768 if (comp_list == NULL) 1769 return (ERR_NOMEM); 1770 1771 for (i = 0; i < comp_num; ++i) { 1772 *(comp_list + i) = raid_obj_create(raid_tab, 1773 obj_type_cnt); 1774 if (*(comp_list + i) < SUCCESS) { 1775 ret = *(comp_list + i); 1776 free(comp_list); 1777 return (ret); 1778 } 1779 1780 (void) raid_obj_clear_status(raid_tab, 1781 *(comp_list + i), OBJ_STATUS_CMD_CLEAN); 1782 (void) raid_obj_add_org(raid_tab, *(comp_list + i), 1783 obj_id); 1784 } 1785 1786 if (raid_obj_op_sys[type].complist != NULL) 1787 raid_obj_op_sys[type].complist(raid_tab, 1788 obj_id, comp_num, comp_list, obj_type_cnt); 1789 free(comp_list); 1790 } 1791 1792 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_SCANCOMP); 1793 return (SUCCESS); 1794 } 1795 1796 static int 1797 obj_rescan(raid_obj_tab_t *raid_tab) 1798 { 1799 int ret; 1800 1801 raid_obj_tab_destroy(raid_tab); 1802 1803 if (raid_obj_tab_create(raid_tab, HASH_SLOTS) != SUCCESS) 1804 return (ERR_NOMEM); 1805 1806 if ((ret = raid_obj_create_system_obj(raid_tab)) != SUCCESS) { 1807 raid_obj_tab_destroy(raid_tab); 1808 return (ret); 1809 } 1810 1811 return (SUCCESS); 1812 } 1813 1814 static raid_obj_id_t 1815 obj_get_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 1816 raid_obj_type_id_t obj_type) 1817 { 1818 raid_obj_id_t id; 1819 raid_obj_type_id_t type; 1820 raid_obj_status_t status; 1821 int ret; 1822 1823 if ((obj_type < OBJ_TYPE_SYSTEM) || (obj_type > OBJ_TYPE_ALL)) 1824 return (ERR_DEVICE_TYPE); 1825 1826 status = raid_obj_get_status(raid_tab, obj_id); 1827 if (status < SUCCESS) 1828 return (status); 1829 1830 if (!(status & OBJ_STATUS_SCANCOMP)) { 1831 ret = obj_scan_comp(raid_tab, obj_id); 1832 if (ret < SUCCESS) 1833 return (ret); 1834 } 1835 1836 id = raid_obj_get_comp(raid_tab, obj_id); 1837 if (id <= OBJ_NONE) 1838 return (id); 1839 1840 type = raid_obj_get_type(raid_tab, id); 1841 if (type < OBJ_TYPE_SYSTEM) 1842 return (type); 1843 1844 if (type == obj_type) 1845 return (id); 1846 1847 while (id > OBJ_NONE) { 1848 id = raid_obj_get_sibling(raid_tab, id); 1849 if (id <= OBJ_NONE) 1850 return (id); 1851 1852 type = raid_obj_get_type(raid_tab, id); 1853 if (type < OBJ_TYPE_SYSTEM) 1854 return (type); 1855 1856 if (type == obj_type) 1857 break; 1858 }; 1859 1860 return (id); 1861 } 1862 1863 static raid_obj_id_t 1864 obj_get_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1865 { 1866 raid_obj_id_t id; 1867 raid_obj_type_id_t type, obj_type; 1868 1869 id = obj_id; 1870 obj_type = raid_obj_get_type(raid_tab, id); 1871 if (obj_type < OBJ_TYPE_SYSTEM) 1872 return (obj_type); 1873 1874 do { 1875 id = raid_obj_get_sibling(raid_tab, id); 1876 if (id < OBJ_NONE) 1877 return (id); 1878 1879 type = raid_obj_get_type(raid_tab, id); 1880 if (type < OBJ_TYPE_SYSTEM) 1881 return (type); 1882 } while ((type != obj_type) && (id != OBJ_NONE)); 1883 1884 return (id); 1885 } 1886 1887 static int 1888 obj_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, void **data) 1889 { 1890 raid_obj_type_id_t type; 1891 raid_obj_status_t status; 1892 void *attr; 1893 int ret = SUCCESS; 1894 1895 status = raid_obj_get_status(raid_tab, obj_id); 1896 if (status < SUCCESS) 1897 return (status); 1898 1899 type = raid_obj_get_type(raid_tab, obj_id); 1900 if (type < OBJ_TYPE_SYSTEM) 1901 return (type); 1902 1903 if (!(status & OBJ_STATUS_OPENED)) { 1904 if (raid_obj_op_sys[type].get_attr == NULL) 1905 (void) raid_obj_set_status(raid_tab, obj_id, 1906 OBJ_STATUS_OPENED); 1907 else 1908 ret = raid_obj_op_sys[type].get_attr(raid_tab, obj_id); 1909 } 1910 if (ret < SUCCESS) 1911 return (ret); 1912 1913 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1914 if (attr == NULL && type != OBJ_TYPE_SYSTEM) 1915 return (ERR_DEVICE_INVALID); 1916 1917 *data = attr; 1918 return (SUCCESS); 1919 } 1920 1921 static raid_obj_id_t 1922 obj_locate_controller(raid_obj_tab_t *raid_tab, uint32_t controller_id) 1923 { 1924 raid_obj_id_t obj_id; 1925 controller_attr_t *attr; 1926 1927 obj_id = obj_get_comp(raid_tab, OBJ_SYSTEM, OBJ_TYPE_CONTROLLER); 1928 if (obj_id <= OBJ_NONE) 1929 return (obj_id); 1930 1931 do { 1932 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1933 if (attr == NULL) 1934 return (ERR_DEVICE_INVALID); 1935 1936 if (attr->controller_id == controller_id) 1937 break; 1938 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) != OBJ_NONE); 1939 1940 return (obj_id); 1941 } 1942 1943 static raid_obj_id_t 1944 obj_locate_array(raid_obj_tab_t *raid_tab, uint32_t controller_id, 1945 uint32_t array_id) 1946 { 1947 raid_obj_id_t obj_id; 1948 1949 obj_id = obj_locate_controller(raid_tab, controller_id); 1950 if (obj_id < OBJ_NONE) 1951 return (obj_id); 1952 1953 obj_id = obj_locate_array_recur(raid_tab, obj_id, array_id); 1954 1955 return (obj_id); 1956 } 1957 1958 static raid_obj_id_t 1959 obj_locate_array_recur(raid_obj_tab_t *raid_tab, 1960 raid_obj_id_t container_obj_id, uint32_t array_id) 1961 { 1962 raid_obj_id_t obj_id, ret; 1963 array_attr_t *attr; 1964 1965 obj_id = obj_get_comp(raid_tab, container_obj_id, OBJ_TYPE_ARRAY); 1966 if (obj_id <= OBJ_NONE) 1967 return (obj_id); 1968 1969 do { 1970 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1971 if (attr == NULL) 1972 return (ERR_DEVICE_INVALID); 1973 1974 if (attr->array_id == array_id) 1975 break; 1976 1977 ret = obj_locate_array_recur(raid_tab, obj_id, array_id); 1978 if (ret != OBJ_NONE) 1979 return (ret); 1980 1981 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 1982 1983 return (obj_id); 1984 } 1985 1986 static raid_obj_id_t 1987 obj_locate_hsp(raid_obj_tab_t *raid_tab, uint32_t controller_id, 1988 uint32_t disk_id, uint32_t array_id) 1989 { 1990 raid_obj_id_t obj_id; 1991 hsp_attr_t *hsp_attr; 1992 1993 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id); 1994 if (obj_id <= OBJ_NONE) 1995 return (obj_id); 1996 1997 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_HSP); 1998 if (obj_id <= OBJ_NONE) 1999 return (obj_id); 2000 2001 do { 2002 (void) obj_get_attr(raid_tab, obj_id, (void **)(&hsp_attr)); 2003 if (hsp_attr->associated_id == array_id) 2004 break; 2005 2006 obj_id = obj_get_sibling(raid_tab, obj_id); 2007 if (obj_id < OBJ_NONE) 2008 return (obj_id); 2009 } while (obj_id > OBJ_NONE); 2010 2011 return (obj_id); 2012 } 2013 2014 static raid_obj_id_t 2015 obj_locate_disk(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2016 uint32_t disk_id) 2017 { 2018 raid_obj_id_t obj_id; 2019 disk_attr_t *attr; 2020 2021 obj_id = obj_locate_controller(raid_tab, controller_id); 2022 if (obj_id <= OBJ_NONE) 2023 return (obj_id); 2024 2025 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK); 2026 if (obj_id <= OBJ_NONE) 2027 return (obj_id); 2028 2029 do { 2030 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2031 if (attr == NULL) 2032 return (ERR_DEVICE_INVALID); 2033 2034 if (attr->disk_id == disk_id) 2035 break; 2036 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2037 2038 return (obj_id); 2039 } 2040 2041 static raid_obj_id_t 2042 obj_locate_arraypart(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2043 uint32_t array_id, uint32_t disk_id) 2044 { 2045 raid_obj_id_t obj_id; 2046 2047 arraypart_attr_t *attr; 2048 2049 obj_id = obj_locate_array(raid_tab, controller_id, array_id); 2050 if (obj_id <= OBJ_NONE) 2051 return (obj_id); 2052 2053 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY_PART); 2054 if (obj_id <= OBJ_NONE) 2055 return (obj_id); 2056 2057 do { 2058 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2059 if (attr == NULL) 2060 return (ERR_DEVICE_INVALID); 2061 2062 if (attr->disk_id == disk_id) 2063 break; 2064 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > 2065 OBJ_NONE); 2066 2067 return (obj_id); 2068 } 2069 2070 static raid_obj_id_t 2071 obj_locate_diskseg(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2072 uint32_t disk_id, uint32_t seq_no) 2073 { 2074 raid_obj_id_t obj_id; 2075 diskseg_attr_t *attr; 2076 2077 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id); 2078 if (obj_id <= OBJ_NONE) 2079 return (obj_id); 2080 2081 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK_SEG); 2082 if (obj_id <= OBJ_NONE) 2083 return (obj_id); 2084 2085 do { 2086 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2087 if (attr == NULL) 2088 return (ERR_DEVICE_INVALID); 2089 2090 if (attr->seq_no == seq_no) 2091 break; 2092 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2093 2094 return (obj_id); 2095 } 2096 2097 static raid_obj_id_t 2098 obj_locate_task(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2099 uint32_t task_id) 2100 { 2101 raid_obj_id_t obj_id, obj_id2, task_obj_id; 2102 task_attr_t *attr; 2103 2104 obj_id = obj_locate_controller(raid_tab, controller_id); 2105 if (obj_id <= OBJ_NONE) 2106 return (obj_id); 2107 2108 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY); 2109 if (obj_id < OBJ_NONE) 2110 return (obj_id); 2111 2112 do { 2113 obj_id2 = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY); 2114 while (obj_id2 != OBJ_NONE) { 2115 task_obj_id = obj_get_comp(raid_tab, obj_id2, 2116 OBJ_TYPE_TASK); 2117 2118 if (task_obj_id < OBJ_NONE) 2119 return (task_obj_id); 2120 2121 if (task_obj_id == OBJ_NONE) { 2122 obj_id2 = obj_get_sibling(raid_tab, obj_id2); 2123 continue; 2124 } 2125 2126 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id); 2127 if (attr == NULL) 2128 return (ERR_DEVICE_INVALID); 2129 2130 if (attr->task_id == task_id) 2131 return (task_obj_id); 2132 2133 obj_id2 = obj_get_sibling(raid_tab, obj_id2); 2134 } 2135 2136 task_obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_TASK); 2137 if (task_obj_id < OBJ_NONE) 2138 return (task_obj_id); 2139 2140 if (task_obj_id == OBJ_NONE) 2141 continue; 2142 2143 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id); 2144 if (attr == NULL) 2145 return (ERR_DEVICE_INVALID); 2146 2147 if (attr->task_id == task_id) 2148 return (task_obj_id); 2149 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2150 2151 if (obj_id < OBJ_NONE) 2152 return (obj_id); 2153 2154 obj_id = obj_locate_controller(raid_tab, controller_id); 2155 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK); 2156 if (obj_id < OBJ_NONE) 2157 return (obj_id); 2158 2159 do { 2160 task_obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_TASK); 2161 if (task_obj_id < OBJ_NONE) 2162 return (task_obj_id); 2163 2164 if (task_obj_id == OBJ_NONE) 2165 continue; 2166 2167 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id); 2168 if (attr == NULL) 2169 return (ERR_DEVICE_INVALID); 2170 2171 if (attr->task_id == task_id) 2172 return (task_obj_id); 2173 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2174 2175 return (obj_id); 2176 } 2177 2178 static raid_obj_id_t 2179 obj_locate_prop(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2180 uint32_t disk_id, uint32_t prop_id) 2181 { 2182 raid_obj_id_t obj_id; 2183 property_attr_t *prop_attr; 2184 2185 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id); 2186 if (obj_id < OBJ_NONE) 2187 return (obj_id); 2188 2189 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_PROP); 2190 if (obj_id <= OBJ_NONE) 2191 return (obj_id); 2192 2193 do { 2194 (void) obj_get_attr(raid_tab, obj_id, (void **)(&prop_attr)); 2195 if (prop_attr->prop_id == prop_id) 2196 break; 2197 2198 obj_id = obj_get_sibling(raid_tab, obj_id); 2199 if (obj_id < OBJ_NONE) 2200 return (obj_id); 2201 } while (obj_id > OBJ_NONE); 2202 2203 return (obj_id); 2204 } 2205 2206 static raid_obj_id_t 2207 obj_get_controller(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2208 { 2209 raid_obj_id_t id = obj_id; 2210 2211 while (raid_obj_get_type(raid_tab, id) != OBJ_TYPE_CONTROLLER) { 2212 id = raid_obj_get_container(raid_tab, id); 2213 if ((id == OBJ_SYSTEM) || (id < OBJ_NONE)) 2214 return (ERR_DEVICE_INVALID); 2215 } 2216 2217 return (id); 2218 } 2219 2220 /* 2221 * Raid object operation routines 2222 */ 2223 static int 2224 obj_sys_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2225 raid_obj_type_id_t comp_type) 2226 { 2227 DIR *dir; 2228 struct dirent *dp; 2229 int num = 0; 2230 2231 if ((raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_SYSTEM)) 2232 return (ERR_DEVICE_TYPE); 2233 2234 if (comp_type != OBJ_TYPE_CONTROLLER) 2235 return (0); 2236 2237 if ((dir = opendir(CFGDIR)) == NULL) 2238 return (ERR_DRIVER_NOT_FOUND); 2239 2240 while ((dp = readdir(dir)) != NULL) { 2241 uint32_t controller_id; 2242 char path[MAX_PATH_LEN]; 2243 2244 if (strcmp(dp->d_name, ".") == 0 || 2245 strcmp(dp->d_name, "..") == 0) 2246 continue; 2247 2248 if (sscanf(dp->d_name, "c%u", &controller_id) != 1) 2249 continue; 2250 2251 if (controller_id_to_path(controller_id, path) == SUCCESS) 2252 ++ num; 2253 } 2254 2255 (void) closedir(dir); 2256 return (num); 2257 } 2258 2259 static int 2260 obj_sys_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2261 int num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2262 { 2263 DIR *dir; 2264 struct dirent *dp; 2265 controller_attr_t *attr; 2266 uint32_t controller_id; 2267 uint32_t *tmplist; 2268 char path[MAX_PATH_LEN]; 2269 int i = 0; 2270 2271 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_SYSTEM) 2272 return (ERR_DEVICE_TYPE); 2273 if ((num <= 0) || (comp_list == NULL)) 2274 return (ERR_OP_ILLEGAL); 2275 2276 if (comp_type != OBJ_TYPE_CONTROLLER) 2277 return (0); 2278 2279 if ((dir = opendir(CFGDIR)) == NULL) 2280 return (ERR_DRIVER_NOT_FOUND); 2281 tmplist = calloc(num, sizeof (uint32_t)); 2282 if (tmplist == NULL) { 2283 return (ERR_NOMEM); 2284 } 2285 while ((dp = readdir(dir)) != NULL) { 2286 if (strcmp(dp->d_name, ".") == 0 || 2287 strcmp(dp->d_name, "..") == 0) 2288 continue; 2289 2290 if (sscanf(dp->d_name, "c%u", &controller_id) != 1) 2291 continue; 2292 2293 if (controller_id_to_path(controller_id, path) == SUCCESS) { 2294 tmplist[i] = controller_id; 2295 ++ i; 2296 } 2297 } 2298 qsort((void *)tmplist, num, sizeof (uint32_t), intcompare); 2299 for (i = 0; i < num; i++) { 2300 attr = raid_obj_get_data_ptr(raid_tab, 2301 *(comp_list + i)); 2302 2303 if (attr == NULL) { 2304 free(tmplist); 2305 return (ERR_DEVICE_INVALID); 2306 } 2307 2308 attr->controller_id = tmplist[i]; 2309 } 2310 free(tmplist); 2311 (void) closedir(dir); 2312 return (SUCCESS); 2313 } 2314 2315 static int 2316 obj_controller_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2317 raid_obj_type_id_t comp_type) 2318 { 2319 raid_lib_t *raid_lib; 2320 int ret = SUCCESS, fd; 2321 controller_attr_t *ctl_attrp; 2322 2323 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2324 return (ERR_DEVICE_TYPE); 2325 2326 if ((comp_type != OBJ_TYPE_ARRAY) && (comp_type != OBJ_TYPE_DISK)) 2327 return (0); 2328 2329 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2330 fd = raid_obj_get_fd(raid_tab, obj_id); 2331 ctl_attrp = raid_obj_get_data_ptr(raid_tab, obj_id); 2332 if ((raid_lib == NULL) || (ctl_attrp == NULL) || (fd == 0)) 2333 return (ERR_DRIVER_CLOSED); 2334 2335 ret = raid_lib->compnum(ctl_attrp->controller_id, 0, 2336 OBJ_TYPE_CONTROLLER, comp_type); 2337 2338 return (ret); 2339 } 2340 2341 static int 2342 obj_controller_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2343 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2344 { 2345 raid_lib_t *raid_lib; 2346 controller_attr_t *ctl_attrp; 2347 int ret, i, fd; 2348 uint32_t *ids; 2349 2350 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2351 return (ERR_DEVICE_TYPE); 2352 2353 if ((comp_type != OBJ_TYPE_ARRAY) && (comp_type != OBJ_TYPE_DISK)) 2354 return (0); 2355 2356 if ((comp_num <= 0) || (comp_list == NULL)) 2357 return (ERR_OP_ILLEGAL); 2358 2359 for (i = 0; i < comp_num; ++i) 2360 if (raid_obj_get_type(raid_tab, *(comp_list + i)) != 2361 comp_type) 2362 return (ERR_DEVICE_TYPE); 2363 2364 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2365 ctl_attrp = raid_obj_get_data_ptr(raid_tab, obj_id); 2366 fd = raid_obj_get_fd(raid_tab, obj_id); 2367 if ((raid_lib == NULL) || (ctl_attrp == NULL)|| (fd == 0)) 2368 return (ERR_DRIVER_CLOSED); 2369 2370 ids = malloc(comp_num * sizeof (uint32_t)); 2371 if (ids == NULL) 2372 return (ERR_NOMEM); 2373 2374 ret = raid_lib->complist(ctl_attrp->controller_id, 0, 2375 OBJ_TYPE_CONTROLLER, comp_type, comp_num, ids); 2376 if (ret < SUCCESS) { 2377 free(ids); 2378 return (ret); 2379 } 2380 qsort((void *)ids, comp_num, sizeof (uint32_t), intcompare); 2381 for (i = 0; i < comp_num; ++ i) { 2382 array_attr_t *array_attr; 2383 disk_attr_t *disk_attr; 2384 void *attr_buf; 2385 2386 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i)); 2387 if (attr_buf == NULL) { 2388 free(ids); 2389 return (ERR_DEVICE_INVALID); 2390 } 2391 2392 switch (comp_type) { 2393 case OBJ_TYPE_ARRAY: 2394 array_attr = attr_buf; 2395 array_attr->array_id = *(ids + i); 2396 break; 2397 case OBJ_TYPE_DISK: 2398 disk_attr = attr_buf; 2399 disk_attr->disk_id = *(ids + i); 2400 break; 2401 default: 2402 free(ids); 2403 return (ERR_DEVICE_INVALID); 2404 } 2405 } 2406 2407 free(ids); 2408 return (SUCCESS); 2409 } 2410 2411 static int 2412 obj_controller_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2413 { 2414 controller_attr_t *attr; 2415 raid_lib_t *raid_lib; 2416 int ret = SUCCESS, fd; 2417 2418 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2419 return (ERR_DEVICE_TYPE); 2420 2421 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 2422 return (SUCCESS); 2423 2424 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2425 if (attr == NULL) 2426 return (ERR_DEVICE_INVALID); 2427 2428 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2429 fd = raid_obj_get_fd(raid_tab, obj_id); 2430 2431 /* 2432 * For a controller, even it's not opened, we can still 2433 * get the driver name 2434 */ 2435 2436 if (fd == 0) 2437 return (SUCCESS); 2438 2439 if (raid_lib == NULL) { 2440 return (SUCCESS); 2441 } 2442 2443 ret = raid_lib->get_attr(attr->controller_id, OBJ_ATTR_NONE, 2444 OBJ_ATTR_NONE, OBJ_TYPE_CONTROLLER, attr); 2445 if (ret < SUCCESS) 2446 return (ret); 2447 2448 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 2449 2450 return (ret); 2451 } 2452 2453 static int 2454 obj_controller_act(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2455 uint32_t sub_cmd, void *prop_list, char **plugin_err_str) 2456 { 2457 controller_attr_t *attr; 2458 raid_lib_t *raid_lib; 2459 int ret, fd; 2460 2461 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2462 return (ERR_DEVICE_TYPE); 2463 2464 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2465 2466 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2467 fd = raid_obj_get_fd(raid_tab, obj_id); 2468 2469 switch (sub_cmd) { 2470 case ACT_CONTROLLER_OPEN: 2471 /* Check if already opened */ 2472 2473 if (fd > 0) 2474 return (SUCCESS); 2475 2476 /* Check if plugin is already attached */ 2477 if (raid_lib == NULL) { 2478 raid_lib = raid_find_lib(raid_tab, obj_id); 2479 if (raid_lib == NULL) 2480 return (ERR_DRIVER_NOT_FOUND); 2481 } 2482 2483 ret = raid_lib->open_controller(attr->controller_id, 2484 plugin_err_str); 2485 if (ret == SUCCESS) { 2486 (void) raid_obj_set_lib(raid_tab, obj_id, raid_lib); 2487 (void) raid_obj_set_fd(raid_tab, obj_id, 1); 2488 } 2489 break; 2490 case ACT_CONTROLLER_CLOSE: 2491 2492 if (fd <= 0) 2493 return (SUCCESS); 2494 2495 if (raid_lib == NULL) { 2496 return (SUCCESS); 2497 } 2498 ret = raid_lib->close_controller(attr->controller_id, 2499 plugin_err_str); 2500 if (ret == SUCCESS) { 2501 (void) raid_obj_set_fd(raid_tab, obj_id, 0); 2502 (void) raid_obj_set_lib(raid_tab, obj_id, NULL); 2503 raid_handle_delete_controller_comp(attr->controller_id); 2504 } 2505 break; 2506 case ACT_CONTROLLER_FLASH_FW: 2507 { 2508 char *filebuf; 2509 int image_fd; 2510 uint32_t size; 2511 struct stat statbuf; 2512 2513 if (prop_list == NULL) 2514 return (ERR_OP_ILLEGAL); 2515 2516 /* Open firmware image file */ 2517 image_fd = open((const char *)prop_list, 2518 O_RDONLY | O_NDELAY); 2519 if (image_fd == -1) 2520 return (ERR_OP_FAILED); 2521 2522 if (fstat(image_fd, &statbuf) != 0) { 2523 (void) close(image_fd); 2524 return (ERR_OP_FAILED); 2525 } 2526 2527 filebuf = malloc(statbuf.st_size); 2528 if (filebuf == NULL) { 2529 (void) close(image_fd); 2530 return (ERR_NOMEM); 2531 } 2532 2533 size = read(image_fd, filebuf, statbuf.st_size); 2534 if (size != statbuf.st_size) { 2535 (void) close(image_fd); 2536 free(filebuf); 2537 return (ERR_OP_FAILED); 2538 } 2539 2540 if (fd <= 0) { 2541 (void) close(image_fd); 2542 free(filebuf); 2543 return (ERR_DRIVER_CLOSED); 2544 } 2545 2546 if (raid_lib == NULL) { 2547 (void) close(image_fd); 2548 free(filebuf); 2549 return (ERR_DRIVER_CLOSED); 2550 } 2551 if (raid_lib->flash_fw == NULL) { 2552 (void) close(image_fd); 2553 free(filebuf); 2554 return (ERR_OP_NO_IMPL); 2555 } 2556 2557 ret = raid_lib->flash_fw(attr->controller_id, 2558 filebuf, size, plugin_err_str); 2559 } 2560 break; 2561 default: 2562 return (ERR_OP_ILLEGAL); 2563 } 2564 2565 return (ret); 2566 } 2567 2568 static int 2569 obj_array_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2570 raid_obj_type_id_t comp_type) 2571 { 2572 array_attr_t *attr; 2573 controller_attr_t *ctl_attrp; 2574 raid_obj_id_t controller_obj_id; 2575 raid_lib_t *raid_lib; 2576 int ret = SUCCESS, fd; 2577 2578 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2579 return (ERR_DEVICE_TYPE); 2580 2581 if (comp_type != OBJ_TYPE_ARRAY_PART && 2582 comp_type != OBJ_TYPE_ARRAY && 2583 comp_type != OBJ_TYPE_TASK) 2584 return (0); 2585 2586 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2587 if (attr == NULL) 2588 return (ERR_DEVICE_INVALID); 2589 2590 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2591 if (controller_obj_id < OBJ_NONE) 2592 return (ERR_DEVICE_INVALID); 2593 2594 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2595 if (ctl_attrp == NULL) { 2596 return (ERR_DEVICE_INVALID); 2597 } 2598 2599 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2600 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2601 if ((raid_lib == NULL) || (fd == 0)) 2602 return (ERR_DRIVER_CLOSED); 2603 2604 ret = raid_lib->compnum(ctl_attrp->controller_id, attr->array_id, 2605 OBJ_TYPE_ARRAY, comp_type); 2606 2607 return (ret); 2608 } 2609 2610 static int 2611 obj_array_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2612 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2613 { 2614 array_attr_t *attr; 2615 controller_attr_t *ctl_attrp; 2616 raid_obj_id_t controller_obj_id; 2617 raid_lib_t *raid_lib; 2618 int ret, i, fd; 2619 uint32_t *ids; 2620 2621 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2622 return (ERR_DEVICE_TYPE); 2623 2624 if (comp_type != OBJ_TYPE_ARRAY_PART && 2625 comp_type != OBJ_TYPE_ARRAY && 2626 comp_type != OBJ_TYPE_TASK) 2627 return (0); 2628 2629 if (comp_num <= 0 || comp_list == NULL) 2630 return (ERR_OP_ILLEGAL); 2631 2632 for (i = 0; i < comp_num; ++i) 2633 if (raid_obj_get_type(raid_tab, *(comp_list + i)) != 2634 comp_type) 2635 return (ERR_DEVICE_TYPE); 2636 2637 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2638 if (attr == NULL) 2639 return (ERR_DEVICE_INVALID); 2640 2641 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2642 if (controller_obj_id < OBJ_NONE) 2643 return (ERR_DEVICE_INVALID); 2644 2645 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2646 if (ctl_attrp == NULL) { 2647 return (ERR_DEVICE_INVALID); 2648 } 2649 2650 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2651 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2652 if ((raid_lib == NULL) || (fd == 0)) 2653 return (ERR_DRIVER_CLOSED); 2654 2655 ids = malloc(comp_num * sizeof (uint32_t)); 2656 if (ids == NULL) 2657 return (ERR_NOMEM); 2658 2659 ret = raid_lib->complist(ctl_attrp->controller_id, 2660 attr->array_id, OBJ_TYPE_ARRAY, comp_type, comp_num, ids); 2661 2662 if (ret < SUCCESS) { 2663 free(ids); 2664 return (ret); 2665 } 2666 2667 for (i = 0; i < comp_num; ++ i) { 2668 array_attr_t *array_attr; 2669 arraypart_attr_t *arraypart_attr; 2670 task_attr_t *task_attr; 2671 void *attr_buf; 2672 2673 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i)); 2674 if (attr_buf == NULL) { 2675 free(ids); 2676 return (ERR_DEVICE_INVALID); 2677 } 2678 2679 switch (comp_type) { 2680 case OBJ_TYPE_ARRAY: 2681 array_attr = attr_buf; 2682 array_attr->array_id = *(ids + i); 2683 break; 2684 case OBJ_TYPE_ARRAY_PART: 2685 arraypart_attr = attr_buf; 2686 arraypart_attr->disk_id = *(ids + i); 2687 break; 2688 case OBJ_TYPE_TASK: 2689 task_attr = attr_buf; 2690 task_attr->task_id = *(ids + i); 2691 break; 2692 default: 2693 free(ids); 2694 return (ERR_DEVICE_INVALID); 2695 } 2696 } 2697 2698 2699 free(ids); 2700 return (ret); 2701 } 2702 2703 static int 2704 obj_array_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2705 { 2706 array_attr_t *attr; 2707 controller_attr_t *ctl_attrp; 2708 raid_lib_t *raid_lib; 2709 int ret = SUCCESS, fd; 2710 raid_obj_id_t controller_obj_id; 2711 2712 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2713 return (ERR_DEVICE_TYPE); 2714 2715 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 2716 return (SUCCESS); 2717 2718 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2719 if (attr == NULL) 2720 return (ERR_DEVICE_INVALID); 2721 2722 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2723 if (controller_obj_id < OBJ_NONE) 2724 return (ERR_DEVICE_INVALID); 2725 2726 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2727 if (ctl_attrp == NULL) { 2728 return (ERR_DEVICE_INVALID); 2729 } 2730 2731 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2732 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2733 if ((raid_lib == NULL) || (fd == 0)) 2734 return (ERR_DRIVER_CLOSED); 2735 2736 ret = raid_lib->get_attr(ctl_attrp->controller_id, 2737 attr->array_id, 0, OBJ_TYPE_ARRAY, attr); 2738 2739 if (ret < SUCCESS) 2740 return (ret); 2741 2742 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 2743 2744 return (ret); 2745 } 2746 2747 static int 2748 obj_array_set_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2749 uint32_t sub_cmd, uint32_t *value, char **plugin_err_str) 2750 { 2751 array_attr_t *attr; 2752 controller_attr_t *ctl_attrp; 2753 raid_lib_t *raid_lib; 2754 int ret = SUCCESS, fd; 2755 raid_obj_id_t controller_obj_id; 2756 2757 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2758 return (ERR_DEVICE_TYPE); 2759 2760 switch (sub_cmd) { 2761 case SET_CACHE_WR_PLY: 2762 if (*value != CACHE_WR_OFF && 2763 *value != CACHE_WR_ON) 2764 return (ERR_OP_ILLEGAL); 2765 break; 2766 case SET_CACHE_RD_PLY: 2767 if (*value != CACHE_RD_OFF && 2768 *value != CACHE_RD_ON) 2769 return (ERR_OP_ILLEGAL); 2770 break; 2771 case SET_ACTIVATION_PLY: 2772 if (*value != ARRAY_ACT_ACTIVATE) 2773 return (ERR_OP_ILLEGAL); 2774 break; 2775 default: 2776 return (ERR_OP_ILLEGAL); 2777 } 2778 2779 (void) obj_get_attr(raid_tab, obj_id, (void **)(&attr)); 2780 2781 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2782 if (controller_obj_id < OBJ_NONE) 2783 return (ERR_DEVICE_INVALID); 2784 2785 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2786 if (ctl_attrp == NULL) { 2787 return (ERR_DEVICE_INVALID); 2788 } 2789 2790 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2791 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2792 if ((raid_lib == NULL) || (fd == 0)) 2793 return (ERR_DRIVER_CLOSED); 2794 2795 if (raid_lib->set_attr == NULL) 2796 return (ERR_OP_NO_IMPL); 2797 2798 ret = raid_lib->set_attr(ctl_attrp->controller_id, 2799 attr->array_id, sub_cmd, value, plugin_err_str); 2800 2801 return (ret); 2802 } 2803 2804 static int 2805 obj_disk_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2806 raid_obj_type_id_t comp_type) 2807 { 2808 disk_attr_t *attr; 2809 controller_attr_t *ctl_attrp; 2810 raid_obj_id_t controller_obj_id; 2811 raid_lib_t *raid_lib; 2812 int ret = SUCCESS, fd; 2813 2814 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK) 2815 return (ERR_DEVICE_TYPE); 2816 2817 if (comp_type != OBJ_TYPE_DISK_SEG && 2818 comp_type != OBJ_TYPE_HSP && 2819 comp_type != OBJ_TYPE_TASK && 2820 comp_type != OBJ_TYPE_PROP) 2821 return (0); 2822 ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr)); 2823 if ((ret != SUCCESS) || (attr == NULL)) { 2824 return (ERR_DEVICE_INVALID); 2825 } 2826 if (attr->state == DISK_STATE_FAILED) { 2827 return (SUCCESS); 2828 } 2829 2830 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2831 if (controller_obj_id < OBJ_NONE) 2832 return (ERR_DEVICE_INVALID); 2833 2834 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2835 if (ctl_attrp == NULL) { 2836 return (ERR_DEVICE_INVALID); 2837 } 2838 2839 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2840 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2841 if ((raid_lib == NULL) || (fd == 0)) 2842 return (ERR_DRIVER_CLOSED); 2843 2844 ret = raid_lib->compnum(ctl_attrp->controller_id, 2845 attr->disk_id, OBJ_TYPE_DISK, comp_type); 2846 2847 return (ret); 2848 } 2849 2850 static int 2851 obj_disk_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2852 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2853 { 2854 disk_attr_t *attr; 2855 controller_attr_t *ctl_attrp; 2856 raid_obj_id_t controller_obj_id; 2857 raid_lib_t *raid_lib; 2858 int ret, i, fd; 2859 uint32_t *ids; 2860 2861 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK) 2862 return (ERR_DEVICE_TYPE); 2863 2864 if (comp_type != OBJ_TYPE_DISK_SEG && 2865 comp_type != OBJ_TYPE_HSP && 2866 comp_type != OBJ_TYPE_TASK && 2867 comp_type != OBJ_TYPE_PROP) 2868 return (0); 2869 2870 if (comp_num <= 0 || comp_list == NULL) 2871 return (ERR_OP_ILLEGAL); 2872 2873 for (i = 0; i < comp_num; ++i) 2874 if (raid_obj_get_type(raid_tab, *(comp_list + i)) != 2875 comp_type) 2876 return (ERR_DEVICE_TYPE); 2877 ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr)); 2878 if ((ret != SUCCESS) || (attr == NULL)) { 2879 return (ERR_DEVICE_INVALID); 2880 } 2881 if (attr->state == DISK_STATE_FAILED) { 2882 return (SUCCESS); 2883 } 2884 2885 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2886 if (controller_obj_id < OBJ_NONE) 2887 return (ERR_DEVICE_INVALID); 2888 2889 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2890 if (ctl_attrp == NULL) { 2891 return (ERR_DEVICE_INVALID); 2892 } 2893 2894 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2895 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2896 if ((raid_lib == NULL) || (fd == 0)) 2897 return (ERR_DRIVER_CLOSED); 2898 2899 ids = malloc(comp_num * sizeof (uint32_t)); 2900 if (ids == NULL) 2901 return (ERR_NOMEM); 2902 2903 ret = raid_lib->complist(ctl_attrp->controller_id, 2904 attr->disk_id, OBJ_TYPE_DISK, comp_type, comp_num, ids); 2905 2906 if (ret < SUCCESS) { 2907 free(ids); 2908 return (ret); 2909 } 2910 2911 for (i = 0; i < comp_num; ++ i) { 2912 diskseg_attr_t *diskseg_attr; 2913 hsp_attr_t *hsp_attr; 2914 task_attr_t *task_attr; 2915 property_attr_t *prop_attr; 2916 void *attr_buf; 2917 2918 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i)); 2919 if (attr_buf == NULL) { 2920 free(ids); 2921 return (ERR_DEVICE_INVALID); 2922 } 2923 2924 switch (comp_type) { 2925 case OBJ_TYPE_DISK_SEG: 2926 diskseg_attr = attr_buf; 2927 diskseg_attr->seq_no = *(ids + i); 2928 break; 2929 case OBJ_TYPE_HSP: 2930 hsp_attr = attr_buf; 2931 hsp_attr->associated_id = *(ids + i); 2932 break; 2933 case OBJ_TYPE_TASK: 2934 task_attr = attr_buf; 2935 task_attr->task_id = *(ids + i); 2936 break; 2937 case OBJ_TYPE_PROP: 2938 prop_attr = attr_buf; 2939 prop_attr->prop_id = *(ids + i); 2940 break; 2941 default: 2942 free(ids); 2943 return (ERR_DEVICE_INVALID); 2944 } 2945 } 2946 2947 2948 free(ids); 2949 return (ret); 2950 } 2951 2952 static int 2953 obj_disk_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2954 { 2955 disk_attr_t *attr; 2956 controller_attr_t *ctl_attrp; 2957 raid_lib_t *raid_lib; 2958 int ret = SUCCESS, fd; 2959 raid_obj_id_t controller_obj_id; 2960 2961 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK) 2962 return (ERR_DEVICE_TYPE); 2963 2964 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 2965 return (SUCCESS); 2966 2967 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2968 if (attr == NULL) 2969 return (ERR_DEVICE_INVALID); 2970 2971 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2972 if (controller_obj_id < OBJ_NONE) 2973 return (ERR_DEVICE_INVALID); 2974 2975 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2976 if (ctl_attrp == NULL) { 2977 return (ERR_DEVICE_INVALID); 2978 } 2979 2980 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2981 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2982 if ((raid_lib == NULL) || (fd == 0)) 2983 return (ERR_DRIVER_CLOSED); 2984 2985 ret = raid_lib->get_attr(ctl_attrp->controller_id, 2986 attr->disk_id, 0, OBJ_TYPE_DISK, attr); 2987 2988 if (ret < SUCCESS) 2989 return (ret); 2990 2991 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 2992 2993 return (ret); 2994 } 2995 2996 static int 2997 obj_hsp_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2998 { 2999 hsp_attr_t *attr; 3000 3001 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_HSP) 3002 return (ERR_DEVICE_TYPE); 3003 3004 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3005 return (SUCCESS); 3006 3007 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3008 if (attr == NULL) 3009 return (ERR_DEVICE_INVALID); 3010 3011 if (attr->associated_id == (uint32_t)OBJ_ATTR_NONE) 3012 attr->type = HSP_TYPE_GLOBAL; 3013 else 3014 attr->type = HSP_TYPE_LOCAL; 3015 3016 return (SUCCESS); 3017 } 3018 3019 static int 3020 obj_arraypart_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3021 { 3022 arraypart_attr_t *attr; 3023 array_attr_t *array_attr; 3024 controller_attr_t *ctl_attrp; 3025 raid_lib_t *raid_lib; 3026 int ret = SUCCESS, fd; 3027 raid_obj_id_t controller_obj_id, array_obj_id; 3028 3029 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY_PART) 3030 return (ERR_DEVICE_TYPE); 3031 3032 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3033 return (SUCCESS); 3034 3035 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3036 if (attr == NULL) 3037 return (ERR_DEVICE_INVALID); 3038 3039 array_obj_id = raid_obj_get_container(raid_tab, obj_id); 3040 if (array_obj_id < OBJ_NONE) 3041 return (ERR_DEVICE_INVALID); 3042 3043 array_attr = raid_obj_get_data_ptr(raid_tab, array_obj_id); 3044 if (array_attr == NULL) 3045 return (ERR_DEVICE_INVALID); 3046 3047 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3048 if (controller_obj_id < OBJ_NONE) 3049 return (ERR_DEVICE_INVALID); 3050 3051 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3052 if (ctl_attrp == NULL) { 3053 return (ERR_DEVICE_INVALID); 3054 } 3055 3056 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3057 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3058 if ((raid_lib == NULL) || (fd == 0)) 3059 return (ERR_DRIVER_CLOSED); 3060 3061 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3062 array_attr->array_id, attr->disk_id, 3063 OBJ_TYPE_ARRAY_PART, attr); 3064 3065 if (ret < SUCCESS) 3066 return (ret); 3067 3068 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 3069 3070 return (ret); 3071 } 3072 3073 static int 3074 obj_diskseg_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3075 { 3076 diskseg_attr_t *attr; 3077 disk_attr_t *disk_attr; 3078 controller_attr_t *ctl_attrp; 3079 raid_lib_t *raid_lib; 3080 int ret = SUCCESS, fd; 3081 raid_obj_id_t controller_obj_id, disk_obj_id; 3082 3083 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK_SEG) 3084 return (ERR_DEVICE_TYPE); 3085 3086 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3087 return (SUCCESS); 3088 3089 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3090 if (attr == NULL) 3091 return (ERR_DEVICE_INVALID); 3092 3093 disk_obj_id = raid_obj_get_container(raid_tab, obj_id); 3094 if (disk_obj_id < OBJ_NONE) 3095 return (ERR_DEVICE_INVALID); 3096 3097 disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id); 3098 if (disk_attr == NULL) 3099 return (ERR_DEVICE_INVALID); 3100 3101 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3102 if (controller_obj_id < OBJ_NONE) 3103 return (ERR_DEVICE_INVALID); 3104 3105 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3106 if (ctl_attrp == NULL) { 3107 return (ERR_DEVICE_INVALID); 3108 } 3109 3110 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3111 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3112 if ((raid_lib == NULL) || (fd == 0)) 3113 return (ERR_DRIVER_CLOSED); 3114 3115 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3116 disk_attr->disk_id, attr->seq_no, OBJ_TYPE_DISK_SEG, attr); 3117 3118 if (ret < SUCCESS) 3119 return (ret); 3120 3121 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 3122 3123 return (ret); 3124 } 3125 3126 static int 3127 obj_task_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3128 { 3129 task_attr_t *attr; 3130 controller_attr_t *ctl_attrp; 3131 raid_lib_t *raid_lib; 3132 int ret = SUCCESS, fd; 3133 raid_obj_id_t controller_obj_id; 3134 3135 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_TASK) 3136 return (ERR_DEVICE_TYPE); 3137 3138 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3139 if (attr == NULL) 3140 return (ERR_DEVICE_INVALID); 3141 3142 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3143 if (controller_obj_id < OBJ_NONE) 3144 return (ERR_DEVICE_INVALID); 3145 3146 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3147 if (ctl_attrp == NULL) { 3148 return (ERR_DEVICE_INVALID); 3149 } 3150 3151 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3152 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3153 if ((raid_lib == NULL) || (fd == 0)) 3154 return (ERR_DRIVER_CLOSED); 3155 3156 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3157 attr->task_id, OBJ_ATTR_NONE, OBJ_TYPE_TASK, attr); 3158 3159 return (ret); 3160 } 3161 3162 static int 3163 obj_prop_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3164 { 3165 property_attr_t *attr, *attr_new; 3166 disk_attr_t *disk_attr; 3167 controller_attr_t *ctl_attrp; 3168 raid_lib_t *raid_lib; 3169 int ret = SUCCESS, fd; 3170 raid_obj_id_t controller_obj_id, disk_obj_id; 3171 3172 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_PROP) 3173 return (ERR_DEVICE_TYPE); 3174 3175 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3176 return (SUCCESS); 3177 3178 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3179 if (attr == NULL) 3180 return (ERR_DEVICE_INVALID); 3181 3182 disk_obj_id = raid_obj_get_container(raid_tab, obj_id); 3183 if (disk_obj_id < OBJ_NONE) 3184 return (ERR_DEVICE_INVALID); 3185 3186 disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id); 3187 if (disk_attr == NULL) 3188 return (ERR_DEVICE_INVALID); 3189 3190 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3191 if (controller_obj_id < OBJ_NONE) 3192 return (ERR_DEVICE_INVALID); 3193 3194 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3195 if (ctl_attrp == NULL) { 3196 return (ERR_DEVICE_INVALID); 3197 } 3198 3199 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3200 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3201 if ((raid_lib == NULL) || (fd == 0)) 3202 return (ERR_DRIVER_CLOSED); 3203 3204 /* Get the property size at first */ 3205 attr->prop_size = 0; 3206 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3207 disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr); 3208 3209 if (ret < SUCCESS) 3210 return (ret); 3211 3212 /* Allocate memory for property and fill the buffer */ 3213 attr_new = realloc(attr, sizeof (property_attr_t) + attr->prop_size); 3214 if (attr_new == NULL) 3215 return (ERR_NOMEM); 3216 3217 (void) raid_obj_set_data_ptr(raid_tab, obj_id, attr_new); 3218 3219 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3220 disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr_new); 3221 3222 if (ret < SUCCESS) 3223 return (ret); 3224 3225 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 3226 3227 return (ret); 3228 } 3229 3230 static int 3231 obj_array_create(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id, 3232 int num_of_comp, raid_obj_id_t *disk_list, char **plugin_err_str) 3233 { 3234 controller_attr_t *controller_attr; 3235 array_attr_t *array_attr, array_attr2; 3236 disk_attr_t *disk_attr; 3237 arraypart_attr_t *arraypart_attrs; 3238 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE; 3239 raid_lib_t *raid_lib; 3240 int i, j, ret, fd; 3241 int disk_cnt = 0, disk_set_num = 0, set_num = 0, layer_cnt = 0; 3242 uint64_t min_disk_capacity = 0; 3243 3244 array_attr = raid_obj_get_data_ptr(raid_tab, array_obj_id); 3245 if (array_attr == NULL) 3246 return (ERR_DEVICE_INVALID); 3247 3248 /* Check the disk layout expression */ 3249 if (disk_list[0] != OBJ_SEPARATOR_BEGIN || 3250 disk_list[num_of_comp - 1] != OBJ_SEPARATOR_END) 3251 return (ERR_ARRAY_LAYOUT); 3252 for (i = 0; i < num_of_comp; ++i) { 3253 if (disk_list[i] == OBJ_SEPARATOR_BEGIN) { 3254 if (disk_cnt != 0) 3255 return (ERR_ARRAY_LAYOUT); 3256 ++layer_cnt; 3257 continue; 3258 } 3259 if (disk_list[i] == OBJ_SEPARATOR_END) { 3260 if (disk_set_num == 0) 3261 disk_set_num = disk_cnt; 3262 else if (disk_set_num != disk_cnt && disk_cnt != 0) 3263 return (ERR_ARRAY_LAYOUT); 3264 disk_cnt = 0; 3265 ++set_num; 3266 --layer_cnt; 3267 continue; 3268 } 3269 switch (array_attr->raid_level) { 3270 case RAID_LEVEL_0: 3271 case RAID_LEVEL_1: 3272 case RAID_LEVEL_1E: 3273 case RAID_LEVEL_5: 3274 if (layer_cnt != 1) 3275 return (ERR_ARRAY_LAYOUT); 3276 break; 3277 case RAID_LEVEL_10: 3278 case RAID_LEVEL_50: 3279 if (layer_cnt != 2) 3280 return (ERR_ARRAY_LAYOUT); 3281 break; 3282 default: 3283 return (ERR_ARRAY_LEVEL); 3284 } 3285 ++disk_cnt; 3286 } 3287 3288 if (layer_cnt != 0) 3289 return (ERR_ARRAY_LAYOUT); 3290 3291 switch (array_attr->raid_level) { 3292 case RAID_LEVEL_0: 3293 if (disk_set_num < 2 || set_num != 1) 3294 return (ERR_ARRAY_LAYOUT); 3295 break; 3296 case RAID_LEVEL_1: 3297 if (disk_set_num != 2 || set_num != 1) 3298 return (ERR_ARRAY_LAYOUT); 3299 break; 3300 case RAID_LEVEL_1E: 3301 case RAID_LEVEL_5: 3302 if (disk_set_num < 3 || set_num != 1) 3303 return (ERR_ARRAY_LAYOUT); 3304 break; 3305 case RAID_LEVEL_10: 3306 if (disk_set_num != 2 || set_num < 2) 3307 return (ERR_ARRAY_LAYOUT); 3308 break; 3309 case RAID_LEVEL_50: 3310 if (disk_set_num < 3 || set_num < 2) 3311 return (ERR_ARRAY_LAYOUT); 3312 break; 3313 default: 3314 return (ERR_ARRAY_LEVEL); 3315 } 3316 3317 arraypart_attrs = calloc(num_of_comp, sizeof (arraypart_attr_t)); 3318 if (arraypart_attrs == NULL) 3319 return (ERR_NOMEM); 3320 3321 for (i = 0; i < num_of_comp; ++i) { 3322 /* Keep seperators */ 3323 if (*(disk_list + i) == OBJ_SEPARATOR_BEGIN) { 3324 arraypart_attrs[i].disk_id = 3325 (uint32_t)OBJ_SEPARATOR_BEGIN; 3326 continue; 3327 } 3328 3329 if (*(disk_list + i) == OBJ_SEPARATOR_END) { 3330 arraypart_attrs[i].disk_id = 3331 (uint32_t)OBJ_SEPARATOR_END; 3332 continue; 3333 } 3334 3335 disk_cnt++; 3336 /* Check if it's a disk */ 3337 if (raid_obj_get_type(raid_tab, *(disk_list + i)) != 3338 OBJ_TYPE_DISK) 3339 return (ERR_DEVICE_TYPE); 3340 3341 /* Check if it's duplicated with other disks */ 3342 for (j = 0; j < i; ++j) 3343 if (*(disk_list + j) == *(disk_list + i)) { 3344 free(arraypart_attrs); 3345 return (ERR_DEVICE_DUP); 3346 } 3347 3348 /* Check disk status */ 3349 ret = obj_get_attr(raid_tab, *(disk_list + i), 3350 (void **)(&disk_attr)); 3351 if (ret != SUCCESS) 3352 return (ret); 3353 3354 if (disk_attr->state != DISK_STATE_GOOD) { 3355 free(arraypart_attrs); 3356 return (ERR_DISK_STATE); 3357 } 3358 3359 /* All disks must belong to the same controller */ 3360 obj_id = obj_get_controller(raid_tab, *(disk_list + i)); 3361 if (obj_id <= OBJ_NONE) 3362 return (obj_id); 3363 if (controller_obj_id == OBJ_NONE) { 3364 controller_obj_id = obj_id; 3365 ret = obj_get_attr(raid_tab, controller_obj_id, 3366 (void **)(&controller_attr)); 3367 } else if (obj_id != controller_obj_id) { 3368 free(arraypart_attrs); 3369 return (ERR_DRIVER_ACROSS); 3370 } 3371 3372 /* Check if the disk contains too many segments */ 3373 obj_id = obj_get_comp(raid_tab, *(disk_list + i), 3374 OBJ_TYPE_DISK_SEG); 3375 j = 0; 3376 while (obj_id > OBJ_NONE) { 3377 ++j; 3378 obj_id = obj_get_sibling(raid_tab, obj_id); 3379 } 3380 if (j > controller_attr->max_seg_per_disk) { 3381 free(arraypart_attrs); 3382 return (ERR_DISK_SEG_AMOUNT); 3383 } 3384 3385 /* Check if controller is a hostraid controller */ 3386 if (controller_attr->capability & RAID_CAP_DISK_TRANS) { 3387 /* 3388 * For hostraid, the first disk should 3389 * be with of minimum capacity 3390 */ 3391 if (min_disk_capacity == 0) { 3392 min_disk_capacity = disk_attr->capacity; 3393 3394 /* Can not specify capacity for hostraid */ 3395 if (array_attr->capacity != 0) { 3396 free(arraypart_attrs); 3397 return (ERR_OP_ILLEGAL); 3398 } 3399 } else if (min_disk_capacity > disk_attr->capacity) { 3400 free(arraypart_attrs); 3401 return (ERR_DISK_SPACE); 3402 } 3403 3404 /* Disk should not be used for hostraid */ 3405 obj_id = obj_get_comp(raid_tab, *(disk_list + i), 3406 OBJ_TYPE_DISK_SEG); 3407 if (obj_id < OBJ_NONE) { 3408 free(arraypart_attrs); 3409 return (obj_id); 3410 } else if (obj_id > OBJ_NONE) { 3411 free(arraypart_attrs); 3412 return (ERR_DISK_NOT_EMPTY); 3413 } 3414 } 3415 3416 arraypart_attrs[i].disk_id = disk_attr->disk_id; 3417 arraypart_attrs[i].offset = OBJ_ATTR_NONE; 3418 arraypart_attrs[i].size = OBJ_ATTR_NONE; 3419 } 3420 3421 /* Check if array amount exceeds limit */ 3422 if (controller_attr->max_array_num <= 3423 obj_controller_compnum(raid_tab, controller_obj_id, 3424 OBJ_TYPE_ARRAY)) 3425 return (ERR_ARRAY_AMOUNT); 3426 3427 3428 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3429 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3430 if ((raid_lib == NULL) || (fd == 0)) 3431 return (ERR_DRIVER_CLOSED); 3432 3433 /* Check if the controller can support the array RAID level */ 3434 switch (array_attr->raid_level) { 3435 case RAID_LEVEL_0: 3436 if (!(controller_attr->capability & RAID_CAP_RAID0)) { 3437 free(arraypart_attrs); 3438 return (ERR_ARRAY_LEVEL); 3439 } 3440 break; 3441 case RAID_LEVEL_1: 3442 if (!(controller_attr->capability & RAID_CAP_RAID1)) { 3443 free(arraypart_attrs); 3444 return (ERR_ARRAY_LEVEL); 3445 } 3446 break; 3447 case RAID_LEVEL_1E: 3448 if (!(controller_attr->capability & RAID_CAP_RAID1E)) { 3449 free(arraypart_attrs); 3450 return (ERR_ARRAY_LEVEL); 3451 } 3452 break; 3453 case RAID_LEVEL_5: 3454 if (!(controller_attr->capability & RAID_CAP_RAID5)) { 3455 free(arraypart_attrs); 3456 return (ERR_ARRAY_LEVEL); 3457 } 3458 break; 3459 case RAID_LEVEL_10: 3460 if (!(controller_attr->capability & RAID_CAP_RAID10)) { 3461 free(arraypart_attrs); 3462 return (ERR_ARRAY_LEVEL); 3463 } 3464 break; 3465 case RAID_LEVEL_50: 3466 if (!(controller_attr->capability & RAID_CAP_RAID50)) { 3467 free(arraypart_attrs); 3468 return (ERR_ARRAY_LEVEL); 3469 } 3470 break; 3471 default: 3472 free(arraypart_attrs); 3473 return (ERR_ARRAY_LEVEL); 3474 } 3475 3476 /* Check if plug in can calculate the maximum size */ 3477 (void) memcpy(&array_attr2, array_attr, sizeof (array_attr_t)); 3478 array_attr2.capacity = OBJ_ATTR_NONE; 3479 ret = raid_lib->array_create(controller_attr->controller_id, 3480 &array_attr2, num_of_comp, arraypart_attrs, plugin_err_str); 3481 3482 /* If plugin/driver will not calculate space */ 3483 if (ret == ERR_OP_NO_IMPL) { 3484 /* Calculate the maximum capacity */ 3485 array_attr2.capacity = raid_space_noalign(raid_tab, 3486 array_attr2.raid_level, num_of_comp, disk_list, 3487 arraypart_attrs); 3488 3489 /* 3490 * If controller is capable to allocate space, 3491 * set offset and size attributes to OBJ_ATTR_NONE 3492 * and let the controller to determine these value 3493 */ 3494 if (controller_attr->capability & RAID_CAP_SMART_ALLOC) 3495 for (i = 0; i < num_of_comp; ++i) { 3496 arraypart_attrs[i].offset = 3497 OBJ_ATTR_NONE; 3498 arraypart_attrs[i].size = 3499 OBJ_ATTR_NONE; 3500 } 3501 3502 /* There's no enough space for specified capacity */ 3503 if (array_attr->capacity > array_attr2.capacity) { 3504 free(arraypart_attrs); 3505 return (ERR_ARRAY_SIZE); 3506 } 3507 3508 /* capacity == 0, allocate maximum space */ 3509 if (array_attr->capacity == 0) 3510 array_attr->capacity = array_attr2.capacity; 3511 } else if (ret < SUCCESS) { 3512 free(arraypart_attrs); 3513 return (ret); 3514 } else if (array_attr2.capacity < array_attr->capacity) { 3515 /* Return the maximum size */ 3516 array_attr->capacity = array_attr2.capacity; 3517 free(arraypart_attrs); 3518 return (ERR_ARRAY_SIZE); 3519 } 3520 3521 if (array_attr->capacity < ARRAYPART_MIN_SIZE * disk_cnt) { 3522 free(arraypart_attrs); 3523 return (ERR_ARRAY_SIZE); 3524 } 3525 3526 3527 ret = raid_lib->array_create(controller_attr->controller_id, 3528 array_attr, num_of_comp, arraypart_attrs, plugin_err_str); 3529 free(arraypart_attrs); 3530 3531 if (ret != SUCCESS) 3532 return (ret); 3533 3534 /* Add array object into device tree so that we can map the handle */ 3535 (void) raid_obj_add_org(raid_tab, array_obj_id, controller_obj_id); 3536 3537 return (ret); 3538 } 3539 3540 static int 3541 obj_array_delete(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id, 3542 char **plugin_err_str) 3543 { 3544 raid_obj_id_t controller_obj_id; 3545 controller_attr_t *controller_attr; 3546 array_attr_t *array_attr; 3547 raid_lib_t *raid_lib; 3548 int ret, fd; 3549 uint32_t *disk_ids = NULL; 3550 3551 controller_obj_id = obj_get_controller(raid_tab, array_obj_id); 3552 if (controller_obj_id <= OBJ_NONE) 3553 return (controller_obj_id); 3554 3555 ret = obj_get_attr(raid_tab, controller_obj_id, 3556 (void **)(&controller_attr)); 3557 if (ret < SUCCESS) { 3558 return (ret); 3559 } 3560 ret = obj_get_attr(raid_tab, array_obj_id, (void **)(&array_attr)); 3561 if (ret < SUCCESS) 3562 return (ret); 3563 3564 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3565 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3566 if ((raid_lib == NULL) || (fd == 0)) 3567 return (ERR_DRIVER_CLOSED); 3568 3569 ret = raid_lib->array_delete(controller_attr->controller_id, 3570 array_attr->array_id, plugin_err_str); 3571 if (ret < SUCCESS) { 3572 if (disk_ids) 3573 free(disk_ids); 3574 return (ret); 3575 } 3576 3577 if (disk_ids) 3578 free(disk_ids); 3579 return (ret); 3580 } 3581 3582 static int 3583 obj_hsp_bind(raid_obj_tab_t *raid_tab, int num, raid_obj_id_t *obj_ids, 3584 char **plugin_err_str) 3585 { 3586 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE; 3587 raid_obj_id_t array_obj_id, disk_obj_id; 3588 hsp_relation_t *hsp_relation; 3589 controller_attr_t *controller_attr; 3590 array_attr_t *array_attr; 3591 arraypart_attr_t *arraypart_attr; 3592 disk_attr_t *disk_attr; 3593 diskseg_attr_t *diskseg_attr; 3594 hsp_attr_t *hsp_attr; 3595 raid_lib_t *raid_lib; 3596 int ret, fd, i, j = 0; 3597 3598 hsp_relation = malloc(sizeof (hsp_relation_t) * num); 3599 if (hsp_relation == NULL) 3600 return (ERR_NOMEM); 3601 3602 for (i = 0; i < num; ++i) { 3603 array_obj_id = *(obj_ids + i * 2); 3604 disk_obj_id = *(obj_ids + i * 2 + 1); 3605 3606 if (raid_obj_get_type(raid_tab, disk_obj_id) != OBJ_TYPE_DISK || 3607 (array_obj_id != OBJ_ATTR_NONE && 3608 raid_obj_get_type(raid_tab, array_obj_id) != 3609 OBJ_TYPE_ARRAY)) { 3610 free(hsp_relation); 3611 return (ERR_DEVICE_TYPE); 3612 } 3613 3614 /* Get controller attributes */ 3615 if (controller_obj_id == OBJ_NONE) 3616 controller_obj_id = obj_get_controller(raid_tab, 3617 disk_obj_id); 3618 else if (controller_obj_id != obj_get_controller(raid_tab, 3619 disk_obj_id)) { 3620 free(hsp_relation); 3621 return (ERR_DRIVER_ACROSS); 3622 } 3623 3624 ret = obj_get_attr(raid_tab, controller_obj_id, 3625 (void **)(&controller_attr)); 3626 3627 /* Get disk attributes */ 3628 ret = obj_get_attr(raid_tab, disk_obj_id, 3629 (void **)(&disk_attr)); 3630 if (disk_attr->state == DISK_STATE_FAILED) { 3631 free(hsp_relation); 3632 return (ERR_DISK_STATE); 3633 } 3634 3635 /* If it's not a hsp disk, check if there's occupied space */ 3636 if (obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP) == 3637 OBJ_NONE) { 3638 obj_id = obj_get_comp(raid_tab, disk_obj_id, 3639 OBJ_TYPE_DISK_SEG); 3640 while (obj_id != OBJ_NONE) { 3641 ret = obj_get_attr(raid_tab, obj_id, 3642 (void **)(&diskseg_attr)); 3643 if (!(diskseg_attr->state & 3644 DISKSEG_STATE_RESERVED)) { 3645 free(hsp_relation); 3646 return (ERR_DISK_NOT_EMPTY); 3647 } 3648 obj_id = obj_get_sibling(raid_tab, obj_id); 3649 } 3650 } 3651 3652 if (array_obj_id != OBJ_ATTR_NONE) { 3653 /* If local hsp is supported */ 3654 if (!(controller_attr->capability & RAID_CAP_L_HSP)) { 3655 free(hsp_relation); 3656 return (ERR_OP_ILLEGAL); 3657 } 3658 3659 if (raid_obj_get_type(raid_tab, array_obj_id) != 3660 OBJ_TYPE_ARRAY) { 3661 free(hsp_relation); 3662 return (ERR_DEVICE_TYPE); 3663 } 3664 3665 /* Get array attributes */ 3666 ret = obj_get_attr(raid_tab, array_obj_id, 3667 (void **)(&array_attr)); 3668 /* RAID 0 array can not use hsp */ 3669 if (array_attr->raid_level == RAID_LEVEL_0) { 3670 free(hsp_relation); 3671 return (ERR_ARRAY_LEVEL); 3672 } 3673 3674 /* If It's belong to another controller */ 3675 if (controller_obj_id != obj_get_controller(raid_tab, 3676 array_obj_id)) { 3677 free(hsp_relation); 3678 return (ERR_DRIVER_ACROSS); 3679 } 3680 3681 /* Get an array part attributes */ 3682 if ((array_attr->raid_level == RAID_LEVEL_10) || 3683 (array_attr->raid_level == RAID_LEVEL_50)) 3684 obj_id = obj_get_comp(raid_tab, array_obj_id, 3685 OBJ_TYPE_ARRAY); 3686 else 3687 obj_id = array_obj_id; 3688 obj_id = obj_get_comp(raid_tab, obj_id, 3689 OBJ_TYPE_ARRAY_PART); 3690 ret = obj_get_attr(raid_tab, obj_id, 3691 (void **)(&arraypart_attr)); 3692 3693 /* Check if disk space is enough for array */ 3694 if (arraypart_attr->size > disk_attr->capacity) { 3695 free(hsp_relation); 3696 return (ERR_DISK_SPACE); 3697 } 3698 if (controller_attr->capability & RAID_CAP_ARRAY_ALIGN) 3699 if ((arraypart_attr->size + 3700 arraypart_attr->offset) > 3701 disk_attr->capacity) { 3702 free(hsp_relation); 3703 return (ERR_DISK_SPACE); 3704 } 3705 } else if (!(controller_attr->capability & RAID_CAP_G_HSP)) { 3706 /* if global hsp is supported */ 3707 free(hsp_relation); 3708 return (ERR_OP_ILLEGAL); 3709 } 3710 3711 /* 3712 * If the array is already associated with the 3713 * local hsp, or it's a global hsp, ignore it 3714 */ 3715 obj_id = obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP); 3716 if (obj_id > OBJ_NONE) { 3717 if (obj_get_attr(raid_tab, obj_id, 3718 (void **)&hsp_attr) >= SUCCESS) { 3719 if (((hsp_attr->type == HSP_TYPE_GLOBAL) && 3720 (array_obj_id != OBJ_ATTR_NONE)) || 3721 ((hsp_attr->type == HSP_TYPE_LOCAL) && 3722 (array_obj_id == OBJ_ATTR_NONE))) { 3723 free(hsp_relation); 3724 return (ERR_OP_ILLEGAL); 3725 } 3726 } 3727 } 3728 3729 if (array_obj_id != OBJ_ATTR_NONE) 3730 hsp_relation[j].array_id = array_attr->array_id; 3731 else 3732 hsp_relation[j].array_id = (uint32_t)OBJ_ATTR_NONE; 3733 hsp_relation[j].disk_id = disk_attr->disk_id; 3734 ++ j; 3735 } 3736 3737 3738 if (j == 0) 3739 return (SUCCESS); 3740 3741 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3742 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3743 if ((raid_lib == NULL) || (fd == 0)) 3744 return (ERR_DRIVER_CLOSED); 3745 3746 if (raid_lib->hsp_bind == NULL) { 3747 free(hsp_relation); 3748 return (ERR_OP_NO_IMPL); 3749 } 3750 3751 ret = raid_lib->hsp_bind(controller_attr->controller_id, 3752 j, hsp_relation, plugin_err_str); 3753 3754 free(hsp_relation); 3755 return (ret); 3756 } 3757 3758 static int 3759 obj_hsp_unbind(raid_obj_tab_t *raid_tab, int num, raid_obj_id_t *obj_ids, 3760 char **plugin_err_str) 3761 { 3762 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE; 3763 raid_obj_id_t array_obj_id, disk_obj_id; 3764 hsp_relation_t *hsp_relation; 3765 controller_attr_t *controller_attr; 3766 array_attr_t *array_attr; 3767 disk_attr_t *disk_attr; 3768 hsp_attr_t *hsp_attr; 3769 raid_lib_t *raid_lib; 3770 int ret, fd, i, j = 0; 3771 3772 hsp_relation = malloc(sizeof (hsp_relation_t) * num); 3773 if (hsp_relation == NULL) 3774 return (ERR_NOMEM); 3775 3776 for (i = 0; i < num; ++i) { 3777 array_obj_id = *(obj_ids + i * 2); 3778 disk_obj_id = *(obj_ids + i * 2 + 1); 3779 3780 if (raid_obj_get_type(raid_tab, disk_obj_id) != OBJ_TYPE_DISK) { 3781 free(hsp_relation); 3782 return (ERR_DEVICE_TYPE); 3783 } 3784 3785 /* Get controller attributes */ 3786 if (controller_obj_id == OBJ_NONE) 3787 controller_obj_id = obj_get_controller(raid_tab, 3788 disk_obj_id); 3789 else if (controller_obj_id != obj_get_controller(raid_tab, 3790 disk_obj_id)) { 3791 free(hsp_relation); 3792 return (ERR_DRIVER_ACROSS); 3793 } 3794 3795 ret = obj_get_attr(raid_tab, controller_obj_id, 3796 (void **)(&controller_attr)); 3797 3798 /* Get disk attributes */ 3799 ret = obj_get_attr(raid_tab, disk_obj_id, 3800 (void **)(&disk_attr)); 3801 if (disk_attr->state == DISK_STATE_FAILED) { 3802 free(hsp_relation); 3803 return (ERR_DISK_STATE); 3804 } 3805 3806 /* If it's not a hsp disk */ 3807 obj_id = obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP); 3808 if (obj_id == OBJ_NONE) { 3809 free(hsp_relation); 3810 return (ERR_DISK_STATE); 3811 } 3812 ret = obj_get_attr(raid_tab, obj_id, (void **)(&hsp_attr)); 3813 3814 if (array_obj_id != OBJ_ATTR_NONE) { 3815 if (raid_obj_get_type(raid_tab, array_obj_id) != 3816 OBJ_TYPE_ARRAY) { 3817 free(hsp_relation); 3818 return (ERR_DEVICE_TYPE); 3819 } 3820 3821 /* Get array attributes */ 3822 ret = obj_get_attr(raid_tab, array_obj_id, 3823 (void **)(&array_attr)); 3824 3825 /* If It's belong to another controller */ 3826 if (controller_obj_id != obj_get_controller(raid_tab, 3827 array_obj_id)) { 3828 free(hsp_relation); 3829 return (ERR_DRIVER_ACROSS); 3830 } 3831 3832 /* If want to remove an array from a global hsp */ 3833 if (hsp_attr->type == HSP_TYPE_GLOBAL) { 3834 free(hsp_relation); 3835 return (ERR_OP_ILLEGAL); 3836 } 3837 3838 do { 3839 (void) obj_get_attr(raid_tab, obj_id, 3840 (void **)(&hsp_attr)); 3841 3842 if (hsp_attr->associated_id == 3843 array_attr->array_id || 3844 hsp_attr->type == HSP_TYPE_GLOBAL) 3845 break; 3846 3847 obj_id = obj_get_sibling(raid_tab, obj_id); 3848 } while (obj_id > OBJ_NONE); 3849 } else if (hsp_attr->type != HSP_TYPE_GLOBAL) { 3850 /* if global hsp is supported */ 3851 free(hsp_relation); 3852 return (ERR_OP_ILLEGAL); 3853 } 3854 3855 /* 3856 * If array is associated with a local hsp, or remove a 3857 * global hsp disk 3858 */ 3859 if ((obj_id && (array_obj_id != OBJ_ATTR_NONE)) || 3860 (array_obj_id == OBJ_ATTR_NONE)) { 3861 if (array_obj_id != OBJ_ATTR_NONE) 3862 hsp_relation[j].array_id = array_attr->array_id; 3863 else 3864 hsp_relation[j].array_id = 3865 (uint32_t)OBJ_ATTR_NONE; 3866 hsp_relation[j].disk_id = disk_attr->disk_id; 3867 ++ j; 3868 } else { 3869 free(hsp_relation); 3870 return (ERR_OP_ILLEGAL); 3871 } 3872 } 3873 3874 3875 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3876 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3877 if ((raid_lib == NULL) || (fd == 0)) 3878 return (ERR_DRIVER_CLOSED); 3879 3880 if (raid_lib->hsp_unbind == NULL) { 3881 free(hsp_relation); 3882 return (ERR_OP_NO_IMPL); 3883 } 3884 3885 ret = raid_lib->hsp_unbind(controller_attr->controller_id, 3886 j, hsp_relation, plugin_err_str); 3887 3888 free(hsp_relation); 3889 return (ret); 3890 } 3891 3892 /* 3893 * Object maintennance routines 3894 */ 3895 static int 3896 raid_obj_create_system_obj(raid_obj_tab_t *raid_tab) 3897 { 3898 raid_obj_t *raid_obj; 3899 int ret; 3900 3901 raid_obj = calloc(1, sizeof (raid_obj_t)); 3902 if (raid_obj == NULL) 3903 return (ERR_NOMEM); 3904 3905 raid_obj->obj_id = OBJ_SYSTEM; 3906 raid_obj->obj_type_id = OBJ_TYPE_SYSTEM; 3907 raid_obj->data = NULL; 3908 3909 ret = raid_obj_tab_insert(raid_tab, raid_obj->obj_id, raid_obj); 3910 if (ret == ERR_DEVICE_DUP) { 3911 free(raid_obj); 3912 return (ERR_DEVICE_UNCLEAN); 3913 } 3914 3915 return (SUCCESS); 3916 } 3917 3918 static raid_obj_id_t 3919 raid_obj_id_new(raid_obj_tab_t *raid_tab) 3920 { 3921 ++ raid_tab->obj_id_cnt; 3922 if (raid_tab->obj_id_cnt <= 0) 3923 return (ERR_DEVICE_OVERFLOW); 3924 3925 return (raid_tab->obj_id_cnt); 3926 } 3927 3928 static void * 3929 raid_obj_attr_new(raid_obj_type_id_t obj_type) 3930 { 3931 void *obj_attr = NULL; 3932 3933 switch (obj_type) { 3934 case OBJ_TYPE_CONTROLLER: 3935 obj_attr = calloc(1, sizeof (controller_attr_t)); 3936 break; 3937 case OBJ_TYPE_ARRAY: 3938 obj_attr = calloc(1, sizeof (array_attr_t)); 3939 break; 3940 case OBJ_TYPE_DISK: 3941 obj_attr = calloc(1, sizeof (disk_attr_t)); 3942 break; 3943 case OBJ_TYPE_HSP: 3944 obj_attr = calloc(1, sizeof (hsp_attr_t)); 3945 break; 3946 case OBJ_TYPE_ARRAY_PART: 3947 obj_attr = calloc(1, sizeof (arraypart_attr_t)); 3948 break; 3949 case OBJ_TYPE_DISK_SEG: 3950 obj_attr = calloc(1, sizeof (diskseg_attr_t)); 3951 break; 3952 case OBJ_TYPE_TASK: 3953 obj_attr = calloc(1, sizeof (task_attr_t)); 3954 break; 3955 case OBJ_TYPE_PROP: 3956 obj_attr = calloc(1, sizeof (property_attr_t)); 3957 break; 3958 default: 3959 break; 3960 } 3961 3962 return (obj_attr); 3963 } 3964 3965 static raid_obj_id_t 3966 raid_obj_create(raid_obj_tab_t *raid_tab, raid_obj_type_id_t obj_type) 3967 { 3968 raid_obj_t *raid_obj; 3969 int ret; 3970 void *data_ptr; 3971 3972 raid_obj = calloc(1, sizeof (raid_obj_t)); 3973 if (raid_obj == NULL) 3974 return (ERR_NOMEM); 3975 3976 raid_obj->obj_id = raid_obj_id_new(raid_tab); 3977 if (raid_obj->obj_id < OBJ_NONE) 3978 return (ERR_DEVICE_OVERFLOW); 3979 3980 ret = raid_obj_tab_insert(raid_tab, raid_obj->obj_id, raid_obj); 3981 if (ret == ERR_DEVICE_DUP) { 3982 free(raid_obj); 3983 return (ERR_DEVICE_DUP); 3984 } 3985 3986 data_ptr = raid_obj_attr_new(obj_type); 3987 if (data_ptr == NULL) { 3988 (void) raid_obj_delete(raid_tab, raid_obj->obj_id); 3989 return (ERR_NOMEM); 3990 } 3991 3992 (void) raid_obj_set_data_ptr(raid_tab, raid_obj->obj_id, data_ptr); 3993 3994 (void) raid_obj_set_type(raid_tab, raid_obj->obj_id, obj_type); 3995 return (raid_obj->obj_id); 3996 } 3997 3998 static int 3999 raid_obj_delete(raid_obj_tab_t *raid_tab, raid_obj_id_t raid_obj_id) 4000 { 4001 raid_obj_t *obj; 4002 4003 obj = raid_obj_tab_remove(raid_tab, raid_obj_id); 4004 if (obj != NULL) { 4005 free(obj->data); 4006 free(obj); 4007 return (SUCCESS); 4008 } 4009 4010 return (ERR_DEVICE_NOENT); 4011 } 4012 4013 static int 4014 raid_obj_add_org(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4015 raid_obj_id_t container_id) 4016 { 4017 raid_obj_id_t tmp, tmp1; 4018 4019 tmp = raid_obj_get_comp(raid_tab, container_id); 4020 if (tmp < OBJ_NONE) 4021 return (ERR_DEVICE_NOENT); 4022 4023 if (tmp == OBJ_NONE) { 4024 (void) raid_obj_set_container(raid_tab, obj_id, container_id); 4025 (void) raid_obj_set_comp(raid_tab, container_id, obj_id); 4026 return (SUCCESS); 4027 } 4028 4029 while ((tmp1 = raid_obj_get_sibling(raid_tab, tmp)) != OBJ_NONE) 4030 tmp = tmp1; 4031 4032 if (raid_obj_set_sibling(raid_tab, tmp, obj_id) < SUCCESS) 4033 return (ERR_DEVICE_NOENT); 4034 (void) raid_obj_set_container(raid_tab, obj_id, container_id); 4035 4036 return (SUCCESS); 4037 } 4038 4039 static raid_obj_type_id_t 4040 raid_obj_get_type(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4041 { 4042 raid_obj_t *obj; 4043 4044 obj = raid_obj_tab_find(raid_tab, obj_id); 4045 if (obj == NULL) 4046 return (ERR_DEVICE_NOENT); 4047 4048 if ((obj->obj_type_id < OBJ_TYPE_SYSTEM) || 4049 (obj->obj_type_id >= OBJ_TYPE_ALL)) 4050 return (ERR_DEVICE_INVALID); 4051 4052 return (obj->obj_type_id); 4053 } 4054 4055 static int 4056 raid_obj_set_type(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4057 raid_obj_type_id_t type) 4058 { 4059 raid_obj_t *obj; 4060 4061 obj = raid_obj_tab_find(raid_tab, obj_id); 4062 if (obj == NULL) 4063 return (ERR_DEVICE_NOENT); 4064 4065 if ((type < OBJ_TYPE_SYSTEM) || (type >= OBJ_TYPE_ALL)) 4066 return (ERR_DEVICE_TYPE); 4067 4068 obj->obj_type_id = type; 4069 return (SUCCESS); 4070 } 4071 4072 static raid_obj_status_t 4073 raid_obj_get_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4074 { 4075 raid_obj_t *obj; 4076 4077 obj = raid_obj_tab_find(raid_tab, obj_id); 4078 if (obj == NULL) 4079 return (ERR_DEVICE_NOENT); 4080 4081 return (obj->status); 4082 } 4083 4084 static int 4085 raid_obj_set_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4086 raid_obj_status_t status) 4087 { 4088 raid_obj_t *obj; 4089 4090 obj = raid_obj_tab_find(raid_tab, obj_id); 4091 if (obj == NULL) 4092 return (ERR_DEVICE_NOENT); 4093 4094 obj->status = obj->status | status; 4095 4096 return (SUCCESS); 4097 } 4098 4099 static int 4100 raid_obj_clear_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4101 raid_obj_status_t status) 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 obj->status = obj->status & ~status; 4110 4111 return (SUCCESS); 4112 } 4113 4114 static raid_obj_id_t 4115 raid_obj_get_container(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4116 { 4117 raid_obj_t *obj; 4118 4119 obj = raid_obj_tab_find(raid_tab, obj_id); 4120 if (obj == NULL) 4121 return (ERR_DEVICE_NOENT); 4122 4123 return (obj->container); 4124 } 4125 4126 static int 4127 raid_obj_set_container(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4128 raid_obj_id_t container_id) 4129 { 4130 raid_obj_t *obj; 4131 4132 obj = raid_obj_tab_find(raid_tab, obj_id); 4133 if (obj == NULL) 4134 return (ERR_DEVICE_NOENT); 4135 4136 obj->container = container_id; 4137 return (SUCCESS); 4138 } 4139 4140 static raid_obj_id_t 4141 raid_obj_get_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4142 { 4143 raid_obj_t *obj; 4144 4145 obj = raid_obj_tab_find(raid_tab, obj_id); 4146 if (obj == NULL) 4147 return (ERR_DEVICE_NOENT); 4148 4149 return (obj->component); 4150 } 4151 4152 static int 4153 raid_obj_set_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4154 raid_obj_id_t comp) 4155 { 4156 raid_obj_t *obj; 4157 4158 obj = raid_obj_tab_find(raid_tab, obj_id); 4159 if (obj == NULL) 4160 return (ERR_DEVICE_NOENT); 4161 4162 obj->component = comp; 4163 return (SUCCESS); 4164 } 4165 4166 static raid_obj_id_t 4167 raid_obj_get_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4168 { 4169 raid_obj_t *obj; 4170 4171 obj = raid_obj_tab_find(raid_tab, obj_id); 4172 if (obj == NULL) 4173 return (ERR_DEVICE_NOENT); 4174 4175 return (obj->sibling); 4176 } 4177 4178 static int 4179 raid_obj_set_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4180 raid_obj_id_t sibling) 4181 { 4182 raid_obj_t *obj; 4183 4184 obj = raid_obj_tab_find(raid_tab, obj_id); 4185 if (obj == NULL) 4186 return (ERR_DEVICE_NOENT); 4187 4188 obj->sibling = sibling; 4189 4190 return (SUCCESS); 4191 } 4192 4193 static void * 4194 raid_obj_get_data_ptr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4195 { 4196 raid_obj_t *obj; 4197 4198 obj = raid_obj_tab_find(raid_tab, obj_id); 4199 if (obj == NULL) 4200 return (NULL); 4201 4202 return (obj->data); 4203 } 4204 4205 static int 4206 raid_obj_set_data_ptr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4207 void *data) 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 obj->data = data; 4216 4217 return (SUCCESS); 4218 } 4219 4220 static raid_obj_handle_t 4221 raid_obj_get_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4222 { 4223 raid_obj_t *obj; 4224 4225 obj = raid_obj_tab_find(raid_tab, obj_id); 4226 if (obj == NULL) 4227 return (ERR_DEVICE_NOENT); 4228 4229 return (obj->handle); 4230 } 4231 4232 static int 4233 raid_obj_set_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4234 raid_obj_handle_t handle) 4235 { 4236 raid_obj_t *obj; 4237 4238 obj = raid_obj_tab_find(raid_tab, obj_id); 4239 if (obj == NULL) 4240 return (ERR_DEVICE_NOENT); 4241 4242 obj->handle = handle; 4243 return (SUCCESS); 4244 } 4245 /* 4246 * Object list maintennance routines 4247 */ 4248 static void 4249 raid_list_create(raid_list_t *list, size_t offset) 4250 { 4251 list->head = NULL; 4252 list->tail = NULL; 4253 list->offset = offset; 4254 } 4255 4256 static void * 4257 raid_list_head(raid_list_t *list) 4258 { 4259 return (list->head); 4260 } 4261 4262 static void * 4263 raid_list_next(raid_list_t *list, void *obj) 4264 { 4265 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj); 4266 4267 return (el->next); 4268 } 4269 4270 static void 4271 raid_list_insert_tail(raid_list_t *list, void *obj) 4272 { 4273 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj), *el1; 4274 4275 el->prev = list->tail; 4276 list->tail = obj; 4277 4278 el->next = NULL; 4279 4280 if (list->head == NULL) 4281 list->head = obj; 4282 4283 if (el->prev != NULL) { 4284 el1 = LIST_OBJ_TO_EL(list, el->prev); 4285 el1->next = obj; 4286 } 4287 } 4288 4289 static void 4290 raid_list_remove(raid_list_t *list, void *obj) 4291 { 4292 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj), *el1; 4293 4294 if (list->head == obj) 4295 list->head = el->next; 4296 4297 if (list->tail == obj) 4298 list->tail = el->prev; 4299 4300 if (el->next != NULL) { 4301 el1 = LIST_OBJ_TO_EL(list, el->next); 4302 el1->prev = el->prev; 4303 } 4304 4305 if (el->prev != NULL) { 4306 el1 = LIST_OBJ_TO_EL(list, el->prev); 4307 el1->next = el->next; 4308 } 4309 4310 el->prev = el->next = NULL; 4311 } 4312 4313 static void * 4314 raid_list_remove_head(raid_list_t *list) 4315 { 4316 void *obj = list->head; 4317 4318 if (obj != NULL) 4319 raid_list_remove(list, obj); 4320 4321 return (obj); 4322 } 4323 4324 static void * 4325 raid_list_find(raid_list_t *list, raid_obj_id_t obj_id) 4326 { 4327 raid_obj_t *obj; 4328 4329 for (obj = raid_list_head(list); obj != NULL; 4330 obj = raid_list_next(list, obj)) 4331 if (obj->obj_id == obj_id) 4332 break; 4333 4334 return (obj); 4335 } 4336 4337 static int 4338 raid_obj_tab_create(raid_obj_tab_t *tab, size_t hash_slots) 4339 { 4340 unsigned i; 4341 4342 if (hash_slots == 0) 4343 return (ERR_OP_ILLEGAL); 4344 4345 tab->slots = hash_slots; 4346 4347 if ((tab->table = calloc(hash_slots, sizeof (raid_list_t))) == NULL) 4348 return (ERR_NOMEM); 4349 4350 for (i = 0; i < hash_slots; i++) 4351 raid_list_create(&tab->table[i], offsetof(raid_obj_t, el)); 4352 4353 return (SUCCESS); 4354 } 4355 4356 static void 4357 raid_obj_tab_destroy(raid_obj_tab_t *tab) 4358 { 4359 unsigned i; 4360 4361 for (i = 0; i < tab->slots; i++) { 4362 struct raid_obj_t *obj; 4363 4364 while ((obj = raid_list_remove_head(&tab->table[i])) != NULL) 4365 free(obj); 4366 4367 raid_list_destroy(&tab->table[i]); 4368 } 4369 4370 if (tab->table) 4371 free(tab->table); 4372 4373 tab->table = NULL; 4374 tab->slots = 0; 4375 tab->obj_id_cnt = 0; 4376 } 4377 4378 static int 4379 raid_obj_tab_insert(raid_obj_tab_t *tab, raid_obj_id_t id, void *obj) 4380 { 4381 raid_list_t *list; 4382 4383 list = OBJ_TAB_SLOT(tab, id); 4384 4385 if (raid_list_find(list, id) != NULL) 4386 return (ERR_DEVICE_DUP); 4387 4388 raid_list_insert_tail(list, obj); 4389 4390 return (SUCCESS); 4391 } 4392 4393 static void * 4394 raid_obj_tab_remove(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 4401 if ((obj = raid_list_find(list, id)) != NULL) 4402 raid_list_remove(list, obj); 4403 4404 return (obj); 4405 } 4406 4407 static void * 4408 raid_obj_tab_find(raid_obj_tab_t *tab, raid_obj_id_t id) 4409 { 4410 raid_list_t *list; 4411 raid_obj_t *obj; 4412 4413 list = OBJ_TAB_SLOT(tab, id); 4414 obj = raid_list_find(list, id); 4415 4416 return (obj); 4417 } 4418 4419 static void 4420 raid_list_destroy(raid_list_t *list) 4421 { 4422 list->head = NULL; 4423 list->tail = NULL; 4424 list->offset = 0; 4425 } 4426 4427 /* 4428 * Plug-in maintennance routines 4429 */ 4430 static int 4431 controller_id_to_path(uint32_t controller_id, char *path) 4432 { 4433 int fd; 4434 char buf[MAX_PATH_LEN] = {0}, buf1[MAX_PATH_LEN] = {0}, *colon; 4435 4436 (void) snprintf(buf, MAX_PATH_LEN, "%s/c%d", CFGDIR, controller_id); 4437 if (readlink(buf, buf1, sizeof (buf1)) < 0) 4438 return (ERR_DRIVER_NOT_FOUND); 4439 4440 if (buf1[0] != '/') 4441 (void) snprintf(buf, sizeof (buf), "%s/", CFGDIR); 4442 else 4443 buf[0] = 0; 4444 (void) strlcat(buf, buf1, MAX_PATH_LEN); 4445 4446 colon = strrchr(buf, ':'); 4447 if (colon == NULL) 4448 return (ERR_DRIVER_NOT_FOUND); 4449 else 4450 *colon = 0; 4451 4452 (void) snprintf(path, MAX_PATH_LEN, "%s:devctl", buf); 4453 4454 fd = open(path, O_RDONLY | O_NDELAY); 4455 4456 if (fd < 0) 4457 return (ERR_DRIVER_NOT_FOUND); 4458 4459 (void) close(fd); 4460 4461 return (SUCCESS); 4462 } 4463 4464 static char * 4465 controller_id_to_driver_name(uint32_t controller_id) 4466 { 4467 char buf[MAX_PATH_LEN]; 4468 di_node_t di_node; 4469 char *name, *tmp; 4470 int ret; 4471 4472 ret = controller_id_to_path(controller_id, buf); 4473 if (ret < SUCCESS) 4474 return (NULL); 4475 4476 tmp = strrchr(buf, ':'); 4477 if (tmp != NULL) 4478 *tmp = 0; 4479 4480 tmp = strstr(buf, "pci"); 4481 if (tmp == NULL) 4482 return (NULL); 4483 4484 di_node = di_init(tmp, DINFOPROP); 4485 if (di_node == DI_NODE_NIL) 4486 return (NULL); 4487 4488 name = di_driver_name(di_node); 4489 4490 return (name); 4491 } 4492 4493 static void 4494 raid_plugin_init() 4495 { 4496 raid_lib_t *raid_lib = raid_lib_sys; 4497 4498 while (raid_lib) { 4499 raid_lib_sys = raid_lib->next; 4500 (void) dlclose(raid_lib->lib_handle); 4501 free(raid_lib); 4502 raid_lib = raid_lib_sys; 4503 } 4504 } 4505 4506 static raid_lib_t * 4507 raid_plugin_load(char *driver_name) 4508 { 4509 char buf[MAX_PATH_LEN] = {0}; 4510 raid_lib_t *supplib; 4511 void *sym; 4512 4513 supplib = calloc(1, sizeof (raid_lib_t)); 4514 if (supplib == NULL) 4515 return (NULL); 4516 4517 (void) snprintf(buf, MAX_PATH_LEN, "%s/%s.so.1", 4518 SUPP_PLUGIN_DIR, driver_name); 4519 4520 supplib->lib_handle = dlopen(buf, RTLD_LAZY); 4521 if (supplib->lib_handle == NULL) { 4522 free(supplib); 4523 return (NULL); 4524 } 4525 4526 supplib->name = driver_name; 4527 4528 if ((sym = dlsym(supplib->lib_handle, "rdcfg_version")) == NULL) 4529 supplib->version = RDCFG_PLUGIN_V1; 4530 else { 4531 supplib->version = *((uint32_t *)sym); 4532 if (supplib->version != RDCFG_PLUGIN_V1) { 4533 (void) dlclose(supplib->lib_handle); 4534 free(supplib); 4535 return (NULL); 4536 } 4537 } 4538 4539 if ((sym = dlsym(supplib->lib_handle, "rdcfg_open_controller")) == 4540 NULL) { 4541 (void) dlclose(supplib->lib_handle); 4542 free(supplib); 4543 return (NULL); 4544 } else 4545 supplib->open_controller = (int(*)(uint32_t, char **))sym; 4546 4547 if ((sym = dlsym(supplib->lib_handle, "rdcfg_close_controller")) == 4548 NULL) { 4549 (void) dlclose(supplib->lib_handle); 4550 free(supplib); 4551 return (NULL); 4552 } else 4553 supplib->close_controller = (int (*)(uint32_t, char **))sym; 4554 4555 if ((sym = dlsym(supplib->lib_handle, "rdcfg_compnum")) == NULL) { 4556 (void) dlclose(supplib->lib_handle); 4557 free(supplib); 4558 return (NULL); 4559 } else 4560 supplib->compnum = (int (*)(uint32_t, uint32_t, 4561 raid_obj_type_id_t, raid_obj_type_id_t))sym; 4562 4563 if ((sym = dlsym(supplib->lib_handle, "rdcfg_complist")) == NULL) { 4564 (void) dlclose(supplib->lib_handle); 4565 free(supplib); 4566 return (NULL); 4567 } else 4568 supplib->complist = (int (*)(uint32_t, uint32_t, 4569 raid_obj_type_id_t, raid_obj_type_id_t, int, void *))sym; 4570 4571 if ((sym = dlsym(supplib->lib_handle, "rdcfg_get_attr")) == NULL) { 4572 (void) dlclose(supplib->lib_handle); 4573 free(supplib); 4574 return (NULL); 4575 } else 4576 supplib->get_attr = (int (*)(uint32_t, uint32_t, uint32_t, 4577 raid_obj_type_id_t, void*))sym; 4578 4579 if ((sym = dlsym(supplib->lib_handle, "rdcfg_array_create")) == NULL) { 4580 (void) dlclose(supplib->lib_handle); 4581 free(supplib); 4582 return (NULL); 4583 } else 4584 supplib->array_create = (int (*)(uint32_t, array_attr_t *, int, 4585 arraypart_attr_t *, char **))sym; 4586 4587 if ((sym = dlsym(supplib->lib_handle, "rdcfg_array_delete")) == NULL) { 4588 (void) dlclose(supplib->lib_handle); 4589 free(supplib); 4590 return (NULL); 4591 } else 4592 supplib->array_delete = 4593 (int (*)(uint32_t, uint32_t, char **))sym; 4594 4595 supplib->hsp_bind = (int (*)(uint32_t, uint32_t, hsp_relation_t *, 4596 char **))dlsym(supplib->lib_handle, "rdcfg_hsp_bind"); 4597 supplib->hsp_unbind = (int (*)(uint32_t, uint32_t, hsp_relation_t *, 4598 char **))dlsym(supplib->lib_handle, "rdcfg_hsp_unbind"); 4599 supplib->set_attr = (int (*)(uint32_t, uint32_t, uint32_t, uint32_t *, 4600 char **))dlsym(supplib->lib_handle, "rdcfg_set_attr"); 4601 supplib->flash_fw = (int (*)(uint32_t, char *, uint32_t, char **)) 4602 dlsym(supplib->lib_handle, "rdcfg_flash_fw"); 4603 4604 supplib->next = raid_lib_sys; 4605 raid_lib_sys = supplib; 4606 return (supplib); 4607 } 4608 4609 static raid_lib_t * 4610 raid_find_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t controller_obj_id) 4611 { 4612 controller_attr_t *controller_attr; 4613 raid_lib_t *raid_lib; 4614 char *driver_name; 4615 raid_obj_handle_t handle; 4616 4617 /* Check if it's mapped to handle structure */ 4618 handle = raid_obj_to_handle(raid_tab, controller_obj_id); 4619 if (raid_handle_sys.handles[handle].raid_lib != NULL) 4620 return (raid_handle_sys.handles[handle].raid_lib); 4621 4622 (void) obj_get_attr(raid_tab, controller_obj_id, 4623 (void **)(&controller_attr)); 4624 4625 /* Check if the plugin module is already loaded */ 4626 driver_name = controller_id_to_driver_name( 4627 controller_attr->controller_id); 4628 if (driver_name == NULL) 4629 return (NULL); 4630 4631 raid_lib = raid_lib_sys; 4632 while (raid_lib != NULL) { 4633 if (raid_lib->name != NULL && 4634 strcmp(driver_name, raid_lib->name) == 0) 4635 return (raid_lib); 4636 4637 raid_lib = raid_lib->next; 4638 } 4639 4640 /* Loading the plugin module */ 4641 raid_lib = raid_plugin_load(driver_name); 4642 4643 return (raid_lib); 4644 } 4645