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