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