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