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