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