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