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