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