1711890bcSjc156560 /* 2711890bcSjc156560 * CDDL HEADER START 3711890bcSjc156560 * 4711890bcSjc156560 * The contents of this file are subject to the terms of the 5711890bcSjc156560 * Common Development and Distribution License (the "License"). 6711890bcSjc156560 * You may not use this file except in compliance with the License. 7711890bcSjc156560 * 8711890bcSjc156560 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9711890bcSjc156560 * or http://www.opensolaris.org/os/licensing. 10711890bcSjc156560 * See the License for the specific language governing permissions 11711890bcSjc156560 * and limitations under the License. 12711890bcSjc156560 * 13711890bcSjc156560 * When distributing Covered Code, include this CDDL HEADER in each 14711890bcSjc156560 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15711890bcSjc156560 * If applicable, add the following below this CDDL HEADER, with the 16711890bcSjc156560 * fields enclosed by brackets "[]" replaced with your own identifying 17711890bcSjc156560 * information: Portions Copyright [yyyy] [name of copyright owner] 18711890bcSjc156560 * 19711890bcSjc156560 * CDDL HEADER END 20711890bcSjc156560 */ 21711890bcSjc156560 22711890bcSjc156560 /* 2372e1c055Sjc156560 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24711890bcSjc156560 * Use is subject to license terms. 25711890bcSjc156560 */ 26711890bcSjc156560 27711890bcSjc156560 #pragma ident "%Z%%M% %I% %E% SMI" 28711890bcSjc156560 29711890bcSjc156560 #include <fcntl.h> 30711890bcSjc156560 #include <sys/types.h> 31711890bcSjc156560 #include <sys/stat.h> 32711890bcSjc156560 #include <stddef.h> 33711890bcSjc156560 #include <stdlib.h> 34711890bcSjc156560 #include <dirent.h> 35711890bcSjc156560 #include <dlfcn.h> 36711890bcSjc156560 #include <link.h> 37711890bcSjc156560 #include <strings.h> 38711890bcSjc156560 #include <stdio.h> 39711890bcSjc156560 #include <unistd.h> 40711890bcSjc156560 #include <sys/mnttab.h> 41711890bcSjc156560 #include <config_admin.h> 42711890bcSjc156560 #include <sys/param.h> 43711890bcSjc156560 #include <libintl.h> 44711890bcSjc156560 #include <libdevinfo.h> 45711890bcSjc156560 #include <raidcfg.h> 46711890bcSjc156560 #include <thread.h> 47711890bcSjc156560 #include <synch.h> 48711890bcSjc156560 49711890bcSjc156560 #ifndef TEXT_DOMAIN 50711890bcSjc156560 #define TEXT_DOMAIN "SYS_TEST" 51711890bcSjc156560 #endif 52711890bcSjc156560 53711890bcSjc156560 #define HASH_SLOTS 16 54711890bcSjc156560 #define HANDLER_SLOTS 256 55711890bcSjc156560 56711890bcSjc156560 /* 57711890bcSjc156560 * Raid object status; 58711890bcSjc156560 */ 59711890bcSjc156560 #define OBJ_STATUS_CMD_CLEAN -1 60711890bcSjc156560 #define OBJ_STATUS_OPENED 1 61711890bcSjc156560 #define OBJ_STATUS_SCANCOMP 1 << 1 62711890bcSjc156560 63711890bcSjc156560 #if defined(__sparcv9) 64711890bcSjc156560 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg/sparcv9" 65711890bcSjc156560 #elif defined(__amd64) 66711890bcSjc156560 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg/amd64" 67711890bcSjc156560 #else 68711890bcSjc156560 #define SUPP_PLUGIN_DIR "/usr/lib/raidcfg" 69711890bcSjc156560 #endif 70711890bcSjc156560 71711890bcSjc156560 /* 72711890bcSjc156560 * Basic types 73711890bcSjc156560 */ 74711890bcSjc156560 typedef int raid_obj_id_t; 75711890bcSjc156560 typedef int raid_obj_status_t; 76711890bcSjc156560 77711890bcSjc156560 /* 78711890bcSjc156560 * Data structures used for object maintennance 79711890bcSjc156560 */ 80711890bcSjc156560 typedef struct { 81711890bcSjc156560 void *head; 82711890bcSjc156560 void *tail; 83711890bcSjc156560 size_t offset; /* offset of double-linked element (raid_list_el_t) */ 84711890bcSjc156560 /* in the linked data structures (objects) */ 85711890bcSjc156560 } raid_list_t; 86711890bcSjc156560 87711890bcSjc156560 typedef struct { 88711890bcSjc156560 void *prev; 89711890bcSjc156560 void *next; 90711890bcSjc156560 } raid_list_el_t; 91711890bcSjc156560 92711890bcSjc156560 typedef struct { 93711890bcSjc156560 raid_obj_id_t obj_id_cnt; /* id 0 is reserved */ 94711890bcSjc156560 size_t slots; /* How many lists linked by *table */ 95711890bcSjc156560 raid_list_t *table; 96711890bcSjc156560 } raid_obj_tab_t; 97711890bcSjc156560 98711890bcSjc156560 /* 99711890bcSjc156560 * Object type structure containing function pointers; 100711890bcSjc156560 */ 101711890bcSjc156560 typedef struct { 102711890bcSjc156560 int (*compnum)(raid_obj_tab_t *, raid_obj_id_t, raid_obj_type_id_t); 103711890bcSjc156560 int (*complist)(raid_obj_tab_t *, raid_obj_id_t, int, raid_obj_id_t *, 104711890bcSjc156560 raid_obj_type_id_t); 105711890bcSjc156560 int (*get_attr)(raid_obj_tab_t *, raid_obj_id_t); 106711890bcSjc156560 int (*set_attr)(raid_obj_tab_t *, raid_obj_id_t, uint32_t, uint32_t *, 107711890bcSjc156560 char **); 108711890bcSjc156560 int (*act)(raid_obj_tab_t *, raid_obj_id_t, uint32_t, void *, char **); 109711890bcSjc156560 int (*create_obj)(raid_obj_tab_t *, raid_obj_id_t, int, 110711890bcSjc156560 raid_obj_id_t *, char **); 111711890bcSjc156560 int (*delete_obj)(raid_obj_tab_t *, raid_obj_id_t, char **); 112711890bcSjc156560 int (*bind_obj)(raid_obj_tab_t *, int, raid_obj_id_t *, char **); 113711890bcSjc156560 int (*unbind_obj)(raid_obj_tab_t *, int, raid_obj_id_t *, char **); 114711890bcSjc156560 } raid_obj_op_t; 115711890bcSjc156560 116711890bcSjc156560 /* 117711890bcSjc156560 * Common object data structure 118711890bcSjc156560 */ 119711890bcSjc156560 typedef struct { 120711890bcSjc156560 raid_list_el_t el; /* double-links */ 121711890bcSjc156560 122711890bcSjc156560 raid_obj_type_id_t obj_type_id; 123711890bcSjc156560 raid_obj_id_t obj_id; 124711890bcSjc156560 raid_obj_status_t status; 125711890bcSjc156560 126711890bcSjc156560 raid_obj_id_t container; 127711890bcSjc156560 raid_obj_id_t sibling; 128711890bcSjc156560 raid_obj_id_t component; 129711890bcSjc156560 130711890bcSjc156560 void *data; /* Pointer to attribute structure */ 131711890bcSjc156560 raid_obj_handle_t handle; 132711890bcSjc156560 } raid_obj_t; 133711890bcSjc156560 134711890bcSjc156560 /* 135711890bcSjc156560 * Definition about handle 136711890bcSjc156560 */ 137711890bcSjc156560 typedef struct { 138711890bcSjc156560 uint32_t next; 139711890bcSjc156560 uint32_t type; 140711890bcSjc156560 uint32_t controller_id; 141711890bcSjc156560 uint32_t array_id; 142711890bcSjc156560 uint32_t disk_id; 143711890bcSjc156560 uint64_t seq_id; 144711890bcSjc156560 uint32_t task_id; 145*b449fa8aSyw161884 uint32_t prop_id; 146711890bcSjc156560 uint32_t fd; /* Only for controller */ 147711890bcSjc156560 raid_lib_t *raid_lib; /* Only for controller */ 148711890bcSjc156560 } handle_attr_t; 149711890bcSjc156560 150711890bcSjc156560 #define LIST_OBJ_TO_EL(list, obj) \ 151711890bcSjc156560 ((void *)((char *)(obj) + (list)->offset)) 152711890bcSjc156560 #define OBJ_TAB_SLOT(tab, id) \ 153711890bcSjc156560 ((tab)->table + ((id)%(tab)->slots)) 154711890bcSjc156560 155711890bcSjc156560 #pragma init(raidcfg_init) 156711890bcSjc156560 #pragma fini(raidcfg_fini) 157711890bcSjc156560 158711890bcSjc156560 /* 159711890bcSjc156560 * Function prototypes 160711890bcSjc156560 */ 161711890bcSjc156560 static int intcompare(const void *p1, const void *p2); 162711890bcSjc156560 static uint64_t raid_space_noalign(raid_obj_tab_t *, uint32_t, int, 163711890bcSjc156560 raid_obj_id_t *, arraypart_attr_t *); 164711890bcSjc156560 static int raid_handle_init(); 165711890bcSjc156560 static void raid_handle_fini(); 166711890bcSjc156560 static raid_obj_handle_t raid_handle_new(raid_obj_type_id_t); 167711890bcSjc156560 static void raid_handle_delete(raid_obj_handle_t); 168711890bcSjc156560 static void raid_handle_delete_controller_comp(uint32_t); 169711890bcSjc156560 static raid_obj_id_t raid_handle_to_obj(raid_obj_tab_t *, 170711890bcSjc156560 raid_obj_handle_t); 171711890bcSjc156560 static raid_obj_handle_t raid_obj_to_handle(raid_obj_tab_t *, 172711890bcSjc156560 raid_obj_id_t); 173711890bcSjc156560 static raid_lib_t *raid_obj_get_lib(raid_obj_tab_t *, raid_obj_id_t); 174711890bcSjc156560 static int raid_obj_set_lib(raid_obj_tab_t *, raid_obj_id_t, raid_lib_t *); 175711890bcSjc156560 static int raid_obj_get_fd(raid_obj_tab_t *, raid_obj_id_t); 176711890bcSjc156560 static int raid_obj_set_fd(raid_obj_tab_t *, raid_obj_id_t, int); 177711890bcSjc156560 static int obj_scan_comp(raid_obj_tab_t *, raid_obj_id_t); 178711890bcSjc156560 static int obj_rescan(raid_obj_tab_t *); 179711890bcSjc156560 static raid_obj_id_t obj_get_comp(raid_obj_tab_t *, raid_obj_id_t, 180711890bcSjc156560 raid_obj_type_id_t); 181711890bcSjc156560 static raid_obj_id_t obj_get_sibling(raid_obj_tab_t *, raid_obj_id_t); 182711890bcSjc156560 static int obj_get_attr(raid_obj_tab_t *, raid_obj_id_t, void **); 183711890bcSjc156560 static raid_obj_id_t obj_locate_controller(raid_obj_tab_t *, uint32_t); 184711890bcSjc156560 static raid_obj_id_t obj_locate_array(raid_obj_tab_t *, uint32_t, uint32_t); 185711890bcSjc156560 static raid_obj_id_t obj_locate_array_recur(raid_obj_tab_t *, raid_obj_id_t, 186711890bcSjc156560 uint32_t); 187711890bcSjc156560 static raid_obj_id_t obj_locate_hsp(raid_obj_tab_t *, uint32_t, 188711890bcSjc156560 uint32_t, uint32_t); 189711890bcSjc156560 static raid_obj_id_t obj_locate_disk(raid_obj_tab_t *, uint32_t, uint32_t); 190711890bcSjc156560 static raid_obj_id_t obj_locate_arraypart(raid_obj_tab_t *, uint32_t, 191711890bcSjc156560 uint32_t, uint32_t); 192711890bcSjc156560 static raid_obj_id_t obj_locate_diskseg(raid_obj_tab_t *, uint32_t, 193711890bcSjc156560 uint32_t, uint32_t); 194711890bcSjc156560 static raid_obj_id_t obj_locate_task(raid_obj_tab_t *, uint32_t, uint32_t); 195*b449fa8aSyw161884 static raid_obj_id_t obj_locate_prop(raid_obj_tab_t *, uint32_t, uint32_t, 196*b449fa8aSyw161884 uint32_t); 197711890bcSjc156560 static raid_obj_id_t obj_get_controller(raid_obj_tab_t *, raid_obj_id_t); 198711890bcSjc156560 199711890bcSjc156560 static int obj_sys_compnum(raid_obj_tab_t *, raid_obj_id_t, 200711890bcSjc156560 raid_obj_type_id_t); 201711890bcSjc156560 static int obj_sys_complist(raid_obj_tab_t *, raid_obj_id_t, int, 202711890bcSjc156560 raid_obj_id_t *, raid_obj_type_id_t); 203711890bcSjc156560 static int obj_controller_compnum(raid_obj_tab_t *, raid_obj_id_t, 204711890bcSjc156560 raid_obj_type_id_t); 205711890bcSjc156560 static int obj_controller_complist(raid_obj_tab_t *, raid_obj_id_t, int, 206711890bcSjc156560 raid_obj_id_t *, raid_obj_type_id_t); 207711890bcSjc156560 static int obj_controller_get_attr(raid_obj_tab_t *, raid_obj_id_t); 208711890bcSjc156560 static int obj_controller_act(raid_obj_tab_t *, raid_obj_id_t, 209711890bcSjc156560 uint32_t, void *, char **); 210711890bcSjc156560 static int obj_array_compnum(raid_obj_tab_t *, raid_obj_id_t, 211711890bcSjc156560 raid_obj_type_id_t); 212711890bcSjc156560 static int obj_array_complist(raid_obj_tab_t *, raid_obj_id_t, int, 213711890bcSjc156560 raid_obj_id_t *, raid_obj_type_id_t); 214711890bcSjc156560 static int obj_array_get_attr(raid_obj_tab_t *, raid_obj_id_t); 215711890bcSjc156560 static int obj_array_set_attr(raid_obj_tab_t *, raid_obj_id_t, 216711890bcSjc156560 uint32_t, uint32_t *, char **); 217711890bcSjc156560 static int obj_disk_compnum(raid_obj_tab_t *, raid_obj_id_t, 218711890bcSjc156560 raid_obj_type_id_t); 219711890bcSjc156560 static int obj_disk_complist(raid_obj_tab_t *, raid_obj_id_t, int, 220711890bcSjc156560 raid_obj_id_t *, raid_obj_type_id_t); 221711890bcSjc156560 static int obj_disk_get_attr(raid_obj_tab_t *, raid_obj_id_t); 222711890bcSjc156560 static int obj_hsp_get_attr(raid_obj_tab_t *, raid_obj_id_t); 223711890bcSjc156560 static int obj_arraypart_get_attr(raid_obj_tab_t *, raid_obj_id_t); 224711890bcSjc156560 static int obj_diskseg_get_attr(raid_obj_tab_t *, raid_obj_id_t); 225711890bcSjc156560 static int obj_task_get_attr(raid_obj_tab_t *, raid_obj_id_t); 226*b449fa8aSyw161884 static int obj_prop_get_attr(raid_obj_tab_t *, raid_obj_id_t); 227711890bcSjc156560 static int obj_array_create(raid_obj_tab_t *, raid_obj_id_t, int, 228711890bcSjc156560 raid_obj_id_t *, char **); 229711890bcSjc156560 static int obj_array_delete(raid_obj_tab_t *, raid_obj_id_t, char **); 230711890bcSjc156560 static int obj_hsp_bind(raid_obj_tab_t *, int, raid_obj_id_t *, char **); 231711890bcSjc156560 static int obj_hsp_unbind(raid_obj_tab_t *, int, raid_obj_id_t *, char **); 232711890bcSjc156560 233711890bcSjc156560 static int raid_obj_create_system_obj(raid_obj_tab_t *); 234711890bcSjc156560 static raid_obj_id_t raid_obj_id_new(raid_obj_tab_t *); 235711890bcSjc156560 static void *raid_obj_attr_new(raid_obj_type_id_t); 236711890bcSjc156560 static raid_obj_id_t raid_obj_create(raid_obj_tab_t *, raid_obj_type_id_t); 237711890bcSjc156560 static int raid_obj_delete(raid_obj_tab_t *, raid_obj_id_t); 238711890bcSjc156560 static int raid_obj_add_org(raid_obj_tab_t *, raid_obj_id_t, raid_obj_id_t); 239711890bcSjc156560 static raid_obj_type_id_t raid_obj_get_type(raid_obj_tab_t *, raid_obj_id_t); 240711890bcSjc156560 static int raid_obj_set_type(raid_obj_tab_t *, raid_obj_id_t, 241711890bcSjc156560 raid_obj_type_id_t); 242711890bcSjc156560 static raid_obj_status_t raid_obj_get_status(raid_obj_tab_t *, raid_obj_id_t); 243711890bcSjc156560 static int raid_obj_set_status(raid_obj_tab_t *, raid_obj_id_t, 244711890bcSjc156560 raid_obj_status_t); 245711890bcSjc156560 static int raid_obj_clear_status(raid_obj_tab_t *, raid_obj_id_t, 246711890bcSjc156560 raid_obj_status_t); 247711890bcSjc156560 static raid_obj_id_t raid_obj_get_container(raid_obj_tab_t *, raid_obj_id_t); 248711890bcSjc156560 static int raid_obj_set_container(raid_obj_tab_t *, raid_obj_id_t, 249711890bcSjc156560 raid_obj_id_t); 250711890bcSjc156560 static raid_obj_id_t raid_obj_get_comp(raid_obj_tab_t *, raid_obj_id_t); 251711890bcSjc156560 static int raid_obj_set_comp(raid_obj_tab_t *, raid_obj_id_t, raid_obj_id_t); 252711890bcSjc156560 static raid_obj_id_t raid_obj_get_sibling(raid_obj_tab_t *, raid_obj_id_t); 253711890bcSjc156560 static int raid_obj_set_sibling(raid_obj_tab_t *, raid_obj_id_t, 254711890bcSjc156560 raid_obj_id_t); 255711890bcSjc156560 static void *raid_obj_get_data_ptr(raid_obj_tab_t *, raid_obj_id_t); 256711890bcSjc156560 static int raid_obj_set_data_ptr(raid_obj_tab_t *, raid_obj_id_t, void *); 257711890bcSjc156560 static raid_obj_handle_t raid_obj_get_handle(raid_obj_tab_t *, 258711890bcSjc156560 raid_obj_id_t); 259711890bcSjc156560 static int raid_obj_set_handle(raid_obj_tab_t *, raid_obj_id_t, 260711890bcSjc156560 raid_obj_handle_t); 261711890bcSjc156560 262711890bcSjc156560 static void raid_list_create(raid_list_t *, size_t); 263711890bcSjc156560 static void *raid_list_head(raid_list_t *); 264711890bcSjc156560 static void *raid_list_next(raid_list_t *, void *); 265711890bcSjc156560 static void raid_list_insert_tail(raid_list_t *, void *); 266711890bcSjc156560 static void raid_list_remove(raid_list_t *, void *); 267711890bcSjc156560 static void *raid_list_remove_head(raid_list_t *); 268711890bcSjc156560 static void *raid_list_find(raid_list_t *, raid_obj_id_t); 269711890bcSjc156560 static int raid_obj_tab_create(raid_obj_tab_t *, size_t); 270711890bcSjc156560 static void raid_obj_tab_destroy(raid_obj_tab_t *); 271711890bcSjc156560 static int raid_obj_tab_insert(raid_obj_tab_t *, raid_obj_id_t, void *); 272711890bcSjc156560 static void *raid_obj_tab_remove(raid_obj_tab_t *, raid_obj_id_t); 273711890bcSjc156560 static void *raid_obj_tab_find(raid_obj_tab_t *, raid_obj_id_t); 274711890bcSjc156560 static void raid_list_destroy(raid_list_t *); 275711890bcSjc156560 276711890bcSjc156560 static int controller_id_to_path(uint32_t, char *); 277711890bcSjc156560 static char *controller_id_to_driver_name(uint32_t); 278711890bcSjc156560 static void raid_plugin_init(); 279711890bcSjc156560 static raid_lib_t *raid_plugin_load(char *); 280711890bcSjc156560 static raid_lib_t *raid_find_lib(raid_obj_tab_t *, raid_obj_id_t); 281711890bcSjc156560 282711890bcSjc156560 /* Global object table */ 283711890bcSjc156560 static raid_obj_tab_t raid_tab_sys = {0, 0, NULL}; 284711890bcSjc156560 285711890bcSjc156560 /* Plug-in modules maintenance data structures */ 286711890bcSjc156560 static raid_lib_t *raid_lib_sys = NULL; 287711890bcSjc156560 288711890bcSjc156560 /* Handle table definition */ 289711890bcSjc156560 static struct { 290711890bcSjc156560 int handle_num; 291711890bcSjc156560 int used; 292711890bcSjc156560 int unused; 293711890bcSjc156560 handle_attr_t *handles; 294711890bcSjc156560 } raid_handle_sys = {0, 0, 0, NULL}; 295711890bcSjc156560 296711890bcSjc156560 /* 297711890bcSjc156560 * RAID object method table definition 298711890bcSjc156560 */ 299711890bcSjc156560 static raid_obj_op_t raid_obj_op_sys[OBJ_TYPE_ALL] = { 300711890bcSjc156560 {obj_sys_compnum, obj_sys_complist, NULL, NULL, NULL, 301711890bcSjc156560 NULL, NULL, NULL, NULL}, /* system object methods */ 302711890bcSjc156560 {obj_controller_compnum, obj_controller_complist, 303711890bcSjc156560 obj_controller_get_attr, NULL, obj_controller_act, 304711890bcSjc156560 NULL, NULL, NULL, NULL}, /* controller object methods */ 305711890bcSjc156560 {obj_array_compnum, obj_array_complist, obj_array_get_attr, 306711890bcSjc156560 obj_array_set_attr, NULL, obj_array_create, 307711890bcSjc156560 obj_array_delete, NULL, NULL}, /* array object methods */ 308711890bcSjc156560 {obj_disk_compnum, obj_disk_complist, obj_disk_get_attr, NULL, 309711890bcSjc156560 NULL, NULL, NULL, NULL, NULL}, /* disk object methods */ 310711890bcSjc156560 {NULL, NULL, obj_hsp_get_attr, NULL, NULL, NULL, NULL, obj_hsp_bind, 311711890bcSjc156560 obj_hsp_unbind}, /* hsp object methods */ 312711890bcSjc156560 {NULL, NULL, obj_arraypart_get_attr, NULL, NULL, NULL, NULL, 313711890bcSjc156560 NULL, NULL}, /* array part object methods */ 314711890bcSjc156560 {NULL, NULL, obj_diskseg_get_attr, NULL, NULL, NULL, NULL, NULL, NULL}, 315711890bcSjc156560 {NULL, NULL, obj_task_get_attr, NULL, NULL, NULL, NULL, 316*b449fa8aSyw161884 NULL, NULL}, /* disk seg object methods */ 317*b449fa8aSyw161884 {NULL, NULL, obj_prop_get_attr, NULL, NULL, NULL, NULL, 318*b449fa8aSyw161884 NULL, NULL} /* property object methods */ 319711890bcSjc156560 }; 320711890bcSjc156560 321711890bcSjc156560 /* 322711890bcSjc156560 * Mutex for multithread safe 323711890bcSjc156560 */ 324711890bcSjc156560 static mutex_t raidcfg_mp; 325711890bcSjc156560 326711890bcSjc156560 /* 327711890bcSjc156560 * RaidCfg library APIs 328711890bcSjc156560 */ 329711890bcSjc156560 const char * 330711890bcSjc156560 raidcfg_errstr(int err_code) 331711890bcSjc156560 { 332711890bcSjc156560 char *ret_val; 333711890bcSjc156560 334711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 335711890bcSjc156560 switch (err_code) { 336711890bcSjc156560 case SUCCESS: 337711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Operation succeeded.\n"); 338711890bcSjc156560 break; 339711890bcSjc156560 case STD_IOCTL: 340711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 341711890bcSjc156560 "Request standard IOCTL service.\n"); 342711890bcSjc156560 break; 343711890bcSjc156560 case ERR_DRIVER_NOT_FOUND: 344711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 345711890bcSjc156560 "Controller device can not be found.\n"); 346711890bcSjc156560 break; 347711890bcSjc156560 case ERR_DRIVER_OPEN: 348711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Can not open controller.\n"); 349711890bcSjc156560 break; 350711890bcSjc156560 case ERR_DRIVER_LOCK: 351711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Controller is locked.\n"); 352711890bcSjc156560 break; 353711890bcSjc156560 case ERR_DRIVER_CLOSED: 354711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Controller is not opened.\n"); 355711890bcSjc156560 break; 356711890bcSjc156560 case ERR_DRIVER_ACROSS: 357711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 358711890bcSjc156560 "Operation across multiple controllers.\n"); 359711890bcSjc156560 break; 360711890bcSjc156560 case ERR_ARRAY_LEVEL: 361711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 362711890bcSjc156560 "Operation not support with volume of this level.\n"); 363711890bcSjc156560 break; 364711890bcSjc156560 case ERR_ARRAY_SIZE: 365711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 366711890bcSjc156560 "Capacity of array out of range.\n"); 367711890bcSjc156560 break; 368711890bcSjc156560 case ERR_ARRAY_STRIPE_SIZE: 369711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Illegal stripe size.\n"); 370711890bcSjc156560 break; 371711890bcSjc156560 case ERR_ARRAY_CACHE_POLICY: 372711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 373711890bcSjc156560 "Illegal cache-write policy.\n"); 374711890bcSjc156560 break; 375711890bcSjc156560 case ERR_ARRAY_IN_USE: 376474adcbbSyw161884 ret_val = dgettext(TEXT_DOMAIN, "Array or disk in use.\n"); 377711890bcSjc156560 break; 378711890bcSjc156560 case ERR_ARRAY_TASK: 379711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Array has background task.\n"); 380711890bcSjc156560 break; 381711890bcSjc156560 case ERR_ARRAY_CONFIG: 382711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 383711890bcSjc156560 "Configuration over device node failed.\n"); 384711890bcSjc156560 break; 385711890bcSjc156560 case ERR_ARRAY_DISKNUM: 386711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Incorrect number of disks.\n"); 387711890bcSjc156560 break; 388711890bcSjc156560 case ERR_ARRAY_LAYOUT: 389711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Illegal array layout.\n"); 390711890bcSjc156560 break; 391711890bcSjc156560 case ERR_ARRAY_AMOUNT: 392711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Too many arrays.\n"); 393711890bcSjc156560 break; 394711890bcSjc156560 case ERR_DISK_STATE: 395711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 396711890bcSjc156560 "Incorrect disk status for current operation.\n"); 397711890bcSjc156560 break; 398711890bcSjc156560 case ERR_DISK_SPACE: 399711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "No enough disk space.\n"); 400711890bcSjc156560 break; 401711890bcSjc156560 case ERR_DISK_SEG_AMOUNT: 402711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Too many disk segments.\n"); 403711890bcSjc156560 break; 404711890bcSjc156560 case ERR_DISK_NOT_EMPTY: 405711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Disk has occupied space.\n"); 406711890bcSjc156560 break; 407711890bcSjc156560 case ERR_DISK_TASK: 408711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Disk has background task.\n"); 409711890bcSjc156560 break; 410711890bcSjc156560 case ERR_TASK_STATE: 411711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 412711890bcSjc156560 "Incorrect task state for current operation.\n"); 413711890bcSjc156560 break; 414711890bcSjc156560 case ERR_OP_ILLEGAL: 415711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Illegal operation.\n"); 416711890bcSjc156560 break; 417711890bcSjc156560 case ERR_OP_NO_IMPL: 418711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 419711890bcSjc156560 "Operation is not implemented.\n"); 420711890bcSjc156560 break; 421711890bcSjc156560 case ERR_OP_FAILED: 422474adcbbSyw161884 ret_val = dgettext(TEXT_DOMAIN, "Operation failed.\n"); 423711890bcSjc156560 break; 424711890bcSjc156560 case ERR_DEVICE_NOENT: 425711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Device not found.\n"); 426711890bcSjc156560 break; 427711890bcSjc156560 case ERR_DEVICE_TYPE: 428711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Illegal type of device.\n"); 429711890bcSjc156560 break; 430711890bcSjc156560 case ERR_DEVICE_DUP: 431711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Device record duplicated.\n"); 432711890bcSjc156560 break; 433711890bcSjc156560 case ERR_DEVICE_OVERFLOW: 434711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Too many devices.\n"); 435711890bcSjc156560 break; 436711890bcSjc156560 case ERR_DEVICE_UNCLEAN: 437711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Device pool is not clean.\n"); 438711890bcSjc156560 break; 439711890bcSjc156560 case ERR_DEVICE_INVALID: 440711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Device record is invalid.\n"); 441711890bcSjc156560 break; 442711890bcSjc156560 case ERR_NOMEM: 443711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, 444711890bcSjc156560 "Can not allocate more memory space.\n"); 445711890bcSjc156560 break; 446711890bcSjc156560 case ERR_PRIV: 447711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "No privilege.\n"); 448711890bcSjc156560 break; 449711890bcSjc156560 default: 450711890bcSjc156560 ret_val = dgettext(TEXT_DOMAIN, "Undefined error.\n"); 451711890bcSjc156560 } 452711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 453711890bcSjc156560 454711890bcSjc156560 return (ret_val); 455711890bcSjc156560 } 456711890bcSjc156560 457711890bcSjc156560 int 458711890bcSjc156560 raidcfg_get_controller(uint32_t controller_id) 459711890bcSjc156560 { 460711890bcSjc156560 raid_obj_id_t obj_id; 461711890bcSjc156560 int ret_val; 462711890bcSjc156560 463711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 464711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 465711890bcSjc156560 obj_id = obj_locate_controller(&raid_tab_sys, controller_id); 466711890bcSjc156560 if (obj_id < OBJ_NONE) { 467711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 468711890bcSjc156560 return (obj_id); 469711890bcSjc156560 } 470711890bcSjc156560 471711890bcSjc156560 if (obj_id == OBJ_NONE) { 472711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 473711890bcSjc156560 return (ERR_DEVICE_NOENT); 474711890bcSjc156560 } 475711890bcSjc156560 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id); 476711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 477711890bcSjc156560 478711890bcSjc156560 return (ret_val); 479711890bcSjc156560 } 480711890bcSjc156560 481711890bcSjc156560 int 482711890bcSjc156560 raidcfg_get_array(int controller_handle, uint64_t target_id, uint64_t lun) 483711890bcSjc156560 { 484711890bcSjc156560 raid_obj_id_t obj_id; 485711890bcSjc156560 raidcfg_array_t *attr; 486711890bcSjc156560 int ret_val; 487711890bcSjc156560 488711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 489711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 490711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, controller_handle); 491711890bcSjc156560 if (obj_id < OBJ_NONE) { 492711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 493711890bcSjc156560 return (obj_id); 494711890bcSjc156560 } 495711890bcSjc156560 496711890bcSjc156560 obj_id = obj_get_comp(&raid_tab_sys, obj_id, OBJ_TYPE_ARRAY); 497711890bcSjc156560 498711890bcSjc156560 while (obj_id > OBJ_NONE) { 499711890bcSjc156560 (void) obj_get_attr(&raid_tab_sys, obj_id, (void **)(&attr)); 500711890bcSjc156560 if (attr->tag.idl.target_id == target_id && 501711890bcSjc156560 attr->tag.idl.lun == lun) 502711890bcSjc156560 break; 503711890bcSjc156560 504711890bcSjc156560 obj_id = obj_get_sibling(&raid_tab_sys, obj_id); 505711890bcSjc156560 } 506711890bcSjc156560 507711890bcSjc156560 if (obj_id < OBJ_NONE) { 508711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 509711890bcSjc156560 return (obj_id); 510711890bcSjc156560 } 511711890bcSjc156560 if (obj_id == OBJ_NONE) { 512711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 513711890bcSjc156560 return (ERR_DEVICE_NOENT); 514711890bcSjc156560 } 515711890bcSjc156560 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id); 516711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 517711890bcSjc156560 518711890bcSjc156560 return (ret_val); 519711890bcSjc156560 } 520711890bcSjc156560 521711890bcSjc156560 int 522711890bcSjc156560 raidcfg_get_disk(int controller_handle, disk_tag_t tag) 523711890bcSjc156560 { 524711890bcSjc156560 raid_obj_id_t obj_id; 525711890bcSjc156560 raidcfg_disk_t *attr; 526711890bcSjc156560 int ret_val; 527711890bcSjc156560 528711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 529711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 530711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, controller_handle); 531711890bcSjc156560 if (obj_id < OBJ_NONE) { 532711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 533711890bcSjc156560 return (obj_id); 534711890bcSjc156560 } 535711890bcSjc156560 536711890bcSjc156560 obj_id = obj_get_comp(&raid_tab_sys, obj_id, OBJ_TYPE_DISK); 537711890bcSjc156560 538711890bcSjc156560 while (obj_id > OBJ_NONE) { 539711890bcSjc156560 (void) obj_get_attr(&raid_tab_sys, obj_id, (void **)(&attr)); 540711890bcSjc156560 if (attr->tag.cidl.bus == tag.cidl.bus && 541711890bcSjc156560 attr->tag.cidl.target_id == tag.cidl.target_id && 542711890bcSjc156560 attr->tag.cidl.lun == tag.cidl.lun) 543711890bcSjc156560 break; 544711890bcSjc156560 545711890bcSjc156560 obj_id = obj_get_sibling(&raid_tab_sys, obj_id); 546711890bcSjc156560 } 547711890bcSjc156560 548711890bcSjc156560 if (obj_id < OBJ_NONE) { 549711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 550711890bcSjc156560 return (obj_id); 551711890bcSjc156560 } 552711890bcSjc156560 if (obj_id == OBJ_NONE) { 553711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 554711890bcSjc156560 return (ERR_DEVICE_NOENT); 555711890bcSjc156560 } 556711890bcSjc156560 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id); 557711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 558711890bcSjc156560 559711890bcSjc156560 return (ret_val); 560711890bcSjc156560 } 561711890bcSjc156560 562711890bcSjc156560 int 563711890bcSjc156560 raidcfg_open_controller(int handle, char **plugin_err_str) 564711890bcSjc156560 { 565711890bcSjc156560 raid_obj_id_t obj_id; 566711890bcSjc156560 int ret; 567711890bcSjc156560 568711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 569711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 570711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 571711890bcSjc156560 if (obj_id < OBJ_NONE) { 572711890bcSjc156560 raid_handle_delete(handle); 573711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 574711890bcSjc156560 return (ERR_DEVICE_NOENT); 575711890bcSjc156560 } 576711890bcSjc156560 577711890bcSjc156560 ret = obj_controller_act(&raid_tab_sys, obj_id, 578711890bcSjc156560 ACT_CONTROLLER_OPEN, NULL, plugin_err_str); 579711890bcSjc156560 if (ret < SUCCESS) { 580711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 581711890bcSjc156560 return (ret); 582711890bcSjc156560 } 583711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 584711890bcSjc156560 585711890bcSjc156560 return (SUCCESS); 586711890bcSjc156560 } 587711890bcSjc156560 588711890bcSjc156560 int 589711890bcSjc156560 raidcfg_close_controller(int handle, char **plugin_err_str) 590711890bcSjc156560 { 591711890bcSjc156560 raid_obj_id_t obj_id; 592711890bcSjc156560 int ret; 593711890bcSjc156560 594711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 595711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 596711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 597711890bcSjc156560 if (obj_id < OBJ_NONE) { 598711890bcSjc156560 raid_handle_delete(handle); 599711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 600711890bcSjc156560 return (ERR_DEVICE_NOENT); 601711890bcSjc156560 } 602711890bcSjc156560 603711890bcSjc156560 ret = obj_controller_act(&raid_tab_sys, obj_id, 604711890bcSjc156560 ACT_CONTROLLER_CLOSE, NULL, plugin_err_str); 605711890bcSjc156560 if (ret < SUCCESS) { 606711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 607711890bcSjc156560 return (ret); 608711890bcSjc156560 } 609711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 610711890bcSjc156560 611711890bcSjc156560 return (SUCCESS); 612711890bcSjc156560 } 613711890bcSjc156560 614711890bcSjc156560 int 615711890bcSjc156560 raidcfg_get_type(int handle) 616711890bcSjc156560 { 617711890bcSjc156560 raid_obj_id_t obj_id; 618711890bcSjc156560 int ret_val; 619711890bcSjc156560 620711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 621711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 622711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 623711890bcSjc156560 if (obj_id < OBJ_NONE) { 624711890bcSjc156560 raid_handle_delete(handle); 625711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 626711890bcSjc156560 return (ERR_DEVICE_NOENT); 627711890bcSjc156560 } 628711890bcSjc156560 ret_val = raid_obj_get_type(&raid_tab_sys, obj_id); 629711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 630711890bcSjc156560 631711890bcSjc156560 return (ret_val); 632711890bcSjc156560 } 633711890bcSjc156560 634711890bcSjc156560 int 635711890bcSjc156560 raidcfg_get_attr(int handle, void *attr) 636711890bcSjc156560 { 637711890bcSjc156560 raid_obj_id_t obj_id; 638711890bcSjc156560 raid_obj_type_id_t type; 639711890bcSjc156560 void *data; 640711890bcSjc156560 int ret, size; 641711890bcSjc156560 642711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 643711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 644711890bcSjc156560 if (attr == NULL) { 645711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 646711890bcSjc156560 return (ERR_DEVICE_INVALID); 647711890bcSjc156560 } 648711890bcSjc156560 649711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 650711890bcSjc156560 if (obj_id < OBJ_NONE) { 651711890bcSjc156560 raid_handle_delete(handle); 652711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 653711890bcSjc156560 return (ERR_DEVICE_NOENT); 654711890bcSjc156560 } 655711890bcSjc156560 656711890bcSjc156560 type = raid_obj_get_type(&raid_tab_sys, obj_id); 657711890bcSjc156560 ret = obj_get_attr(&raid_tab_sys, obj_id, &data); 658711890bcSjc156560 if (ret < SUCCESS) { 659711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 660711890bcSjc156560 return (ret); 661711890bcSjc156560 } 662711890bcSjc156560 663711890bcSjc156560 switch (type) { 664711890bcSjc156560 case OBJ_TYPE_CONTROLLER: 665711890bcSjc156560 size = sizeof (controller_attr_t); 666711890bcSjc156560 break; 667711890bcSjc156560 case OBJ_TYPE_ARRAY: 668711890bcSjc156560 size = sizeof (array_attr_t); 669711890bcSjc156560 break; 670711890bcSjc156560 case OBJ_TYPE_HSP: 671711890bcSjc156560 { 672711890bcSjc156560 raidcfg_hsp_t *dst = attr; 673711890bcSjc156560 hsp_attr_t *src = data; 674711890bcSjc156560 controller_attr_t *ctlr_attr; 675711890bcSjc156560 array_attr_t *array_attr; 676711890bcSjc156560 677711890bcSjc156560 dst->associated_id = src->associated_id; 678711890bcSjc156560 dst->type = src->type; 679711890bcSjc156560 680711890bcSjc156560 obj_id = obj_get_controller(&raid_tab_sys, obj_id); 681711890bcSjc156560 ret = obj_get_attr(&raid_tab_sys, obj_id, 682711890bcSjc156560 (void **)(&ctlr_attr)); 683711890bcSjc156560 if (ret < SUCCESS) { 684711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 685711890bcSjc156560 return (ret); 686711890bcSjc156560 } 687711890bcSjc156560 688711890bcSjc156560 if (src->type == HSP_TYPE_LOCAL) { 689711890bcSjc156560 obj_id = obj_locate_array(&raid_tab_sys, 690711890bcSjc156560 ctlr_attr->controller_id, 691711890bcSjc156560 src->associated_id); 692711890bcSjc156560 ret = obj_get_attr(&raid_tab_sys, obj_id, 693711890bcSjc156560 (void **)(&array_attr)); 694711890bcSjc156560 if (ret < SUCCESS) { 695711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 696711890bcSjc156560 return (ret); 697711890bcSjc156560 } 698711890bcSjc156560 699711890bcSjc156560 dst->tag.idl.target_id = 700711890bcSjc156560 array_attr->tag.idl.target_id; 701711890bcSjc156560 dst->tag.idl.lun = array_attr->tag.idl.lun; 702711890bcSjc156560 } 703711890bcSjc156560 } 704711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 705711890bcSjc156560 return (SUCCESS); 706711890bcSjc156560 case OBJ_TYPE_DISK: 707711890bcSjc156560 size = sizeof (disk_attr_t); 708711890bcSjc156560 break; 709711890bcSjc156560 case OBJ_TYPE_ARRAY_PART: 710711890bcSjc156560 { 711711890bcSjc156560 raidcfg_arraypart_t *dst = attr; 712711890bcSjc156560 arraypart_attr_t *src = data; 713711890bcSjc156560 controller_attr_t *ctlr_attr; 714711890bcSjc156560 disk_attr_t *disk_attr; 715711890bcSjc156560 716711890bcSjc156560 dst->disk_id = src->disk_id; 717711890bcSjc156560 dst->offset = src->offset; 718711890bcSjc156560 dst->size = src->size; 719711890bcSjc156560 dst->state = src->state; 720711890bcSjc156560 721711890bcSjc156560 obj_id = obj_get_controller(&raid_tab_sys, obj_id); 722711890bcSjc156560 ret = obj_get_attr(&raid_tab_sys, obj_id, 723711890bcSjc156560 (void **)(&ctlr_attr)); 724711890bcSjc156560 if (ret < SUCCESS) { 725711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 726711890bcSjc156560 return (ret); 727711890bcSjc156560 } 728711890bcSjc156560 729711890bcSjc156560 obj_id = obj_locate_disk(&raid_tab_sys, 730711890bcSjc156560 ctlr_attr->controller_id, src->disk_id); 731711890bcSjc156560 if (obj_id <= OBJ_NONE) { 732711890bcSjc156560 dst->tag.cidl.bus = (uint64_t)OBJ_ATTR_NONE; 733711890bcSjc156560 dst->tag.cidl.target_id = 734711890bcSjc156560 (uint64_t)OBJ_ATTR_NONE; 735711890bcSjc156560 dst->tag.cidl.lun = (uint64_t)OBJ_ATTR_NONE; 736711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 737711890bcSjc156560 return (SUCCESS); 738711890bcSjc156560 } 739711890bcSjc156560 740711890bcSjc156560 ret = obj_get_attr(&raid_tab_sys, obj_id, 741711890bcSjc156560 (void **)(&disk_attr)); 742711890bcSjc156560 if (ret < SUCCESS) { 743711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 744711890bcSjc156560 return (ret); 745711890bcSjc156560 } 746711890bcSjc156560 747711890bcSjc156560 dst->tag.cidl.bus = disk_attr->tag.cidl.bus; 748711890bcSjc156560 dst->tag.cidl.target_id = disk_attr->tag.cidl.target_id; 749711890bcSjc156560 dst->tag.cidl.lun = disk_attr->tag.cidl.lun; 750711890bcSjc156560 } 751711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 752711890bcSjc156560 return (SUCCESS); 753711890bcSjc156560 case OBJ_TYPE_DISK_SEG: 754711890bcSjc156560 size = sizeof (diskseg_attr_t); 755711890bcSjc156560 break; 756711890bcSjc156560 case OBJ_TYPE_TASK: 757711890bcSjc156560 size = sizeof (task_attr_t); 758711890bcSjc156560 break; 759*b449fa8aSyw161884 case OBJ_TYPE_PROP: 760*b449fa8aSyw161884 { 761*b449fa8aSyw161884 property_attr_t *src = data, *dst = attr; 762*b449fa8aSyw161884 763*b449fa8aSyw161884 dst->prop_id = src->prop_id; 764*b449fa8aSyw161884 dst->prop_type = src->prop_type; 765*b449fa8aSyw161884 if (dst->prop_size == 0) { 766*b449fa8aSyw161884 dst->prop_size = src->prop_size; 767*b449fa8aSyw161884 (void) mutex_unlock(&raidcfg_mp); 768*b449fa8aSyw161884 return (SUCCESS); 769*b449fa8aSyw161884 } 770*b449fa8aSyw161884 771*b449fa8aSyw161884 if (dst->prop_size < src->prop_size) 772*b449fa8aSyw161884 size = dst->prop_size; 773*b449fa8aSyw161884 else 774*b449fa8aSyw161884 size = src->prop_size; 775*b449fa8aSyw161884 776*b449fa8aSyw161884 (void) memcpy(dst->prop, src->prop, size); 777*b449fa8aSyw161884 (void) mutex_unlock(&raidcfg_mp); 778*b449fa8aSyw161884 return (SUCCESS); 779*b449fa8aSyw161884 } 780*b449fa8aSyw161884 break; 781711890bcSjc156560 default: 782711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 783711890bcSjc156560 return (ERR_DEVICE_TYPE); 784711890bcSjc156560 } 785711890bcSjc156560 786711890bcSjc156560 (void) memcpy(attr, data, size); 787711890bcSjc156560 788711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 789711890bcSjc156560 return (ret); 790711890bcSjc156560 } 791711890bcSjc156560 792711890bcSjc156560 int 793711890bcSjc156560 raidcfg_get_container(int handle) 794711890bcSjc156560 { 795711890bcSjc156560 raid_obj_id_t obj_id; 796711890bcSjc156560 int ret_val; 797711890bcSjc156560 798711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 799711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 800711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 801711890bcSjc156560 if (obj_id < OBJ_NONE) { 802711890bcSjc156560 raid_handle_delete(handle); 803711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 804711890bcSjc156560 return (ERR_DEVICE_NOENT); 805711890bcSjc156560 } 806711890bcSjc156560 807711890bcSjc156560 obj_id = raid_obj_get_container(&raid_tab_sys, obj_id); 808711890bcSjc156560 if (obj_id < OBJ_NONE) { 809711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 810711890bcSjc156560 return (obj_id); 811711890bcSjc156560 } 812711890bcSjc156560 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id); 813711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 814711890bcSjc156560 815711890bcSjc156560 return (ret_val); 816711890bcSjc156560 } 817711890bcSjc156560 818711890bcSjc156560 int 819711890bcSjc156560 raidcfg_list_head(int handle, raid_obj_type_id_t type) 820711890bcSjc156560 { 821711890bcSjc156560 raid_obj_id_t obj_id; 822711890bcSjc156560 int ret_val; 823711890bcSjc156560 824711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 825711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 826711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 827711890bcSjc156560 if (obj_id < OBJ_NONE) { 828711890bcSjc156560 raid_handle_delete(handle); 829711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 830711890bcSjc156560 return (ERR_DEVICE_NOENT); 831711890bcSjc156560 } 832711890bcSjc156560 833711890bcSjc156560 obj_id = obj_get_comp(&raid_tab_sys, obj_id, type); 834711890bcSjc156560 if (obj_id < OBJ_NONE) { 835711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 836711890bcSjc156560 return (obj_id); 837711890bcSjc156560 } 838711890bcSjc156560 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id); 839711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 840711890bcSjc156560 841711890bcSjc156560 return (ret_val); 842711890bcSjc156560 } 843711890bcSjc156560 844711890bcSjc156560 int 845711890bcSjc156560 raidcfg_list_next(int handle) 846711890bcSjc156560 { 847711890bcSjc156560 raid_obj_id_t obj_id; 848711890bcSjc156560 int ret_val; 849711890bcSjc156560 850711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 851711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 852711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 853711890bcSjc156560 if (obj_id < OBJ_NONE) { 854711890bcSjc156560 raid_handle_delete(handle); 855711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 856711890bcSjc156560 return (ERR_DEVICE_NOENT); 857711890bcSjc156560 } 858711890bcSjc156560 859711890bcSjc156560 obj_id = obj_get_sibling(&raid_tab_sys, obj_id); 860711890bcSjc156560 if (obj_id < OBJ_NONE) { 861711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 862711890bcSjc156560 return (obj_id); 863711890bcSjc156560 } 864711890bcSjc156560 ret_val = raid_obj_to_handle(&raid_tab_sys, obj_id); 865711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 866711890bcSjc156560 867711890bcSjc156560 return (ret_val); 868711890bcSjc156560 } 869711890bcSjc156560 870711890bcSjc156560 int 871711890bcSjc156560 raidcfg_set_attr(int handle, uint32_t set_cmd, void *value, 872711890bcSjc156560 char **plugin_err_str) 873711890bcSjc156560 { 874711890bcSjc156560 raid_obj_id_t obj_id; 875711890bcSjc156560 raid_obj_type_id_t type; 876711890bcSjc156560 int ret; 877711890bcSjc156560 878711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 879711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 880711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 881711890bcSjc156560 if (obj_id < OBJ_NONE) { 882711890bcSjc156560 raid_handle_delete(handle); 883711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 884711890bcSjc156560 return (ERR_DEVICE_NOENT); 885711890bcSjc156560 } 886711890bcSjc156560 887711890bcSjc156560 type = raid_obj_get_type(&raid_tab_sys, obj_id); 888711890bcSjc156560 if (raid_obj_op_sys[type].set_attr == NULL) { 889711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 890711890bcSjc156560 return (ERR_OP_NO_IMPL); 891711890bcSjc156560 } 892711890bcSjc156560 893711890bcSjc156560 ret = raid_obj_op_sys[type].set_attr(&raid_tab_sys, 894711890bcSjc156560 obj_id, set_cmd, value, plugin_err_str); 895711890bcSjc156560 896711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 897711890bcSjc156560 return (ret); 898711890bcSjc156560 } 899711890bcSjc156560 900711890bcSjc156560 int 901711890bcSjc156560 raidcfg_update_fw(int handle, char *file, char **plugin_err_str) 902711890bcSjc156560 { 903711890bcSjc156560 raid_obj_id_t obj_id; 904711890bcSjc156560 int ret; 905711890bcSjc156560 906711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 907711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 908711890bcSjc156560 obj_id = raid_handle_to_obj(&raid_tab_sys, handle); 909711890bcSjc156560 if (obj_id < OBJ_NONE) { 910711890bcSjc156560 raid_handle_delete(handle); 911711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 912711890bcSjc156560 return (ERR_DEVICE_NOENT); 913711890bcSjc156560 } 914711890bcSjc156560 915711890bcSjc156560 if (raid_obj_get_type(&raid_tab_sys, obj_id) != OBJ_TYPE_CONTROLLER) { 916711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 917711890bcSjc156560 return (ERR_OP_NO_IMPL); 918711890bcSjc156560 } 919711890bcSjc156560 920711890bcSjc156560 ret = raid_obj_op_sys[OBJ_TYPE_CONTROLLER].act(&raid_tab_sys, 921711890bcSjc156560 obj_id, ACT_CONTROLLER_FLASH_FW, file, plugin_err_str); 922711890bcSjc156560 923711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 924711890bcSjc156560 return (ret); 925711890bcSjc156560 } 926711890bcSjc156560 927711890bcSjc156560 int 928711890bcSjc156560 raidcfg_create_array(int num_of_comps, int *disk_handles, 929711890bcSjc156560 uint32_t raid_level, uint64_t size, uint32_t stripe_size, 930711890bcSjc156560 char **plugin_err_str) 931711890bcSjc156560 { 932711890bcSjc156560 raid_obj_id_t *disk_obj_ids, obj_id; 933711890bcSjc156560 array_attr_t *array_attr; 934711890bcSjc156560 raid_obj_handle_t array_handle; 935711890bcSjc156560 int i, ret; 936711890bcSjc156560 937711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 938711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 939711890bcSjc156560 940711890bcSjc156560 disk_obj_ids = calloc(num_of_comps, sizeof (raid_obj_id_t)); 941711890bcSjc156560 if (disk_obj_ids == NULL) { 942711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 943711890bcSjc156560 return (ERR_NOMEM); 944711890bcSjc156560 } 945711890bcSjc156560 946711890bcSjc156560 /* convert disk handles into disk object ids; */ 947711890bcSjc156560 for (i = 0; i < num_of_comps; ++i) { 948711890bcSjc156560 if (*(disk_handles + i) == OBJ_SEPARATOR_BEGIN || 949711890bcSjc156560 *(disk_handles + i) == OBJ_SEPARATOR_END) { 950711890bcSjc156560 *(disk_obj_ids + i) = *(disk_handles + i); 951711890bcSjc156560 continue; 952711890bcSjc156560 } 953711890bcSjc156560 954711890bcSjc156560 *(disk_obj_ids + i) = raid_handle_to_obj(&raid_tab_sys, 955711890bcSjc156560 *(disk_handles + i)); 956711890bcSjc156560 if (raid_obj_get_type(&raid_tab_sys, *(disk_obj_ids + i)) != 957711890bcSjc156560 OBJ_TYPE_DISK) { 958711890bcSjc156560 free(disk_obj_ids); 959711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 960711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 961711890bcSjc156560 return (ERR_DEVICE_TYPE); 962711890bcSjc156560 } 963711890bcSjc156560 } 964711890bcSjc156560 965711890bcSjc156560 /* Create an empty array object */ 966711890bcSjc156560 obj_id = raid_obj_create(&raid_tab_sys, OBJ_TYPE_ARRAY); 967711890bcSjc156560 if (obj_id < OBJ_NONE) { 968711890bcSjc156560 free(disk_obj_ids); 969711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 970711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 971711890bcSjc156560 return (obj_id); 972711890bcSjc156560 } 973711890bcSjc156560 (void) raid_obj_clear_status(&raid_tab_sys, obj_id, 974711890bcSjc156560 OBJ_STATUS_CMD_CLEAN); 975711890bcSjc156560 976711890bcSjc156560 array_attr = raid_obj_get_data_ptr(&raid_tab_sys, obj_id); 977711890bcSjc156560 array_attr->array_id = (uint32_t)OBJ_ATTR_NONE; 978711890bcSjc156560 array_attr->raid_level = raid_level; 979711890bcSjc156560 array_attr->capacity = size; 980711890bcSjc156560 array_attr->stripe_size = stripe_size; 981711890bcSjc156560 array_attr->write_policy = CACHE_WR_ON; 982711890bcSjc156560 array_attr->read_policy = CACHE_RD_ON; 983711890bcSjc156560 984711890bcSjc156560 ret = raid_obj_op_sys[OBJ_TYPE_ARRAY].create_obj(&raid_tab_sys, obj_id, 985711890bcSjc156560 num_of_comps, disk_obj_ids, plugin_err_str); 986711890bcSjc156560 free(disk_obj_ids); 987711890bcSjc156560 988711890bcSjc156560 if (ret < SUCCESS) { 989711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 990711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 991711890bcSjc156560 return (ret); 992711890bcSjc156560 } 993711890bcSjc156560 994711890bcSjc156560 /* create_obj() method should put the array object in the device tree */ 995711890bcSjc156560 array_handle = raid_obj_to_handle(&raid_tab_sys, obj_id); 996711890bcSjc156560 997711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 998711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 999711890bcSjc156560 return (array_handle); 1000711890bcSjc156560 } 1001711890bcSjc156560 1002711890bcSjc156560 int 1003711890bcSjc156560 raidcfg_delete_array(int array_handle, char **plugin_err_str) 1004711890bcSjc156560 { 1005711890bcSjc156560 raid_obj_id_t array_obj_id; 1006711890bcSjc156560 int ret; 1007711890bcSjc156560 1008711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 1009711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1010711890bcSjc156560 1011711890bcSjc156560 if (raidcfg_get_type(array_handle) != OBJ_TYPE_ARRAY) { 1012711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1013711890bcSjc156560 return (ERR_DEVICE_TYPE); 1014711890bcSjc156560 } 1015711890bcSjc156560 1016711890bcSjc156560 array_obj_id = raid_handle_to_obj(&raid_tab_sys, array_handle); 1017711890bcSjc156560 if (array_obj_id < OBJ_NONE) { 1018711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1019711890bcSjc156560 return (array_obj_id); 1020711890bcSjc156560 } 1021711890bcSjc156560 if (array_obj_id == OBJ_NONE) { 1022711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1023711890bcSjc156560 return (ERR_DEVICE_INVALID); 1024711890bcSjc156560 } 1025711890bcSjc156560 1026711890bcSjc156560 ret = raid_obj_op_sys[OBJ_TYPE_ARRAY].delete_obj(&raid_tab_sys, 1027711890bcSjc156560 array_obj_id, plugin_err_str); 1028711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1029711890bcSjc156560 1030711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1031711890bcSjc156560 return (ret); 1032711890bcSjc156560 } 1033711890bcSjc156560 1034711890bcSjc156560 int 1035711890bcSjc156560 raidcfg_set_hsp(int num, raidcfg_hsp_relation_t *hsp_relations, 1036711890bcSjc156560 char **plugin_err_str) 1037711890bcSjc156560 { 1038711890bcSjc156560 raid_obj_id_t disk_obj_id, array_obj_id; 1039711890bcSjc156560 raid_obj_id_t *hsp_relation_objs; 1040711890bcSjc156560 int ret, i; 1041711890bcSjc156560 1042711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 1043711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1044711890bcSjc156560 if ((num == 0) || (hsp_relations == NULL)) { 1045711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1046711890bcSjc156560 return (ERR_OP_ILLEGAL); 1047711890bcSjc156560 } 1048711890bcSjc156560 1049711890bcSjc156560 hsp_relation_objs = malloc(2 * num * sizeof (raid_obj_id_t)); 1050711890bcSjc156560 if (hsp_relation_objs == NULL) { 1051711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1052711890bcSjc156560 return (ERR_NOMEM); 1053711890bcSjc156560 } 1054711890bcSjc156560 1055711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1056711890bcSjc156560 1057711890bcSjc156560 for (i = 0; i < num; ++ i) { 1058711890bcSjc156560 if (hsp_relations->array_handle != OBJ_ATTR_NONE) { 1059711890bcSjc156560 array_obj_id = raid_handle_to_obj(&raid_tab_sys, 1060711890bcSjc156560 hsp_relations[i].array_handle); 1061711890bcSjc156560 if (array_obj_id < OBJ_NONE) { 1062711890bcSjc156560 free(hsp_relation_objs); 1063711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1064711890bcSjc156560 return (array_obj_id); 1065711890bcSjc156560 } 1066711890bcSjc156560 if (array_obj_id == OBJ_NONE) { 1067711890bcSjc156560 (void) free(hsp_relation_objs); 1068711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1069711890bcSjc156560 return (ERR_DEVICE_NOENT); 1070711890bcSjc156560 } 1071711890bcSjc156560 if (raidcfg_get_type(hsp_relations[i].array_handle) != 1072711890bcSjc156560 OBJ_TYPE_ARRAY) { 1073711890bcSjc156560 free(hsp_relation_objs); 1074711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1075711890bcSjc156560 return (ERR_DEVICE_TYPE); 1076711890bcSjc156560 } 1077711890bcSjc156560 } else 1078711890bcSjc156560 array_obj_id = OBJ_ATTR_NONE; 1079711890bcSjc156560 1080711890bcSjc156560 disk_obj_id = raid_handle_to_obj(&raid_tab_sys, 1081711890bcSjc156560 hsp_relations[i].disk_handle); 1082711890bcSjc156560 if (disk_obj_id < OBJ_NONE) { 1083711890bcSjc156560 free(hsp_relation_objs); 1084711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1085711890bcSjc156560 return (disk_obj_id); 1086711890bcSjc156560 } 1087711890bcSjc156560 if (disk_obj_id == OBJ_NONE) { 1088711890bcSjc156560 free(hsp_relation_objs); 1089711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1090711890bcSjc156560 return (ERR_DEVICE_NOENT); 1091711890bcSjc156560 } 1092711890bcSjc156560 if (raidcfg_get_type(hsp_relations[i].disk_handle) != 1093711890bcSjc156560 OBJ_TYPE_DISK) { 1094711890bcSjc156560 free(hsp_relation_objs); 1095711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1096711890bcSjc156560 return (ERR_DEVICE_TYPE); 1097711890bcSjc156560 } 1098711890bcSjc156560 1099711890bcSjc156560 hsp_relation_objs[2 * i] = array_obj_id; 1100711890bcSjc156560 hsp_relation_objs[2 * i + 1] = disk_obj_id; 1101711890bcSjc156560 } 1102711890bcSjc156560 1103711890bcSjc156560 ret = raid_obj_op_sys[OBJ_TYPE_HSP].bind_obj(&raid_tab_sys, num, 1104711890bcSjc156560 hsp_relation_objs, plugin_err_str); 1105711890bcSjc156560 1106711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1107711890bcSjc156560 free(hsp_relation_objs); 1108711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1109711890bcSjc156560 1110711890bcSjc156560 return (ret); 1111711890bcSjc156560 } 1112711890bcSjc156560 1113711890bcSjc156560 int 1114711890bcSjc156560 raidcfg_unset_hsp(int num, raidcfg_hsp_relation_t *hsp_relations, 1115711890bcSjc156560 char **plugin_err_str) 1116711890bcSjc156560 { 1117711890bcSjc156560 raid_obj_id_t disk_obj_id, array_obj_id; 1118711890bcSjc156560 raid_obj_id_t *hsp_relation_objs; 1119711890bcSjc156560 int ret, i; 1120711890bcSjc156560 1121711890bcSjc156560 (void) mutex_lock(&raidcfg_mp); 1122711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1123711890bcSjc156560 if ((num == 0) || (hsp_relations == NULL)) { 1124711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1125711890bcSjc156560 return (ERR_OP_ILLEGAL); 1126711890bcSjc156560 } 1127711890bcSjc156560 1128711890bcSjc156560 hsp_relation_objs = malloc(2 * num * sizeof (raid_obj_id_t)); 1129711890bcSjc156560 if (hsp_relation_objs == NULL) { 1130711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1131711890bcSjc156560 return (ERR_NOMEM); 1132711890bcSjc156560 } 1133711890bcSjc156560 1134711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1135711890bcSjc156560 1136711890bcSjc156560 for (i = 0; i < num; ++ i) { 1137711890bcSjc156560 if (hsp_relations->array_handle != OBJ_ATTR_NONE) { 1138711890bcSjc156560 array_obj_id = raid_handle_to_obj(&raid_tab_sys, 1139711890bcSjc156560 hsp_relations[i].array_handle); 1140711890bcSjc156560 if (array_obj_id < OBJ_NONE) { 1141711890bcSjc156560 free(hsp_relation_objs); 1142711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1143711890bcSjc156560 return (array_obj_id); 1144711890bcSjc156560 } 1145711890bcSjc156560 if (array_obj_id == OBJ_NONE) { 1146711890bcSjc156560 free(hsp_relation_objs); 1147711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1148711890bcSjc156560 return (ERR_DEVICE_NOENT); 1149711890bcSjc156560 } 1150711890bcSjc156560 if (raidcfg_get_type(hsp_relations[i].array_handle) != 1151711890bcSjc156560 OBJ_TYPE_ARRAY) { 1152711890bcSjc156560 free(hsp_relation_objs); 1153711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1154711890bcSjc156560 return (ERR_DEVICE_TYPE); 1155711890bcSjc156560 } 1156711890bcSjc156560 } else 1157711890bcSjc156560 array_obj_id = OBJ_ATTR_NONE; 1158711890bcSjc156560 1159711890bcSjc156560 disk_obj_id = raid_handle_to_obj(&raid_tab_sys, 1160711890bcSjc156560 hsp_relations[i].disk_handle); 1161711890bcSjc156560 if (disk_obj_id < OBJ_NONE) { 1162711890bcSjc156560 free(hsp_relation_objs); 1163711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1164711890bcSjc156560 return (disk_obj_id); 1165711890bcSjc156560 } 1166711890bcSjc156560 if (disk_obj_id == OBJ_NONE) { 1167711890bcSjc156560 free(hsp_relation_objs); 1168711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1169711890bcSjc156560 return (ERR_DEVICE_NOENT); 1170711890bcSjc156560 } 1171711890bcSjc156560 if (raidcfg_get_type(hsp_relations[i].disk_handle) != 1172711890bcSjc156560 OBJ_TYPE_DISK) { 1173711890bcSjc156560 free(hsp_relation_objs); 1174711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1175711890bcSjc156560 return (ERR_DEVICE_TYPE); 1176711890bcSjc156560 } 1177711890bcSjc156560 1178711890bcSjc156560 hsp_relation_objs[2 * i] = array_obj_id; 1179711890bcSjc156560 hsp_relation_objs[2 * i + 1] = disk_obj_id; 1180711890bcSjc156560 } 1181711890bcSjc156560 1182711890bcSjc156560 ret = raid_obj_op_sys[OBJ_TYPE_HSP].unbind_obj(&raid_tab_sys, 1183711890bcSjc156560 num, hsp_relation_objs, plugin_err_str); 1184711890bcSjc156560 1185711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1186711890bcSjc156560 free(hsp_relation_objs); 1187711890bcSjc156560 (void) mutex_unlock(&raidcfg_mp); 1188711890bcSjc156560 1189711890bcSjc156560 return (ret); 1190711890bcSjc156560 } 1191711890bcSjc156560 1192711890bcSjc156560 /* 1193711890bcSjc156560 * RaidCfg lib routines 1194711890bcSjc156560 */ 1195711890bcSjc156560 void 1196711890bcSjc156560 raidcfg_init(void) 1197711890bcSjc156560 { 1198711890bcSjc156560 (void) mutex_init(&raidcfg_mp, NULL, NULL); 1199711890bcSjc156560 raid_plugin_init(); 1200711890bcSjc156560 (void) raid_handle_init(); 1201711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1202711890bcSjc156560 } 1203711890bcSjc156560 1204711890bcSjc156560 void 1205711890bcSjc156560 raidcfg_fini(void) 1206711890bcSjc156560 { 1207711890bcSjc156560 /* 1208711890bcSjc156560 * Need to close all opened controllers before destroying object table 1209711890bcSjc156560 */ 1210711890bcSjc156560 (void) obj_rescan(&raid_tab_sys); 1211711890bcSjc156560 raid_handle_fini(); 1212711890bcSjc156560 raid_obj_tab_destroy(&raid_tab_sys); 1213711890bcSjc156560 raid_plugin_init(); 1214711890bcSjc156560 (void) mutex_destroy(&raidcfg_mp); 1215711890bcSjc156560 } 1216711890bcSjc156560 1217711890bcSjc156560 /* 1218711890bcSjc156560 * Support routines 1219711890bcSjc156560 */ 1220711890bcSjc156560 static int 1221711890bcSjc156560 intcompare(const void *p1, const void *p2) 1222711890bcSjc156560 { 1223711890bcSjc156560 int i, j; 1224711890bcSjc156560 i = *((int *)p1); 1225711890bcSjc156560 j = *((int *)p2); 1226711890bcSjc156560 return (i - j); 1227711890bcSjc156560 } 1228711890bcSjc156560 1229711890bcSjc156560 static uint64_t 1230711890bcSjc156560 raid_space_noalign(raid_obj_tab_t *raid_tab, uint32_t raid_level, int num, 1231711890bcSjc156560 raid_obj_id_t *disk_objs, arraypart_attr_t *arraypart_attrs) 1232711890bcSjc156560 { 1233711890bcSjc156560 disk_attr_t *disk_attr; 1234711890bcSjc156560 diskseg_attr_t *diskseg_attr; 1235711890bcSjc156560 raid_obj_id_t obj_id; 1236711890bcSjc156560 uint64_t offset, capacity; 1237711890bcSjc156560 int i, disk_num, sub_array_num, disk_layer; 1238711890bcSjc156560 1239711890bcSjc156560 /* Find out the maximum available space for all disks */ 1240711890bcSjc156560 for (i = 0; i < num; ++i) { 1241711890bcSjc156560 if ((disk_objs[i] == OBJ_SEPARATOR_BEGIN) || 1242711890bcSjc156560 (disk_objs[i] == OBJ_SEPARATOR_END)) 1243711890bcSjc156560 continue; 1244711890bcSjc156560 1245711890bcSjc156560 (void) obj_get_attr(raid_tab, disk_objs[i], 1246711890bcSjc156560 (void **)(&disk_attr)); 1247711890bcSjc156560 obj_id = obj_get_comp(raid_tab, disk_objs[i], 1248711890bcSjc156560 OBJ_TYPE_DISK_SEG); 1249711890bcSjc156560 if (obj_id == OBJ_NONE) { 1250711890bcSjc156560 arraypart_attrs[i].offset = 0; 1251711890bcSjc156560 arraypart_attrs[i].size = disk_attr->capacity; 1252711890bcSjc156560 continue; 1253711890bcSjc156560 } 1254711890bcSjc156560 1255711890bcSjc156560 (void) obj_get_attr(raid_tab, obj_id, (void **) 1256711890bcSjc156560 (&diskseg_attr)); 1257711890bcSjc156560 arraypart_attrs[i].offset = 0; 1258711890bcSjc156560 arraypart_attrs[i].size = diskseg_attr->offset; 1259711890bcSjc156560 offset = diskseg_attr->offset + diskseg_attr->size; 1260711890bcSjc156560 1261711890bcSjc156560 while ((obj_id = obj_get_sibling(raid_tab, obj_id)) != 1262711890bcSjc156560 OBJ_NONE) { 1263711890bcSjc156560 (void) obj_get_attr(raid_tab, obj_id, 1264711890bcSjc156560 (void **)(&diskseg_attr)); 1265711890bcSjc156560 if ((diskseg_attr->offset - offset) > 1266711890bcSjc156560 arraypart_attrs[i].size) { 1267711890bcSjc156560 arraypart_attrs[i].offset = offset; 1268700682b8Syw161884 arraypart_attrs[i].size = diskseg_attr->offset - 1269700682b8Syw161884 offset; 1270711890bcSjc156560 } 1271711890bcSjc156560 1272711890bcSjc156560 offset = diskseg_attr->offset + diskseg_attr->size; 1273711890bcSjc156560 } 1274711890bcSjc156560 1275711890bcSjc156560 if ((disk_attr->capacity - offset) > arraypart_attrs[i].size) { 1276711890bcSjc156560 arraypart_attrs[i].offset = offset; 1277700682b8Syw161884 arraypart_attrs[i].size = disk_attr->capacity - 1278700682b8Syw161884 offset; 1279711890bcSjc156560 } 1280711890bcSjc156560 } 1281711890bcSjc156560 1282711890bcSjc156560 capacity = OBJ_ATTR_NONE; 1283711890bcSjc156560 disk_num = 0; 1284711890bcSjc156560 disk_layer = 0; 1285711890bcSjc156560 sub_array_num = 0; 1286711890bcSjc156560 for (i = 0; i < num; ++i) { 1287711890bcSjc156560 if (disk_objs[i] == OBJ_SEPARATOR_BEGIN) { 1288711890bcSjc156560 ++ disk_layer; 1289711890bcSjc156560 continue; 1290711890bcSjc156560 } 1291711890bcSjc156560 if (disk_objs[i] == OBJ_SEPARATOR_END) { 1292711890bcSjc156560 -- disk_layer; 1293711890bcSjc156560 if (disk_layer != 0) 1294711890bcSjc156560 ++ sub_array_num; 1295711890bcSjc156560 continue; 1296711890bcSjc156560 } 1297711890bcSjc156560 1298711890bcSjc156560 if (capacity > arraypart_attrs[i].size) 1299711890bcSjc156560 capacity = arraypart_attrs[i].size; 1300711890bcSjc156560 ++disk_num; 1301711890bcSjc156560 } 1302711890bcSjc156560 1303711890bcSjc156560 switch (raid_level) { 1304711890bcSjc156560 case RAID_LEVEL_0: 1305711890bcSjc156560 capacity = capacity * disk_num; 1306711890bcSjc156560 break; 1307711890bcSjc156560 case RAID_LEVEL_1: 1308711890bcSjc156560 capacity = capacity * disk_num / 2; 1309711890bcSjc156560 break; 1310711890bcSjc156560 case RAID_LEVEL_1E: 1311711890bcSjc156560 capacity = capacity * disk_num / 2; 1312711890bcSjc156560 break; 1313711890bcSjc156560 case RAID_LEVEL_5: 1314711890bcSjc156560 capacity = capacity * (disk_num - 1); 1315711890bcSjc156560 break; 1316711890bcSjc156560 case RAID_LEVEL_10: 1317711890bcSjc156560 capacity = capacity * disk_num / 2; 1318711890bcSjc156560 break; 1319711890bcSjc156560 case RAID_LEVEL_50: 1320711890bcSjc156560 capacity = capacity * (disk_num - sub_array_num); 1321711890bcSjc156560 break; 1322711890bcSjc156560 default: 1323711890bcSjc156560 return (ERR_ARRAY_LEVEL); 1324711890bcSjc156560 break; 1325711890bcSjc156560 } 1326711890bcSjc156560 1327711890bcSjc156560 return (capacity); 1328711890bcSjc156560 } 1329711890bcSjc156560 1330711890bcSjc156560 /* 1331711890bcSjc156560 * Raid handle maintenance routines 1332711890bcSjc156560 */ 1333711890bcSjc156560 static int 1334711890bcSjc156560 raid_handle_init() 1335711890bcSjc156560 { 1336711890bcSjc156560 int i; 1337711890bcSjc156560 void *ptr; 1338711890bcSjc156560 1339711890bcSjc156560 raid_handle_sys.handle_num += HANDLER_SLOTS; 1340711890bcSjc156560 ptr = realloc(raid_handle_sys.handles, 1341711890bcSjc156560 raid_handle_sys.handle_num * sizeof (handle_attr_t)); 1342711890bcSjc156560 if (ptr == NULL) 1343711890bcSjc156560 return (ERR_NOMEM); 1344711890bcSjc156560 raid_handle_sys.handles = ptr; 1345711890bcSjc156560 1346711890bcSjc156560 /* Clean up the new allocated handles */ 1347711890bcSjc156560 for (i = raid_handle_sys.handle_num - HANDLER_SLOTS; 1348711890bcSjc156560 i < raid_handle_sys.handle_num; ++i) { 1349711890bcSjc156560 raid_handle_sys.handles[i].type = OBJ_TYPE_ALL; 1350711890bcSjc156560 raid_handle_sys.handles[i].next = i + 1; 1351711890bcSjc156560 } 1352711890bcSjc156560 1353711890bcSjc156560 /* For the first time of allocation, set up the system object handle */ 1354711890bcSjc156560 if (raid_handle_sys.handle_num == HANDLER_SLOTS) { 1355711890bcSjc156560 raid_handle_sys.handles[0].type = OBJ_TYPE_SYSTEM; 1356711890bcSjc156560 raid_handle_sys.handles[0].next = 0; 1357711890bcSjc156560 raid_handle_sys.unused = 1; 1358711890bcSjc156560 raid_handle_sys.used = 0; 1359711890bcSjc156560 } 1360711890bcSjc156560 return (SUCCESS); 1361711890bcSjc156560 } 1362711890bcSjc156560 1363711890bcSjc156560 static void 1364711890bcSjc156560 raid_handle_fini() 1365711890bcSjc156560 { 1366711890bcSjc156560 raid_obj_handle_t i; 1367711890bcSjc156560 1368711890bcSjc156560 i = raid_handle_sys.used; 1369711890bcSjc156560 1370711890bcSjc156560 /* Close all opened controllers */ 1371711890bcSjc156560 while (i != 0) { 1372711890bcSjc156560 if ((raid_handle_sys.handles[i].type == OBJ_TYPE_CONTROLLER) && 1373711890bcSjc156560 (raid_handle_sys.handles[i].fd != 0) && 1374711890bcSjc156560 (raid_handle_sys.handles[i].raid_lib != NULL)) 1375711890bcSjc156560 raid_handle_sys.handles[i].raid_lib->close_controller( 1376711890bcSjc156560 raid_handle_sys.handles[i].controller_id, NULL); 1377711890bcSjc156560 i = raid_handle_sys.handles[i].next; 1378711890bcSjc156560 } 1379711890bcSjc156560 1380711890bcSjc156560 /* Clean up handle space */ 1381711890bcSjc156560 raid_handle_sys.handle_num = 0; 1382711890bcSjc156560 raid_handle_sys.unused = 0; 1383711890bcSjc156560 raid_handle_sys.used = 0; 1384711890bcSjc156560 free(raid_handle_sys.handles); 1385711890bcSjc156560 raid_handle_sys.handles = NULL; 1386711890bcSjc156560 } 1387711890bcSjc156560 1388711890bcSjc156560 static raid_obj_handle_t 1389711890bcSjc156560 raid_handle_new(raid_obj_type_id_t type) 1390711890bcSjc156560 { 1391711890bcSjc156560 int ret; 1392711890bcSjc156560 1393711890bcSjc156560 if (raid_handle_sys.unused == raid_handle_sys.handle_num - 1) { 1394711890bcSjc156560 ret = raid_handle_init(); 1395711890bcSjc156560 if (ret < SUCCESS) 1396711890bcSjc156560 return (ret); 1397711890bcSjc156560 } 1398711890bcSjc156560 1399711890bcSjc156560 ret = raid_handle_sys.unused; 1400711890bcSjc156560 raid_handle_sys.unused = raid_handle_sys.handles[ret].next; 1401711890bcSjc156560 1402711890bcSjc156560 raid_handle_sys.handles[ret].next = raid_handle_sys.used; 1403711890bcSjc156560 raid_handle_sys.used = ret; 1404711890bcSjc156560 raid_handle_sys.handles[ret].type = type; 1405711890bcSjc156560 1406711890bcSjc156560 return (ret); 1407711890bcSjc156560 } 1408711890bcSjc156560 1409711890bcSjc156560 static void 1410711890bcSjc156560 raid_handle_delete(raid_obj_handle_t handle) 1411711890bcSjc156560 { 1412711890bcSjc156560 int i = raid_handle_sys.used, j = 0; 1413711890bcSjc156560 1414711890bcSjc156560 if (handle == 0) 1415711890bcSjc156560 return; 1416711890bcSjc156560 1417711890bcSjc156560 while (i != 0 && i != handle) { 1418711890bcSjc156560 j = i; 1419711890bcSjc156560 i = raid_handle_sys.handles[i].next; 1420711890bcSjc156560 } 1421711890bcSjc156560 1422711890bcSjc156560 if (i == handle) { 1423711890bcSjc156560 if (j != 0) 1424711890bcSjc156560 raid_handle_sys.handles[j].next = 1425711890bcSjc156560 raid_handle_sys.handles[i].next; 1426711890bcSjc156560 else 1427711890bcSjc156560 raid_handle_sys.used = 1428711890bcSjc156560 raid_handle_sys.handles[i].next; 1429711890bcSjc156560 1430711890bcSjc156560 raid_handle_sys.handles[i].type = OBJ_TYPE_ALL; 1431711890bcSjc156560 raid_handle_sys.handles[i].next = 1432711890bcSjc156560 raid_handle_sys.unused; 1433711890bcSjc156560 raid_handle_sys.unused = i; 1434711890bcSjc156560 } 1435711890bcSjc156560 } 1436711890bcSjc156560 1437711890bcSjc156560 static void 1438711890bcSjc156560 raid_handle_delete_controller_comp(uint32_t controller_id) 1439711890bcSjc156560 { 1440711890bcSjc156560 int i = raid_handle_sys.used, j; 1441711890bcSjc156560 1442711890bcSjc156560 while (i != 0) { 1443711890bcSjc156560 j = i; 1444711890bcSjc156560 i = raid_handle_sys.handles[i].next; 1445700682b8Syw161884 if ((raid_handle_sys.handles[j].controller_id == 1446700682b8Syw161884 controller_id) && 1447700682b8Syw161884 (raid_handle_sys.handles[j].type != 1448700682b8Syw161884 OBJ_TYPE_CONTROLLER)) 1449711890bcSjc156560 raid_handle_delete(j); 1450711890bcSjc156560 } 1451711890bcSjc156560 } 1452711890bcSjc156560 1453711890bcSjc156560 static raid_obj_id_t 1454711890bcSjc156560 raid_handle_to_obj(raid_obj_tab_t *raid_tab, raid_obj_handle_t handle) 1455711890bcSjc156560 { 1456711890bcSjc156560 handle_attr_t *handle_attr; 1457711890bcSjc156560 raid_obj_id_t obj_id; 1458711890bcSjc156560 1459711890bcSjc156560 if (handle == OBJ_SYSTEM) 1460711890bcSjc156560 return (OBJ_SYSTEM); 1461711890bcSjc156560 1462711890bcSjc156560 handle_attr = raid_handle_sys.handles + handle; 1463711890bcSjc156560 1464711890bcSjc156560 switch (handle_attr->type) { 1465711890bcSjc156560 case OBJ_TYPE_SYSTEM: 1466711890bcSjc156560 return (OBJ_SYSTEM); 1467711890bcSjc156560 case OBJ_TYPE_CONTROLLER: 1468711890bcSjc156560 obj_id = obj_locate_controller(raid_tab, 1469711890bcSjc156560 handle_attr->controller_id); 1470711890bcSjc156560 break; 1471711890bcSjc156560 case OBJ_TYPE_ARRAY: 1472711890bcSjc156560 obj_id = obj_locate_array(raid_tab, 1473711890bcSjc156560 handle_attr->controller_id, handle_attr->array_id); 1474711890bcSjc156560 break; 1475711890bcSjc156560 case OBJ_TYPE_HSP: 1476711890bcSjc156560 obj_id = obj_locate_hsp(raid_tab, 1477711890bcSjc156560 handle_attr->controller_id, handle_attr->disk_id, 1478711890bcSjc156560 handle_attr->array_id); 1479711890bcSjc156560 break; 1480711890bcSjc156560 case OBJ_TYPE_DISK: 1481711890bcSjc156560 obj_id = obj_locate_disk(raid_tab, 1482711890bcSjc156560 handle_attr->controller_id, handle_attr->disk_id); 1483711890bcSjc156560 break; 1484711890bcSjc156560 case OBJ_TYPE_ARRAY_PART: 1485711890bcSjc156560 obj_id = obj_locate_arraypart(raid_tab, 1486711890bcSjc156560 handle_attr->controller_id, handle_attr->array_id, 1487711890bcSjc156560 handle_attr->disk_id); 1488711890bcSjc156560 break; 1489711890bcSjc156560 case OBJ_TYPE_DISK_SEG: 1490711890bcSjc156560 obj_id = obj_locate_diskseg(raid_tab, 1491711890bcSjc156560 handle_attr->controller_id, 1492711890bcSjc156560 handle_attr->disk_id, handle_attr->seq_id); 1493711890bcSjc156560 break; 1494711890bcSjc156560 case OBJ_TYPE_TASK: 1495711890bcSjc156560 obj_id = obj_locate_task(raid_tab, 1496711890bcSjc156560 handle_attr->controller_id, handle_attr->task_id); 1497711890bcSjc156560 break; 1498*b449fa8aSyw161884 case OBJ_TYPE_PROP: 1499*b449fa8aSyw161884 obj_id = obj_locate_prop(raid_tab, 1500*b449fa8aSyw161884 handle_attr->controller_id, handle_attr->disk_id, 1501*b449fa8aSyw161884 handle_attr->prop_id); 1502*b449fa8aSyw161884 break; 1503711890bcSjc156560 default: 1504711890bcSjc156560 return (ERR_DEVICE_INVALID); 1505711890bcSjc156560 } 1506711890bcSjc156560 1507711890bcSjc156560 if (obj_id < OBJ_NONE) 1508711890bcSjc156560 return (obj_id); 1509711890bcSjc156560 if (obj_id == OBJ_NONE) 1510711890bcSjc156560 return (ERR_DEVICE_NOENT); 1511711890bcSjc156560 1512711890bcSjc156560 (void) raid_obj_set_handle(raid_tab, obj_id, handle); 1513711890bcSjc156560 return (obj_id); 1514711890bcSjc156560 } 1515711890bcSjc156560 1516711890bcSjc156560 static raid_obj_handle_t 1517711890bcSjc156560 raid_obj_to_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1518711890bcSjc156560 { 1519711890bcSjc156560 raid_obj_id_t obj_id_backup = obj_id; 1520711890bcSjc156560 raid_obj_type_id_t type; 1521711890bcSjc156560 raid_obj_handle_t handle; 1522711890bcSjc156560 controller_attr_t *controller_attr; 1523711890bcSjc156560 array_attr_t *array_attr; 1524711890bcSjc156560 hsp_attr_t *hsp_attr; 1525711890bcSjc156560 disk_attr_t *disk_attr; 1526711890bcSjc156560 arraypart_attr_t *arraypart_attr; 1527711890bcSjc156560 diskseg_attr_t *diskseg_attr; 1528711890bcSjc156560 task_attr_t *task_attr; 1529*b449fa8aSyw161884 property_attr_t *prop_attr; 1530711890bcSjc156560 1531711890bcSjc156560 if (obj_id == OBJ_SYSTEM) 1532711890bcSjc156560 return (OBJ_SYSTEM); 1533711890bcSjc156560 1534711890bcSjc156560 /* If the object mapped by a handle */ 1535711890bcSjc156560 handle = raid_obj_get_handle(raid_tab, obj_id); 1536711890bcSjc156560 if (handle != 0) 1537711890bcSjc156560 return (handle); 1538711890bcSjc156560 1539711890bcSjc156560 /* Search for existing handles */ 1540711890bcSjc156560 for (handle = raid_handle_sys.used; handle != 0; 1541711890bcSjc156560 handle = raid_handle_sys.handles[handle].next) 1542711890bcSjc156560 if (raid_handle_to_obj(raid_tab, handle) == obj_id) 1543711890bcSjc156560 break; 1544711890bcSjc156560 1545711890bcSjc156560 if (handle != 0) 1546711890bcSjc156560 return (handle); 1547711890bcSjc156560 1548711890bcSjc156560 /* Allocate new handle for this object */ 1549711890bcSjc156560 type = raid_obj_get_type(raid_tab, obj_id); 1550711890bcSjc156560 handle = raid_handle_new(type); 1551711890bcSjc156560 (void) raid_obj_set_handle(raid_tab, obj_id, handle); 1552711890bcSjc156560 raid_handle_sys.handles[handle].type = type; 1553711890bcSjc156560 1554711890bcSjc156560 switch (type) { 1555711890bcSjc156560 case OBJ_TYPE_SYSTEM: 1556711890bcSjc156560 break; 1557711890bcSjc156560 case OBJ_TYPE_CONTROLLER: 1558711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1559711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1560711890bcSjc156560 controller_attr->controller_id; 1561711890bcSjc156560 break; 1562711890bcSjc156560 case OBJ_TYPE_ARRAY: 1563711890bcSjc156560 array_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1564711890bcSjc156560 raid_handle_sys.handles[handle].array_id = array_attr->array_id; 1565711890bcSjc156560 obj_id = obj_get_controller(raid_tab, obj_id); 1566711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1567711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1568711890bcSjc156560 controller_attr->controller_id; 1569711890bcSjc156560 break; 1570711890bcSjc156560 case OBJ_TYPE_HSP: 1571711890bcSjc156560 hsp_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1572711890bcSjc156560 raid_handle_sys.handles[handle].array_id = 1573711890bcSjc156560 hsp_attr->associated_id; 1574711890bcSjc156560 obj_id = raid_obj_get_container(raid_tab, obj_id); 1575711890bcSjc156560 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1576711890bcSjc156560 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id; 1577711890bcSjc156560 obj_id = obj_get_controller(raid_tab, obj_id); 1578711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1579711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1580711890bcSjc156560 controller_attr->controller_id; 1581711890bcSjc156560 break; 1582711890bcSjc156560 case OBJ_TYPE_DISK: 1583711890bcSjc156560 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1584711890bcSjc156560 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id; 1585711890bcSjc156560 obj_id = obj_get_controller(raid_tab, obj_id); 1586711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1587711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1588711890bcSjc156560 controller_attr->controller_id; 1589711890bcSjc156560 break; 1590711890bcSjc156560 case OBJ_TYPE_ARRAY_PART: 1591711890bcSjc156560 arraypart_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1592711890bcSjc156560 raid_handle_sys.handles[handle].disk_id = 1593711890bcSjc156560 arraypart_attr->disk_id; 1594711890bcSjc156560 obj_id = raid_obj_get_container(raid_tab, obj_id); 1595711890bcSjc156560 array_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1596711890bcSjc156560 raid_handle_sys.handles[handle].array_id = 1597711890bcSjc156560 array_attr->array_id; 1598711890bcSjc156560 obj_id = obj_get_controller(raid_tab, obj_id); 1599711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1600711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1601711890bcSjc156560 controller_attr->controller_id; 1602711890bcSjc156560 break; 1603711890bcSjc156560 case OBJ_TYPE_DISK_SEG: 1604711890bcSjc156560 diskseg_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1605711890bcSjc156560 raid_handle_sys.handles[handle].seq_id = diskseg_attr->seq_no; 1606711890bcSjc156560 obj_id = raid_obj_get_container(raid_tab, obj_id); 1607711890bcSjc156560 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1608711890bcSjc156560 raid_handle_sys.handles[handle].disk_id = 1609711890bcSjc156560 disk_attr->disk_id; 1610711890bcSjc156560 obj_id = obj_get_controller(raid_tab, obj_id); 1611711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1612711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1613711890bcSjc156560 controller_attr->controller_id; 1614711890bcSjc156560 break; 1615711890bcSjc156560 case OBJ_TYPE_TASK: 1616711890bcSjc156560 task_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1617711890bcSjc156560 raid_handle_sys.handles[handle].task_id = task_attr->task_id; 1618711890bcSjc156560 obj_id = obj_get_controller(raid_tab, obj_id); 1619711890bcSjc156560 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1620711890bcSjc156560 raid_handle_sys.handles[handle].controller_id = 1621711890bcSjc156560 controller_attr->controller_id; 1622711890bcSjc156560 break; 1623*b449fa8aSyw161884 case OBJ_TYPE_PROP: 1624*b449fa8aSyw161884 prop_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1625*b449fa8aSyw161884 raid_handle_sys.handles[handle].prop_id = 1626*b449fa8aSyw161884 prop_attr->prop_id; 1627*b449fa8aSyw161884 obj_id = raid_obj_get_container(raid_tab, obj_id); 1628*b449fa8aSyw161884 disk_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1629*b449fa8aSyw161884 raid_handle_sys.handles[handle].disk_id = disk_attr->disk_id; 1630*b449fa8aSyw161884 obj_id = obj_get_controller(raid_tab, obj_id); 1631*b449fa8aSyw161884 controller_attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1632*b449fa8aSyw161884 raid_handle_sys.handles[handle].controller_id = 1633*b449fa8aSyw161884 controller_attr->controller_id; 1634*b449fa8aSyw161884 break; 1635711890bcSjc156560 default: 1636711890bcSjc156560 return (ERR_DEVICE_INVALID); 1637711890bcSjc156560 } 1638711890bcSjc156560 1639711890bcSjc156560 (void) raid_obj_set_handle(raid_tab, obj_id_backup, handle); 1640711890bcSjc156560 return (handle); 1641711890bcSjc156560 } 1642711890bcSjc156560 1643711890bcSjc156560 static raid_lib_t * 1644711890bcSjc156560 raid_obj_get_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1645711890bcSjc156560 { 1646711890bcSjc156560 raid_obj_handle_t handle; 1647711890bcSjc156560 controller_attr_t *attr; 1648711890bcSjc156560 1649711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1650711890bcSjc156560 return (NULL); 1651711890bcSjc156560 1652711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1653711890bcSjc156560 handle = raid_handle_sys.used; 1654711890bcSjc156560 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1655711890bcSjc156560 raid_handle_sys.handles[handle].controller_id != 1656711890bcSjc156560 attr->controller_id) 1657711890bcSjc156560 handle = raid_handle_sys.handles[handle].next; 1658711890bcSjc156560 1659711890bcSjc156560 if (handle == 0) 1660711890bcSjc156560 return (NULL); 1661711890bcSjc156560 1662711890bcSjc156560 return (raid_handle_sys.handles[handle].raid_lib); 1663711890bcSjc156560 } 1664711890bcSjc156560 1665711890bcSjc156560 static int 1666711890bcSjc156560 raid_obj_set_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 1667711890bcSjc156560 raid_lib_t *raid_lib) 1668711890bcSjc156560 { 1669711890bcSjc156560 raid_obj_handle_t handle; 1670711890bcSjc156560 controller_attr_t *attr; 1671711890bcSjc156560 1672711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1673711890bcSjc156560 return (ERR_DEVICE_TYPE); 1674711890bcSjc156560 1675711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1676711890bcSjc156560 handle = raid_handle_sys.used; 1677711890bcSjc156560 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1678711890bcSjc156560 raid_handle_sys.handles[handle].controller_id != 1679711890bcSjc156560 attr->controller_id) 1680711890bcSjc156560 handle = raid_handle_sys.handles[handle].next; 1681711890bcSjc156560 1682711890bcSjc156560 if (handle == 0) 1683711890bcSjc156560 return (ERR_DEVICE_NOENT); 1684711890bcSjc156560 1685711890bcSjc156560 raid_handle_sys.handles[handle].raid_lib = raid_lib; 1686711890bcSjc156560 return (SUCCESS); 1687711890bcSjc156560 } 1688711890bcSjc156560 1689711890bcSjc156560 static int 1690711890bcSjc156560 raid_obj_get_fd(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1691711890bcSjc156560 { 1692711890bcSjc156560 raid_obj_handle_t handle; 1693711890bcSjc156560 controller_attr_t *attr; 1694711890bcSjc156560 1695711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1696711890bcSjc156560 return (ERR_DEVICE_TYPE); 1697711890bcSjc156560 1698711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1699711890bcSjc156560 handle = raid_handle_sys.used; 1700711890bcSjc156560 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1701711890bcSjc156560 raid_handle_sys.handles[handle].controller_id != 1702711890bcSjc156560 attr->controller_id) 1703711890bcSjc156560 handle = raid_handle_sys.handles[handle].next; 1704711890bcSjc156560 1705711890bcSjc156560 if (handle == 0) 1706711890bcSjc156560 return (ERR_DEVICE_NOENT); 1707711890bcSjc156560 1708711890bcSjc156560 return (raid_handle_sys.handles[handle].fd); 1709711890bcSjc156560 } 1710711890bcSjc156560 1711711890bcSjc156560 static int 1712711890bcSjc156560 raid_obj_set_fd(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, int fd) 1713711890bcSjc156560 { 1714711890bcSjc156560 raid_obj_handle_t handle; 1715711890bcSjc156560 controller_attr_t *attr; 1716711890bcSjc156560 1717711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 1718711890bcSjc156560 return (ERR_DEVICE_TYPE); 1719711890bcSjc156560 1720711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1721711890bcSjc156560 handle = raid_handle_sys.used; 1722711890bcSjc156560 while (raid_handle_sys.handles[handle].type != OBJ_TYPE_CONTROLLER || 1723711890bcSjc156560 raid_handle_sys.handles[handle].controller_id != 1724711890bcSjc156560 attr->controller_id) 1725711890bcSjc156560 handle = raid_handle_sys.handles[handle].next; 1726711890bcSjc156560 1727711890bcSjc156560 if (handle == 0) 1728711890bcSjc156560 return (ERR_DEVICE_NOENT); 1729711890bcSjc156560 1730711890bcSjc156560 raid_handle_sys.handles[handle].fd = fd; 1731711890bcSjc156560 return (SUCCESS); 1732711890bcSjc156560 } 1733711890bcSjc156560 1734711890bcSjc156560 /* 1735711890bcSjc156560 * Raid object maintenance routines 1736711890bcSjc156560 */ 1737711890bcSjc156560 static int 1738711890bcSjc156560 obj_scan_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1739711890bcSjc156560 { 1740711890bcSjc156560 raid_obj_status_t status; 1741711890bcSjc156560 raid_obj_type_id_t type; 1742711890bcSjc156560 int ret, i, obj_type_cnt, comp_num; 1743711890bcSjc156560 raid_obj_id_t *comp_list; 1744711890bcSjc156560 1745711890bcSjc156560 status = raid_obj_get_status(raid_tab, obj_id); 1746711890bcSjc156560 if (status < SUCCESS) 1747711890bcSjc156560 return (status); 1748711890bcSjc156560 1749711890bcSjc156560 if (status & OBJ_STATUS_SCANCOMP) 1750711890bcSjc156560 return (SUCCESS); 1751711890bcSjc156560 1752711890bcSjc156560 type = raid_obj_get_type(raid_tab, obj_id); 1753711890bcSjc156560 if (type < OBJ_TYPE_SYSTEM || type > OBJ_TYPE_ALL) 1754711890bcSjc156560 return (ERR_DEVICE_INVALID); 1755711890bcSjc156560 1756711890bcSjc156560 for (obj_type_cnt = OBJ_SYSTEM; obj_type_cnt < OBJ_TYPE_ALL; 1757711890bcSjc156560 ++obj_type_cnt) { 1758711890bcSjc156560 if (raid_obj_op_sys[type].compnum != NULL) 1759711890bcSjc156560 comp_num = raid_obj_op_sys[type].compnum( 1760711890bcSjc156560 raid_tab, obj_id, obj_type_cnt); 1761711890bcSjc156560 else 1762711890bcSjc156560 comp_num = 0; 1763711890bcSjc156560 1764711890bcSjc156560 if (comp_num < SUCCESS) 1765711890bcSjc156560 return (comp_num); 1766711890bcSjc156560 if (comp_num == 0) 1767711890bcSjc156560 continue; 1768711890bcSjc156560 1769711890bcSjc156560 comp_list = calloc(comp_num, sizeof (raid_obj_id_t)); 1770711890bcSjc156560 if (comp_list == NULL) 1771711890bcSjc156560 return (ERR_NOMEM); 1772711890bcSjc156560 1773711890bcSjc156560 for (i = 0; i < comp_num; ++i) { 1774711890bcSjc156560 *(comp_list + i) = raid_obj_create(raid_tab, 1775711890bcSjc156560 obj_type_cnt); 1776711890bcSjc156560 if (*(comp_list + i) < SUCCESS) { 1777711890bcSjc156560 ret = *(comp_list + i); 1778711890bcSjc156560 free(comp_list); 1779711890bcSjc156560 return (ret); 1780711890bcSjc156560 } 1781711890bcSjc156560 1782711890bcSjc156560 (void) raid_obj_clear_status(raid_tab, 1783711890bcSjc156560 *(comp_list + i), OBJ_STATUS_CMD_CLEAN); 1784711890bcSjc156560 (void) raid_obj_add_org(raid_tab, *(comp_list + i), 1785711890bcSjc156560 obj_id); 1786711890bcSjc156560 } 1787711890bcSjc156560 1788711890bcSjc156560 if (raid_obj_op_sys[type].complist != NULL) 1789711890bcSjc156560 raid_obj_op_sys[type].complist(raid_tab, 1790711890bcSjc156560 obj_id, comp_num, comp_list, obj_type_cnt); 1791711890bcSjc156560 free(comp_list); 1792711890bcSjc156560 } 1793711890bcSjc156560 1794711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_SCANCOMP); 1795711890bcSjc156560 return (SUCCESS); 1796711890bcSjc156560 } 1797711890bcSjc156560 1798711890bcSjc156560 static int 1799711890bcSjc156560 obj_rescan(raid_obj_tab_t *raid_tab) 1800711890bcSjc156560 { 1801711890bcSjc156560 int ret; 1802711890bcSjc156560 1803711890bcSjc156560 raid_obj_tab_destroy(raid_tab); 1804711890bcSjc156560 1805711890bcSjc156560 if (raid_obj_tab_create(raid_tab, HASH_SLOTS) != SUCCESS) 1806711890bcSjc156560 return (ERR_NOMEM); 1807711890bcSjc156560 1808711890bcSjc156560 if ((ret = raid_obj_create_system_obj(raid_tab)) != SUCCESS) { 1809711890bcSjc156560 raid_obj_tab_destroy(raid_tab); 1810711890bcSjc156560 return (ret); 1811711890bcSjc156560 } 1812711890bcSjc156560 1813711890bcSjc156560 return (SUCCESS); 1814711890bcSjc156560 } 1815711890bcSjc156560 1816711890bcSjc156560 static raid_obj_id_t 1817711890bcSjc156560 obj_get_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 1818711890bcSjc156560 raid_obj_type_id_t obj_type) 1819711890bcSjc156560 { 1820711890bcSjc156560 raid_obj_id_t id; 1821711890bcSjc156560 raid_obj_type_id_t type; 1822711890bcSjc156560 raid_obj_status_t status; 1823711890bcSjc156560 int ret; 1824711890bcSjc156560 1825711890bcSjc156560 if ((obj_type < OBJ_TYPE_SYSTEM) || (obj_type > OBJ_TYPE_ALL)) 1826711890bcSjc156560 return (ERR_DEVICE_TYPE); 1827711890bcSjc156560 1828711890bcSjc156560 status = raid_obj_get_status(raid_tab, obj_id); 1829711890bcSjc156560 if (status < SUCCESS) 1830711890bcSjc156560 return (status); 1831711890bcSjc156560 1832711890bcSjc156560 if (!(status & OBJ_STATUS_SCANCOMP)) { 1833711890bcSjc156560 ret = obj_scan_comp(raid_tab, obj_id); 1834711890bcSjc156560 if (ret < SUCCESS) 1835711890bcSjc156560 return (ret); 1836711890bcSjc156560 } 1837711890bcSjc156560 1838711890bcSjc156560 id = raid_obj_get_comp(raid_tab, obj_id); 1839711890bcSjc156560 if (id <= OBJ_NONE) 1840711890bcSjc156560 return (id); 1841711890bcSjc156560 1842711890bcSjc156560 type = raid_obj_get_type(raid_tab, id); 1843711890bcSjc156560 if (type < OBJ_TYPE_SYSTEM) 1844711890bcSjc156560 return (type); 1845711890bcSjc156560 1846711890bcSjc156560 if (type == obj_type) 1847711890bcSjc156560 return (id); 1848711890bcSjc156560 1849711890bcSjc156560 while (id > OBJ_NONE) { 1850711890bcSjc156560 id = raid_obj_get_sibling(raid_tab, id); 1851711890bcSjc156560 if (id <= OBJ_NONE) 1852711890bcSjc156560 return (id); 1853711890bcSjc156560 1854711890bcSjc156560 type = raid_obj_get_type(raid_tab, id); 1855711890bcSjc156560 if (type < OBJ_TYPE_SYSTEM) 1856711890bcSjc156560 return (type); 1857711890bcSjc156560 1858711890bcSjc156560 if (type == obj_type) 1859711890bcSjc156560 break; 1860711890bcSjc156560 }; 1861711890bcSjc156560 1862711890bcSjc156560 return (id); 1863711890bcSjc156560 } 1864711890bcSjc156560 1865711890bcSjc156560 static raid_obj_id_t 1866711890bcSjc156560 obj_get_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 1867711890bcSjc156560 { 1868711890bcSjc156560 raid_obj_id_t id; 1869711890bcSjc156560 raid_obj_type_id_t type, obj_type; 1870711890bcSjc156560 1871711890bcSjc156560 id = obj_id; 1872711890bcSjc156560 obj_type = raid_obj_get_type(raid_tab, id); 1873711890bcSjc156560 if (obj_type < OBJ_TYPE_SYSTEM) 1874711890bcSjc156560 return (obj_type); 1875711890bcSjc156560 1876711890bcSjc156560 do { 1877711890bcSjc156560 id = raid_obj_get_sibling(raid_tab, id); 1878711890bcSjc156560 if (id < OBJ_NONE) 1879711890bcSjc156560 return (id); 1880711890bcSjc156560 1881711890bcSjc156560 type = raid_obj_get_type(raid_tab, id); 1882711890bcSjc156560 if (type < OBJ_TYPE_SYSTEM) 1883711890bcSjc156560 return (type); 1884711890bcSjc156560 } while ((type != obj_type) && (id != OBJ_NONE)); 1885711890bcSjc156560 1886711890bcSjc156560 return (id); 1887711890bcSjc156560 } 1888711890bcSjc156560 1889711890bcSjc156560 static int 1890711890bcSjc156560 obj_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, void **data) 1891711890bcSjc156560 { 1892711890bcSjc156560 raid_obj_type_id_t type; 1893711890bcSjc156560 raid_obj_status_t status; 1894711890bcSjc156560 void *attr; 1895711890bcSjc156560 int ret = SUCCESS; 1896711890bcSjc156560 1897711890bcSjc156560 status = raid_obj_get_status(raid_tab, obj_id); 1898711890bcSjc156560 if (status < SUCCESS) 1899711890bcSjc156560 return (status); 1900711890bcSjc156560 1901711890bcSjc156560 type = raid_obj_get_type(raid_tab, obj_id); 1902711890bcSjc156560 if (type < OBJ_TYPE_SYSTEM) 1903711890bcSjc156560 return (type); 1904711890bcSjc156560 1905711890bcSjc156560 if (!(status & OBJ_STATUS_OPENED)) { 1906711890bcSjc156560 if (raid_obj_op_sys[type].get_attr == NULL) 1907711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, 1908711890bcSjc156560 OBJ_STATUS_OPENED); 1909711890bcSjc156560 else 1910711890bcSjc156560 ret = raid_obj_op_sys[type].get_attr(raid_tab, obj_id); 1911711890bcSjc156560 } 1912711890bcSjc156560 if (ret < SUCCESS) 1913711890bcSjc156560 return (ret); 1914711890bcSjc156560 1915711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1916711890bcSjc156560 if (attr == NULL && type != OBJ_TYPE_SYSTEM) 1917711890bcSjc156560 return (ERR_DEVICE_INVALID); 1918711890bcSjc156560 1919711890bcSjc156560 *data = attr; 1920711890bcSjc156560 return (SUCCESS); 1921711890bcSjc156560 } 1922711890bcSjc156560 1923711890bcSjc156560 static raid_obj_id_t 1924711890bcSjc156560 obj_locate_controller(raid_obj_tab_t *raid_tab, uint32_t controller_id) 1925711890bcSjc156560 { 1926711890bcSjc156560 raid_obj_id_t obj_id; 1927711890bcSjc156560 controller_attr_t *attr; 1928711890bcSjc156560 1929711890bcSjc156560 obj_id = obj_get_comp(raid_tab, OBJ_SYSTEM, OBJ_TYPE_CONTROLLER); 1930711890bcSjc156560 if (obj_id <= OBJ_NONE) 1931711890bcSjc156560 return (obj_id); 1932711890bcSjc156560 1933711890bcSjc156560 do { 1934711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1935711890bcSjc156560 if (attr == NULL) 1936711890bcSjc156560 return (ERR_DEVICE_INVALID); 1937711890bcSjc156560 1938711890bcSjc156560 if (attr->controller_id == controller_id) 1939711890bcSjc156560 break; 1940711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) != OBJ_NONE); 1941711890bcSjc156560 1942711890bcSjc156560 return (obj_id); 1943711890bcSjc156560 } 1944711890bcSjc156560 1945711890bcSjc156560 static raid_obj_id_t 1946711890bcSjc156560 obj_locate_array(raid_obj_tab_t *raid_tab, uint32_t controller_id, 1947711890bcSjc156560 uint32_t array_id) 1948711890bcSjc156560 { 1949711890bcSjc156560 raid_obj_id_t obj_id; 1950711890bcSjc156560 1951711890bcSjc156560 obj_id = obj_locate_controller(raid_tab, controller_id); 1952711890bcSjc156560 if (obj_id < OBJ_NONE) 1953711890bcSjc156560 return (obj_id); 1954711890bcSjc156560 1955711890bcSjc156560 obj_id = obj_locate_array_recur(raid_tab, obj_id, array_id); 1956711890bcSjc156560 1957711890bcSjc156560 return (obj_id); 1958711890bcSjc156560 } 1959711890bcSjc156560 1960711890bcSjc156560 static raid_obj_id_t 1961711890bcSjc156560 obj_locate_array_recur(raid_obj_tab_t *raid_tab, 1962711890bcSjc156560 raid_obj_id_t container_obj_id, uint32_t array_id) 1963711890bcSjc156560 { 1964711890bcSjc156560 raid_obj_id_t obj_id, ret; 1965711890bcSjc156560 array_attr_t *attr; 1966711890bcSjc156560 1967711890bcSjc156560 obj_id = obj_get_comp(raid_tab, container_obj_id, OBJ_TYPE_ARRAY); 1968711890bcSjc156560 if (obj_id <= OBJ_NONE) 1969711890bcSjc156560 return (obj_id); 1970711890bcSjc156560 1971711890bcSjc156560 do { 1972711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 1973711890bcSjc156560 if (attr == NULL) 1974711890bcSjc156560 return (ERR_DEVICE_INVALID); 1975711890bcSjc156560 1976711890bcSjc156560 if (attr->array_id == array_id) 1977711890bcSjc156560 break; 1978711890bcSjc156560 1979711890bcSjc156560 ret = obj_locate_array_recur(raid_tab, obj_id, array_id); 1980711890bcSjc156560 if (ret != OBJ_NONE) 1981711890bcSjc156560 return (ret); 1982711890bcSjc156560 1983711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 1984711890bcSjc156560 1985711890bcSjc156560 return (obj_id); 1986711890bcSjc156560 } 1987711890bcSjc156560 1988711890bcSjc156560 static raid_obj_id_t 1989711890bcSjc156560 obj_locate_hsp(raid_obj_tab_t *raid_tab, uint32_t controller_id, 1990711890bcSjc156560 uint32_t disk_id, uint32_t array_id) 1991711890bcSjc156560 { 1992711890bcSjc156560 raid_obj_id_t obj_id; 1993711890bcSjc156560 hsp_attr_t *hsp_attr; 1994711890bcSjc156560 1995711890bcSjc156560 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id); 1996711890bcSjc156560 if (obj_id <= OBJ_NONE) 1997711890bcSjc156560 return (obj_id); 1998711890bcSjc156560 1999711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_HSP); 2000711890bcSjc156560 if (obj_id <= OBJ_NONE) 2001711890bcSjc156560 return (obj_id); 2002711890bcSjc156560 2003711890bcSjc156560 do { 2004711890bcSjc156560 (void) obj_get_attr(raid_tab, obj_id, (void **)(&hsp_attr)); 2005711890bcSjc156560 if (hsp_attr->associated_id == array_id) 2006711890bcSjc156560 break; 2007711890bcSjc156560 2008711890bcSjc156560 obj_id = obj_get_sibling(raid_tab, obj_id); 2009711890bcSjc156560 if (obj_id < OBJ_NONE) 2010711890bcSjc156560 return (obj_id); 2011711890bcSjc156560 } while (obj_id > OBJ_NONE); 2012711890bcSjc156560 2013711890bcSjc156560 return (obj_id); 2014711890bcSjc156560 } 2015711890bcSjc156560 2016711890bcSjc156560 static raid_obj_id_t 2017711890bcSjc156560 obj_locate_disk(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2018711890bcSjc156560 uint32_t disk_id) 2019711890bcSjc156560 { 2020711890bcSjc156560 raid_obj_id_t obj_id; 2021711890bcSjc156560 disk_attr_t *attr; 2022711890bcSjc156560 2023711890bcSjc156560 obj_id = obj_locate_controller(raid_tab, controller_id); 2024711890bcSjc156560 if (obj_id <= OBJ_NONE) 2025711890bcSjc156560 return (obj_id); 2026711890bcSjc156560 2027711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK); 2028711890bcSjc156560 if (obj_id <= OBJ_NONE) 2029711890bcSjc156560 return (obj_id); 2030711890bcSjc156560 2031711890bcSjc156560 do { 2032711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2033711890bcSjc156560 if (attr == NULL) 2034711890bcSjc156560 return (ERR_DEVICE_INVALID); 2035711890bcSjc156560 2036711890bcSjc156560 if (attr->disk_id == disk_id) 2037711890bcSjc156560 break; 2038711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2039711890bcSjc156560 2040711890bcSjc156560 return (obj_id); 2041711890bcSjc156560 } 2042711890bcSjc156560 2043711890bcSjc156560 static raid_obj_id_t 2044711890bcSjc156560 obj_locate_arraypart(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2045711890bcSjc156560 uint32_t array_id, uint32_t disk_id) 2046711890bcSjc156560 { 2047711890bcSjc156560 raid_obj_id_t obj_id; 2048711890bcSjc156560 2049711890bcSjc156560 arraypart_attr_t *attr; 2050711890bcSjc156560 2051711890bcSjc156560 obj_id = obj_locate_array(raid_tab, controller_id, array_id); 2052711890bcSjc156560 if (obj_id <= OBJ_NONE) 2053711890bcSjc156560 return (obj_id); 2054711890bcSjc156560 2055711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY_PART); 2056711890bcSjc156560 if (obj_id <= OBJ_NONE) 2057711890bcSjc156560 return (obj_id); 2058711890bcSjc156560 2059711890bcSjc156560 do { 2060711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2061711890bcSjc156560 if (attr == NULL) 2062711890bcSjc156560 return (ERR_DEVICE_INVALID); 2063711890bcSjc156560 2064711890bcSjc156560 if (attr->disk_id == disk_id) 2065711890bcSjc156560 break; 2066711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > 2067711890bcSjc156560 OBJ_NONE); 2068711890bcSjc156560 2069711890bcSjc156560 return (obj_id); 2070711890bcSjc156560 } 2071711890bcSjc156560 2072711890bcSjc156560 static raid_obj_id_t 2073711890bcSjc156560 obj_locate_diskseg(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2074711890bcSjc156560 uint32_t disk_id, uint32_t seq_no) 2075711890bcSjc156560 { 2076711890bcSjc156560 raid_obj_id_t obj_id; 2077711890bcSjc156560 diskseg_attr_t *attr; 2078711890bcSjc156560 2079711890bcSjc156560 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id); 2080711890bcSjc156560 if (obj_id <= OBJ_NONE) 2081711890bcSjc156560 return (obj_id); 2082711890bcSjc156560 2083711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK_SEG); 2084711890bcSjc156560 if (obj_id <= OBJ_NONE) 2085711890bcSjc156560 return (obj_id); 2086711890bcSjc156560 2087711890bcSjc156560 do { 2088711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2089711890bcSjc156560 if (attr == NULL) 2090711890bcSjc156560 return (ERR_DEVICE_INVALID); 2091711890bcSjc156560 2092711890bcSjc156560 if (attr->seq_no == seq_no) 2093711890bcSjc156560 break; 2094711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2095711890bcSjc156560 2096711890bcSjc156560 return (obj_id); 2097711890bcSjc156560 } 2098711890bcSjc156560 2099711890bcSjc156560 static raid_obj_id_t 2100711890bcSjc156560 obj_locate_task(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2101711890bcSjc156560 uint32_t task_id) 2102711890bcSjc156560 { 2103711890bcSjc156560 raid_obj_id_t obj_id, obj_id2, task_obj_id; 2104711890bcSjc156560 task_attr_t *attr; 2105711890bcSjc156560 2106711890bcSjc156560 obj_id = obj_locate_controller(raid_tab, controller_id); 2107711890bcSjc156560 if (obj_id <= OBJ_NONE) 2108711890bcSjc156560 return (obj_id); 2109711890bcSjc156560 2110711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY); 2111711890bcSjc156560 if (obj_id < OBJ_NONE) 2112711890bcSjc156560 return (obj_id); 2113711890bcSjc156560 2114711890bcSjc156560 do { 2115711890bcSjc156560 obj_id2 = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_ARRAY); 2116711890bcSjc156560 while (obj_id2 != OBJ_NONE) { 2117711890bcSjc156560 task_obj_id = obj_get_comp(raid_tab, obj_id2, 2118711890bcSjc156560 OBJ_TYPE_TASK); 2119711890bcSjc156560 2120711890bcSjc156560 if (task_obj_id < OBJ_NONE) 2121711890bcSjc156560 return (task_obj_id); 2122711890bcSjc156560 2123711890bcSjc156560 if (task_obj_id == OBJ_NONE) { 2124711890bcSjc156560 obj_id2 = obj_get_sibling(raid_tab, obj_id2); 2125711890bcSjc156560 continue; 2126711890bcSjc156560 } 2127711890bcSjc156560 2128711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id); 2129711890bcSjc156560 if (attr == NULL) 2130711890bcSjc156560 return (ERR_DEVICE_INVALID); 2131711890bcSjc156560 2132711890bcSjc156560 if (attr->task_id == task_id) 2133711890bcSjc156560 return (task_obj_id); 2134711890bcSjc156560 2135711890bcSjc156560 obj_id2 = obj_get_sibling(raid_tab, obj_id2); 2136711890bcSjc156560 } 2137711890bcSjc156560 2138711890bcSjc156560 task_obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_TASK); 2139711890bcSjc156560 if (task_obj_id < OBJ_NONE) 2140711890bcSjc156560 return (task_obj_id); 2141711890bcSjc156560 2142711890bcSjc156560 if (task_obj_id == OBJ_NONE) 2143711890bcSjc156560 continue; 2144711890bcSjc156560 2145711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id); 2146711890bcSjc156560 if (attr == NULL) 2147711890bcSjc156560 return (ERR_DEVICE_INVALID); 2148711890bcSjc156560 2149711890bcSjc156560 if (attr->task_id == task_id) 2150711890bcSjc156560 return (task_obj_id); 2151711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2152711890bcSjc156560 2153711890bcSjc156560 if (obj_id < OBJ_NONE) 2154711890bcSjc156560 return (obj_id); 2155711890bcSjc156560 2156711890bcSjc156560 obj_id = obj_locate_controller(raid_tab, controller_id); 2157711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_DISK); 2158711890bcSjc156560 if (obj_id < OBJ_NONE) 2159711890bcSjc156560 return (obj_id); 2160711890bcSjc156560 2161711890bcSjc156560 do { 2162711890bcSjc156560 task_obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_TASK); 2163711890bcSjc156560 if (task_obj_id < OBJ_NONE) 2164711890bcSjc156560 return (task_obj_id); 2165711890bcSjc156560 2166711890bcSjc156560 if (task_obj_id == OBJ_NONE) 2167711890bcSjc156560 continue; 2168711890bcSjc156560 2169711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, task_obj_id); 2170711890bcSjc156560 if (attr == NULL) 2171711890bcSjc156560 return (ERR_DEVICE_INVALID); 2172711890bcSjc156560 2173711890bcSjc156560 if (attr->task_id == task_id) 2174711890bcSjc156560 return (task_obj_id); 2175711890bcSjc156560 } while ((obj_id = obj_get_sibling(raid_tab, obj_id)) > OBJ_NONE); 2176711890bcSjc156560 2177711890bcSjc156560 return (obj_id); 2178*b449fa8aSyw161884 } 2179711890bcSjc156560 2180*b449fa8aSyw161884 static raid_obj_id_t 2181*b449fa8aSyw161884 obj_locate_prop(raid_obj_tab_t *raid_tab, uint32_t controller_id, 2182*b449fa8aSyw161884 uint32_t disk_id, uint32_t prop_id) 2183*b449fa8aSyw161884 { 2184*b449fa8aSyw161884 raid_obj_id_t obj_id; 2185*b449fa8aSyw161884 property_attr_t *prop_attr; 2186*b449fa8aSyw161884 2187*b449fa8aSyw161884 obj_id = obj_locate_disk(raid_tab, controller_id, disk_id); 2188*b449fa8aSyw161884 if (obj_id < OBJ_NONE) 2189*b449fa8aSyw161884 return (obj_id); 2190*b449fa8aSyw161884 2191*b449fa8aSyw161884 obj_id = obj_get_comp(raid_tab, obj_id, OBJ_TYPE_PROP); 2192*b449fa8aSyw161884 if (obj_id <= OBJ_NONE) 2193*b449fa8aSyw161884 return (obj_id); 2194*b449fa8aSyw161884 2195*b449fa8aSyw161884 do { 2196*b449fa8aSyw161884 (void) obj_get_attr(raid_tab, obj_id, (void **)(&prop_attr)); 2197*b449fa8aSyw161884 if (prop_attr->prop_id == prop_id) 2198*b449fa8aSyw161884 break; 2199*b449fa8aSyw161884 2200*b449fa8aSyw161884 obj_id = obj_get_sibling(raid_tab, obj_id); 2201*b449fa8aSyw161884 if (obj_id < OBJ_NONE) 2202*b449fa8aSyw161884 return (obj_id); 2203*b449fa8aSyw161884 } while (obj_id > OBJ_NONE); 2204*b449fa8aSyw161884 2205*b449fa8aSyw161884 return (obj_id); 2206711890bcSjc156560 } 2207711890bcSjc156560 2208711890bcSjc156560 static raid_obj_id_t 2209711890bcSjc156560 obj_get_controller(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2210711890bcSjc156560 { 2211711890bcSjc156560 raid_obj_id_t id = obj_id; 2212711890bcSjc156560 2213711890bcSjc156560 while (raid_obj_get_type(raid_tab, id) != OBJ_TYPE_CONTROLLER) { 2214711890bcSjc156560 id = raid_obj_get_container(raid_tab, id); 2215711890bcSjc156560 if ((id == OBJ_SYSTEM) || (id < OBJ_NONE)) 2216711890bcSjc156560 return (ERR_DEVICE_INVALID); 2217711890bcSjc156560 } 2218711890bcSjc156560 2219711890bcSjc156560 return (id); 2220711890bcSjc156560 } 2221711890bcSjc156560 2222711890bcSjc156560 /* 2223711890bcSjc156560 * Raid object operation routines 2224711890bcSjc156560 */ 2225711890bcSjc156560 static int 2226711890bcSjc156560 obj_sys_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2227711890bcSjc156560 raid_obj_type_id_t comp_type) 2228711890bcSjc156560 { 2229711890bcSjc156560 DIR *dir; 2230711890bcSjc156560 struct dirent *dp; 2231711890bcSjc156560 int num = 0; 2232711890bcSjc156560 2233711890bcSjc156560 if ((raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_SYSTEM)) 2234711890bcSjc156560 return (ERR_DEVICE_TYPE); 2235711890bcSjc156560 2236711890bcSjc156560 if (comp_type != OBJ_TYPE_CONTROLLER) 2237711890bcSjc156560 return (0); 2238711890bcSjc156560 2239711890bcSjc156560 if ((dir = opendir(CFGDIR)) == NULL) 2240711890bcSjc156560 return (ERR_DRIVER_NOT_FOUND); 2241711890bcSjc156560 2242711890bcSjc156560 while ((dp = readdir(dir)) != NULL) { 2243711890bcSjc156560 uint32_t controller_id; 2244711890bcSjc156560 char path[MAX_PATH_LEN]; 2245711890bcSjc156560 2246711890bcSjc156560 if (strcmp(dp->d_name, ".") == 0 || 2247711890bcSjc156560 strcmp(dp->d_name, "..") == 0) 2248711890bcSjc156560 continue; 2249711890bcSjc156560 2250711890bcSjc156560 if (sscanf(dp->d_name, "c%u", &controller_id) != 1) 2251711890bcSjc156560 continue; 2252711890bcSjc156560 2253711890bcSjc156560 if (controller_id_to_path(controller_id, path) == SUCCESS) 2254711890bcSjc156560 ++ num; 2255711890bcSjc156560 } 2256711890bcSjc156560 2257711890bcSjc156560 (void) closedir(dir); 2258711890bcSjc156560 return (num); 2259711890bcSjc156560 } 2260711890bcSjc156560 2261711890bcSjc156560 static int 2262711890bcSjc156560 obj_sys_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2263711890bcSjc156560 int num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2264711890bcSjc156560 { 2265711890bcSjc156560 DIR *dir; 2266711890bcSjc156560 struct dirent *dp; 2267711890bcSjc156560 controller_attr_t *attr; 2268711890bcSjc156560 uint32_t controller_id; 2269711890bcSjc156560 uint32_t *tmplist; 2270711890bcSjc156560 char path[MAX_PATH_LEN]; 2271711890bcSjc156560 int i = 0; 2272711890bcSjc156560 2273711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_SYSTEM) 2274711890bcSjc156560 return (ERR_DEVICE_TYPE); 2275711890bcSjc156560 if ((num <= 0) || (comp_list == NULL)) 2276711890bcSjc156560 return (ERR_OP_ILLEGAL); 2277711890bcSjc156560 2278711890bcSjc156560 if (comp_type != OBJ_TYPE_CONTROLLER) 2279711890bcSjc156560 return (0); 2280711890bcSjc156560 2281711890bcSjc156560 if ((dir = opendir(CFGDIR)) == NULL) 2282711890bcSjc156560 return (ERR_DRIVER_NOT_FOUND); 2283711890bcSjc156560 tmplist = calloc(num, sizeof (uint32_t)); 2284711890bcSjc156560 if (tmplist == NULL) { 2285711890bcSjc156560 return (ERR_NOMEM); 2286711890bcSjc156560 } 2287711890bcSjc156560 while ((dp = readdir(dir)) != NULL) { 2288711890bcSjc156560 if (strcmp(dp->d_name, ".") == 0 || 2289711890bcSjc156560 strcmp(dp->d_name, "..") == 0) 2290711890bcSjc156560 continue; 2291711890bcSjc156560 2292711890bcSjc156560 if (sscanf(dp->d_name, "c%u", &controller_id) != 1) 2293711890bcSjc156560 continue; 2294711890bcSjc156560 2295711890bcSjc156560 if (controller_id_to_path(controller_id, path) == SUCCESS) { 2296711890bcSjc156560 tmplist[i] = controller_id; 2297711890bcSjc156560 ++ i; 2298711890bcSjc156560 } 2299711890bcSjc156560 } 2300711890bcSjc156560 qsort((void *)tmplist, num, sizeof (uint32_t), intcompare); 2301711890bcSjc156560 for (i = 0; i < num; i++) { 2302711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, 2303711890bcSjc156560 *(comp_list + i)); 2304711890bcSjc156560 2305711890bcSjc156560 if (attr == NULL) { 2306711890bcSjc156560 free(tmplist); 2307711890bcSjc156560 return (ERR_DEVICE_INVALID); 2308711890bcSjc156560 } 2309711890bcSjc156560 2310711890bcSjc156560 attr->controller_id = tmplist[i]; 2311711890bcSjc156560 } 2312711890bcSjc156560 free(tmplist); 2313711890bcSjc156560 (void) closedir(dir); 2314711890bcSjc156560 return (SUCCESS); 2315711890bcSjc156560 } 2316711890bcSjc156560 2317711890bcSjc156560 static int 2318711890bcSjc156560 obj_controller_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2319711890bcSjc156560 raid_obj_type_id_t comp_type) 2320711890bcSjc156560 { 2321711890bcSjc156560 raid_lib_t *raid_lib; 2322711890bcSjc156560 int ret = SUCCESS, fd; 2323711890bcSjc156560 controller_attr_t *ctl_attrp; 2324711890bcSjc156560 2325711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2326711890bcSjc156560 return (ERR_DEVICE_TYPE); 2327711890bcSjc156560 2328711890bcSjc156560 if ((comp_type != OBJ_TYPE_ARRAY) && (comp_type != OBJ_TYPE_DISK)) 2329711890bcSjc156560 return (0); 2330711890bcSjc156560 2331711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2332711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, obj_id); 2333711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, obj_id); 2334711890bcSjc156560 if ((raid_lib == NULL) || (ctl_attrp == NULL) || (fd == 0)) 2335711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2336711890bcSjc156560 2337711890bcSjc156560 ret = raid_lib->compnum(ctl_attrp->controller_id, 0, 2338711890bcSjc156560 OBJ_TYPE_CONTROLLER, comp_type); 2339711890bcSjc156560 2340711890bcSjc156560 return (ret); 2341711890bcSjc156560 } 2342711890bcSjc156560 2343711890bcSjc156560 static int 2344711890bcSjc156560 obj_controller_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2345711890bcSjc156560 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2346711890bcSjc156560 { 2347711890bcSjc156560 raid_lib_t *raid_lib; 2348711890bcSjc156560 controller_attr_t *ctl_attrp; 2349711890bcSjc156560 int ret, i, fd; 2350711890bcSjc156560 uint32_t *ids; 2351711890bcSjc156560 2352711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2353711890bcSjc156560 return (ERR_DEVICE_TYPE); 2354711890bcSjc156560 2355711890bcSjc156560 if ((comp_type != OBJ_TYPE_ARRAY) && (comp_type != OBJ_TYPE_DISK)) 2356711890bcSjc156560 return (0); 2357711890bcSjc156560 2358711890bcSjc156560 if ((comp_num <= 0) || (comp_list == NULL)) 2359711890bcSjc156560 return (ERR_OP_ILLEGAL); 2360711890bcSjc156560 2361711890bcSjc156560 for (i = 0; i < comp_num; ++i) 2362711890bcSjc156560 if (raid_obj_get_type(raid_tab, *(comp_list + i)) != 2363711890bcSjc156560 comp_type) 2364711890bcSjc156560 return (ERR_DEVICE_TYPE); 2365711890bcSjc156560 2366711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2367711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, obj_id); 2368711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, obj_id); 2369711890bcSjc156560 if ((raid_lib == NULL) || (ctl_attrp == NULL)|| (fd == 0)) 2370711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2371711890bcSjc156560 2372711890bcSjc156560 ids = malloc(comp_num * sizeof (uint32_t)); 2373711890bcSjc156560 if (ids == NULL) 2374711890bcSjc156560 return (ERR_NOMEM); 2375711890bcSjc156560 2376711890bcSjc156560 ret = raid_lib->complist(ctl_attrp->controller_id, 0, 2377711890bcSjc156560 OBJ_TYPE_CONTROLLER, comp_type, comp_num, ids); 2378711890bcSjc156560 if (ret < SUCCESS) { 2379711890bcSjc156560 free(ids); 2380711890bcSjc156560 return (ret); 2381711890bcSjc156560 } 2382711890bcSjc156560 qsort((void *)ids, comp_num, sizeof (uint32_t), intcompare); 2383711890bcSjc156560 for (i = 0; i < comp_num; ++ i) { 2384711890bcSjc156560 array_attr_t *array_attr; 2385711890bcSjc156560 disk_attr_t *disk_attr; 2386711890bcSjc156560 void *attr_buf; 2387711890bcSjc156560 2388711890bcSjc156560 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i)); 2389711890bcSjc156560 if (attr_buf == NULL) { 2390711890bcSjc156560 free(ids); 2391711890bcSjc156560 return (ERR_DEVICE_INVALID); 2392711890bcSjc156560 } 2393711890bcSjc156560 2394711890bcSjc156560 switch (comp_type) { 2395711890bcSjc156560 case OBJ_TYPE_ARRAY: 2396711890bcSjc156560 array_attr = attr_buf; 2397711890bcSjc156560 array_attr->array_id = *(ids + i); 2398711890bcSjc156560 break; 2399711890bcSjc156560 case OBJ_TYPE_DISK: 2400711890bcSjc156560 disk_attr = attr_buf; 2401711890bcSjc156560 disk_attr->disk_id = *(ids + i); 2402711890bcSjc156560 break; 2403711890bcSjc156560 default: 2404711890bcSjc156560 free(ids); 2405711890bcSjc156560 return (ERR_DEVICE_INVALID); 2406711890bcSjc156560 } 2407711890bcSjc156560 } 2408711890bcSjc156560 2409711890bcSjc156560 free(ids); 2410711890bcSjc156560 return (SUCCESS); 2411711890bcSjc156560 } 2412711890bcSjc156560 2413711890bcSjc156560 static int 2414711890bcSjc156560 obj_controller_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2415711890bcSjc156560 { 2416711890bcSjc156560 controller_attr_t *attr; 2417711890bcSjc156560 raid_lib_t *raid_lib; 2418711890bcSjc156560 int ret = SUCCESS, fd; 2419711890bcSjc156560 2420711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2421711890bcSjc156560 return (ERR_DEVICE_TYPE); 2422711890bcSjc156560 2423711890bcSjc156560 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 2424711890bcSjc156560 return (SUCCESS); 2425711890bcSjc156560 2426711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2427711890bcSjc156560 if (attr == NULL) 2428711890bcSjc156560 return (ERR_DEVICE_INVALID); 2429711890bcSjc156560 2430711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2431711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, obj_id); 2432711890bcSjc156560 2433711890bcSjc156560 /* 2434711890bcSjc156560 * For a controller, even it's not opened, we can still 2435711890bcSjc156560 * get the driver name 2436711890bcSjc156560 */ 2437711890bcSjc156560 2438711890bcSjc156560 if (fd == 0) 2439711890bcSjc156560 return (SUCCESS); 2440711890bcSjc156560 2441711890bcSjc156560 if (raid_lib == NULL) { 2442711890bcSjc156560 return (SUCCESS); 2443711890bcSjc156560 } 2444711890bcSjc156560 2445711890bcSjc156560 ret = raid_lib->get_attr(attr->controller_id, OBJ_ATTR_NONE, 2446711890bcSjc156560 OBJ_ATTR_NONE, OBJ_TYPE_CONTROLLER, attr); 2447711890bcSjc156560 if (ret < SUCCESS) 2448711890bcSjc156560 return (ret); 2449711890bcSjc156560 2450711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 2451711890bcSjc156560 2452711890bcSjc156560 return (ret); 2453711890bcSjc156560 } 2454711890bcSjc156560 2455711890bcSjc156560 static int 2456711890bcSjc156560 obj_controller_act(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2457711890bcSjc156560 uint32_t sub_cmd, void *prop_list, char **plugin_err_str) 2458711890bcSjc156560 { 2459711890bcSjc156560 controller_attr_t *attr; 2460711890bcSjc156560 raid_lib_t *raid_lib; 2461711890bcSjc156560 int ret, fd; 2462711890bcSjc156560 2463711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_CONTROLLER) 2464711890bcSjc156560 return (ERR_DEVICE_TYPE); 2465711890bcSjc156560 2466711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2467711890bcSjc156560 2468711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, obj_id); 2469711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, obj_id); 2470711890bcSjc156560 2471711890bcSjc156560 switch (sub_cmd) { 2472711890bcSjc156560 case ACT_CONTROLLER_OPEN: 2473711890bcSjc156560 /* Check if already opened */ 2474711890bcSjc156560 2475711890bcSjc156560 if (fd > 0) 2476711890bcSjc156560 return (SUCCESS); 2477711890bcSjc156560 2478711890bcSjc156560 /* Check if plugin is already attached */ 2479711890bcSjc156560 if (raid_lib == NULL) { 2480711890bcSjc156560 raid_lib = raid_find_lib(raid_tab, obj_id); 2481711890bcSjc156560 if (raid_lib == NULL) 2482711890bcSjc156560 return (ERR_DRIVER_NOT_FOUND); 2483711890bcSjc156560 } 2484711890bcSjc156560 2485711890bcSjc156560 ret = raid_lib->open_controller(attr->controller_id, 2486711890bcSjc156560 plugin_err_str); 2487711890bcSjc156560 if (ret == SUCCESS) { 2488711890bcSjc156560 (void) raid_obj_set_lib(raid_tab, obj_id, raid_lib); 2489711890bcSjc156560 (void) raid_obj_set_fd(raid_tab, obj_id, 1); 2490711890bcSjc156560 } 2491711890bcSjc156560 break; 2492711890bcSjc156560 case ACT_CONTROLLER_CLOSE: 2493711890bcSjc156560 2494711890bcSjc156560 if (fd <= 0) 2495711890bcSjc156560 return (SUCCESS); 2496711890bcSjc156560 2497711890bcSjc156560 if (raid_lib == NULL) { 2498711890bcSjc156560 return (SUCCESS); 2499711890bcSjc156560 } 2500711890bcSjc156560 ret = raid_lib->close_controller(attr->controller_id, 2501711890bcSjc156560 plugin_err_str); 2502711890bcSjc156560 if (ret == SUCCESS) { 2503711890bcSjc156560 (void) raid_obj_set_fd(raid_tab, obj_id, 0); 2504711890bcSjc156560 (void) raid_obj_set_lib(raid_tab, obj_id, NULL); 2505711890bcSjc156560 raid_handle_delete_controller_comp(attr->controller_id); 2506711890bcSjc156560 } 2507711890bcSjc156560 break; 2508711890bcSjc156560 case ACT_CONTROLLER_FLASH_FW: 2509711890bcSjc156560 { 2510711890bcSjc156560 char *filebuf; 2511711890bcSjc156560 int image_fd; 2512711890bcSjc156560 uint32_t size; 2513711890bcSjc156560 struct stat statbuf; 2514711890bcSjc156560 2515711890bcSjc156560 if (prop_list == NULL) 2516711890bcSjc156560 return (ERR_OP_ILLEGAL); 2517711890bcSjc156560 2518711890bcSjc156560 /* Open firmware image file */ 2519711890bcSjc156560 image_fd = open((const char *)prop_list, 2520711890bcSjc156560 O_RDONLY | O_NDELAY); 2521711890bcSjc156560 if (image_fd == -1) 2522711890bcSjc156560 return (ERR_OP_FAILED); 2523711890bcSjc156560 2524711890bcSjc156560 if (fstat(image_fd, &statbuf) != 0) { 2525711890bcSjc156560 (void) close(image_fd); 2526711890bcSjc156560 return (ERR_OP_FAILED); 2527711890bcSjc156560 } 2528711890bcSjc156560 2529711890bcSjc156560 filebuf = malloc(statbuf.st_size); 2530711890bcSjc156560 if (filebuf == NULL) { 2531711890bcSjc156560 (void) close(image_fd); 2532711890bcSjc156560 return (ERR_NOMEM); 2533711890bcSjc156560 } 2534711890bcSjc156560 2535711890bcSjc156560 size = read(image_fd, filebuf, statbuf.st_size); 2536711890bcSjc156560 if (size != statbuf.st_size) { 2537711890bcSjc156560 (void) close(image_fd); 2538711890bcSjc156560 free(filebuf); 2539711890bcSjc156560 return (ERR_OP_FAILED); 2540711890bcSjc156560 } 2541711890bcSjc156560 2542711890bcSjc156560 if (fd <= 0) { 2543711890bcSjc156560 (void) close(image_fd); 2544711890bcSjc156560 free(filebuf); 2545711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2546711890bcSjc156560 } 2547711890bcSjc156560 2548711890bcSjc156560 if (raid_lib == NULL) { 2549711890bcSjc156560 (void) close(image_fd); 2550711890bcSjc156560 free(filebuf); 2551711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2552711890bcSjc156560 } 2553711890bcSjc156560 if (raid_lib->flash_fw == NULL) { 2554711890bcSjc156560 (void) close(image_fd); 2555711890bcSjc156560 free(filebuf); 2556711890bcSjc156560 return (ERR_OP_NO_IMPL); 2557711890bcSjc156560 } 2558711890bcSjc156560 2559711890bcSjc156560 ret = raid_lib->flash_fw(attr->controller_id, 2560711890bcSjc156560 filebuf, size, plugin_err_str); 2561711890bcSjc156560 } 2562711890bcSjc156560 break; 2563711890bcSjc156560 default: 2564711890bcSjc156560 return (ERR_OP_ILLEGAL); 2565711890bcSjc156560 } 2566711890bcSjc156560 2567711890bcSjc156560 return (ret); 2568711890bcSjc156560 } 2569711890bcSjc156560 2570711890bcSjc156560 static int 2571711890bcSjc156560 obj_array_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2572711890bcSjc156560 raid_obj_type_id_t comp_type) 2573711890bcSjc156560 { 2574711890bcSjc156560 array_attr_t *attr; 2575711890bcSjc156560 controller_attr_t *ctl_attrp; 2576711890bcSjc156560 raid_obj_id_t controller_obj_id; 2577711890bcSjc156560 raid_lib_t *raid_lib; 2578711890bcSjc156560 int ret = SUCCESS, fd; 2579711890bcSjc156560 2580711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2581711890bcSjc156560 return (ERR_DEVICE_TYPE); 2582711890bcSjc156560 2583711890bcSjc156560 if (comp_type != OBJ_TYPE_ARRAY_PART && 2584711890bcSjc156560 comp_type != OBJ_TYPE_ARRAY && 2585711890bcSjc156560 comp_type != OBJ_TYPE_TASK) 2586711890bcSjc156560 return (0); 2587711890bcSjc156560 2588711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2589711890bcSjc156560 if (attr == NULL) 2590711890bcSjc156560 return (ERR_DEVICE_INVALID); 2591711890bcSjc156560 2592711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2593711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2594711890bcSjc156560 return (ERR_DEVICE_INVALID); 2595711890bcSjc156560 2596711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2597711890bcSjc156560 if (ctl_attrp == NULL) { 2598711890bcSjc156560 return (ERR_DEVICE_INVALID); 2599711890bcSjc156560 } 2600711890bcSjc156560 2601711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2602711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2603711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2604711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2605711890bcSjc156560 2606711890bcSjc156560 ret = raid_lib->compnum(ctl_attrp->controller_id, attr->array_id, 2607711890bcSjc156560 OBJ_TYPE_ARRAY, comp_type); 2608711890bcSjc156560 2609711890bcSjc156560 return (ret); 2610711890bcSjc156560 } 2611711890bcSjc156560 2612711890bcSjc156560 static int 2613711890bcSjc156560 obj_array_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2614711890bcSjc156560 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2615711890bcSjc156560 { 2616711890bcSjc156560 array_attr_t *attr; 2617711890bcSjc156560 controller_attr_t *ctl_attrp; 2618711890bcSjc156560 raid_obj_id_t controller_obj_id; 2619711890bcSjc156560 raid_lib_t *raid_lib; 2620711890bcSjc156560 int ret, i, fd; 2621711890bcSjc156560 uint32_t *ids; 2622711890bcSjc156560 2623711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2624711890bcSjc156560 return (ERR_DEVICE_TYPE); 2625711890bcSjc156560 2626711890bcSjc156560 if (comp_type != OBJ_TYPE_ARRAY_PART && 2627711890bcSjc156560 comp_type != OBJ_TYPE_ARRAY && 2628711890bcSjc156560 comp_type != OBJ_TYPE_TASK) 2629711890bcSjc156560 return (0); 2630711890bcSjc156560 2631711890bcSjc156560 if (comp_num <= 0 || comp_list == NULL) 2632711890bcSjc156560 return (ERR_OP_ILLEGAL); 2633711890bcSjc156560 2634711890bcSjc156560 for (i = 0; i < comp_num; ++i) 2635711890bcSjc156560 if (raid_obj_get_type(raid_tab, *(comp_list + i)) != 2636711890bcSjc156560 comp_type) 2637711890bcSjc156560 return (ERR_DEVICE_TYPE); 2638711890bcSjc156560 2639711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2640711890bcSjc156560 if (attr == NULL) 2641711890bcSjc156560 return (ERR_DEVICE_INVALID); 2642711890bcSjc156560 2643711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2644711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2645711890bcSjc156560 return (ERR_DEVICE_INVALID); 2646711890bcSjc156560 2647711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2648711890bcSjc156560 if (ctl_attrp == NULL) { 2649711890bcSjc156560 return (ERR_DEVICE_INVALID); 2650711890bcSjc156560 } 2651711890bcSjc156560 2652711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2653711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2654711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2655711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2656711890bcSjc156560 2657711890bcSjc156560 ids = malloc(comp_num * sizeof (uint32_t)); 2658711890bcSjc156560 if (ids == NULL) 2659711890bcSjc156560 return (ERR_NOMEM); 2660711890bcSjc156560 2661711890bcSjc156560 ret = raid_lib->complist(ctl_attrp->controller_id, 2662711890bcSjc156560 attr->array_id, OBJ_TYPE_ARRAY, comp_type, comp_num, ids); 2663711890bcSjc156560 2664711890bcSjc156560 if (ret < SUCCESS) { 2665711890bcSjc156560 free(ids); 2666711890bcSjc156560 return (ret); 2667711890bcSjc156560 } 2668711890bcSjc156560 2669711890bcSjc156560 for (i = 0; i < comp_num; ++ i) { 2670711890bcSjc156560 array_attr_t *array_attr; 2671711890bcSjc156560 arraypart_attr_t *arraypart_attr; 2672711890bcSjc156560 task_attr_t *task_attr; 2673711890bcSjc156560 void *attr_buf; 2674711890bcSjc156560 2675711890bcSjc156560 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i)); 2676711890bcSjc156560 if (attr_buf == NULL) { 2677711890bcSjc156560 free(ids); 2678711890bcSjc156560 return (ERR_DEVICE_INVALID); 2679711890bcSjc156560 } 2680711890bcSjc156560 2681711890bcSjc156560 switch (comp_type) { 2682711890bcSjc156560 case OBJ_TYPE_ARRAY: 2683711890bcSjc156560 array_attr = attr_buf; 2684711890bcSjc156560 array_attr->array_id = *(ids + i); 2685711890bcSjc156560 break; 2686711890bcSjc156560 case OBJ_TYPE_ARRAY_PART: 2687711890bcSjc156560 arraypart_attr = attr_buf; 2688711890bcSjc156560 arraypart_attr->disk_id = *(ids + i); 2689711890bcSjc156560 break; 2690711890bcSjc156560 case OBJ_TYPE_TASK: 2691711890bcSjc156560 task_attr = attr_buf; 2692711890bcSjc156560 task_attr->task_id = *(ids + i); 2693711890bcSjc156560 break; 2694711890bcSjc156560 default: 2695711890bcSjc156560 free(ids); 2696711890bcSjc156560 return (ERR_DEVICE_INVALID); 2697711890bcSjc156560 } 2698711890bcSjc156560 } 2699711890bcSjc156560 2700711890bcSjc156560 2701711890bcSjc156560 free(ids); 2702711890bcSjc156560 return (ret); 2703711890bcSjc156560 } 2704711890bcSjc156560 2705711890bcSjc156560 static int 2706711890bcSjc156560 obj_array_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2707711890bcSjc156560 { 2708711890bcSjc156560 array_attr_t *attr; 2709711890bcSjc156560 controller_attr_t *ctl_attrp; 2710711890bcSjc156560 raid_lib_t *raid_lib; 2711711890bcSjc156560 int ret = SUCCESS, fd; 2712711890bcSjc156560 raid_obj_id_t controller_obj_id; 2713711890bcSjc156560 2714711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2715711890bcSjc156560 return (ERR_DEVICE_TYPE); 2716711890bcSjc156560 2717711890bcSjc156560 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 2718711890bcSjc156560 return (SUCCESS); 2719711890bcSjc156560 2720711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2721711890bcSjc156560 if (attr == NULL) 2722711890bcSjc156560 return (ERR_DEVICE_INVALID); 2723711890bcSjc156560 2724711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2725711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2726711890bcSjc156560 return (ERR_DEVICE_INVALID); 2727711890bcSjc156560 2728711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2729711890bcSjc156560 if (ctl_attrp == NULL) { 2730711890bcSjc156560 return (ERR_DEVICE_INVALID); 2731711890bcSjc156560 } 2732711890bcSjc156560 2733711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2734711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2735711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2736711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2737711890bcSjc156560 2738711890bcSjc156560 ret = raid_lib->get_attr(ctl_attrp->controller_id, 2739711890bcSjc156560 attr->array_id, 0, OBJ_TYPE_ARRAY, attr); 2740711890bcSjc156560 2741711890bcSjc156560 if (ret < SUCCESS) 2742711890bcSjc156560 return (ret); 2743711890bcSjc156560 2744711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 2745711890bcSjc156560 2746711890bcSjc156560 return (ret); 2747711890bcSjc156560 } 2748711890bcSjc156560 2749711890bcSjc156560 static int 2750711890bcSjc156560 obj_array_set_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2751711890bcSjc156560 uint32_t sub_cmd, uint32_t *value, char **plugin_err_str) 2752711890bcSjc156560 { 2753711890bcSjc156560 array_attr_t *attr; 2754711890bcSjc156560 controller_attr_t *ctl_attrp; 2755711890bcSjc156560 raid_lib_t *raid_lib; 2756711890bcSjc156560 int ret = SUCCESS, fd; 2757711890bcSjc156560 raid_obj_id_t controller_obj_id; 2758711890bcSjc156560 2759711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY) 2760711890bcSjc156560 return (ERR_DEVICE_TYPE); 2761711890bcSjc156560 2762711890bcSjc156560 switch (sub_cmd) { 2763711890bcSjc156560 case SET_CACHE_WR_PLY: 2764711890bcSjc156560 if (*value != CACHE_WR_OFF && 2765711890bcSjc156560 *value != CACHE_WR_ON) 2766711890bcSjc156560 return (ERR_OP_ILLEGAL); 2767711890bcSjc156560 break; 2768711890bcSjc156560 case SET_CACHE_RD_PLY: 2769711890bcSjc156560 if (*value != CACHE_RD_OFF && 2770711890bcSjc156560 *value != CACHE_RD_ON) 2771711890bcSjc156560 return (ERR_OP_ILLEGAL); 2772711890bcSjc156560 break; 2773*b449fa8aSyw161884 case SET_ACTIVATION_PLY: 2774*b449fa8aSyw161884 if (*value != ARRAY_ACT_ACTIVATE) 2775*b449fa8aSyw161884 return (ERR_OP_ILLEGAL); 2776*b449fa8aSyw161884 break; 2777711890bcSjc156560 default: 2778711890bcSjc156560 return (ERR_OP_ILLEGAL); 2779711890bcSjc156560 } 2780711890bcSjc156560 2781711890bcSjc156560 (void) obj_get_attr(raid_tab, obj_id, (void **)(&attr)); 2782711890bcSjc156560 2783711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2784711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2785711890bcSjc156560 return (ERR_DEVICE_INVALID); 2786711890bcSjc156560 2787711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2788711890bcSjc156560 if (ctl_attrp == NULL) { 2789711890bcSjc156560 return (ERR_DEVICE_INVALID); 2790711890bcSjc156560 } 2791711890bcSjc156560 2792711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2793711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2794711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2795711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2796711890bcSjc156560 2797711890bcSjc156560 if (raid_lib->set_attr == NULL) 2798711890bcSjc156560 return (ERR_OP_NO_IMPL); 2799711890bcSjc156560 2800711890bcSjc156560 ret = raid_lib->set_attr(ctl_attrp->controller_id, 2801711890bcSjc156560 attr->array_id, sub_cmd, value, plugin_err_str); 2802711890bcSjc156560 2803711890bcSjc156560 return (ret); 2804711890bcSjc156560 } 2805711890bcSjc156560 2806711890bcSjc156560 static int 2807711890bcSjc156560 obj_disk_compnum(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2808711890bcSjc156560 raid_obj_type_id_t comp_type) 2809711890bcSjc156560 { 2810711890bcSjc156560 disk_attr_t *attr; 2811711890bcSjc156560 controller_attr_t *ctl_attrp; 2812711890bcSjc156560 raid_obj_id_t controller_obj_id; 2813711890bcSjc156560 raid_lib_t *raid_lib; 2814711890bcSjc156560 int ret = SUCCESS, fd; 2815711890bcSjc156560 2816711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK) 2817711890bcSjc156560 return (ERR_DEVICE_TYPE); 2818711890bcSjc156560 2819711890bcSjc156560 if (comp_type != OBJ_TYPE_DISK_SEG && 2820711890bcSjc156560 comp_type != OBJ_TYPE_HSP && 2821*b449fa8aSyw161884 comp_type != OBJ_TYPE_TASK && 2822*b449fa8aSyw161884 comp_type != OBJ_TYPE_PROP) 2823711890bcSjc156560 return (0); 2824711890bcSjc156560 ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr)); 2825711890bcSjc156560 if ((ret != SUCCESS) || (attr == NULL)) { 2826711890bcSjc156560 return (ERR_DEVICE_INVALID); 2827711890bcSjc156560 } 2828711890bcSjc156560 if (attr->state == DISK_STATE_FAILED) { 2829711890bcSjc156560 return (SUCCESS); 2830711890bcSjc156560 } 2831711890bcSjc156560 2832711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2833711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2834711890bcSjc156560 return (ERR_DEVICE_INVALID); 2835711890bcSjc156560 2836711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2837711890bcSjc156560 if (ctl_attrp == NULL) { 2838711890bcSjc156560 return (ERR_DEVICE_INVALID); 2839711890bcSjc156560 } 2840711890bcSjc156560 2841711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2842711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2843711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2844711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2845711890bcSjc156560 2846711890bcSjc156560 ret = raid_lib->compnum(ctl_attrp->controller_id, 2847711890bcSjc156560 attr->disk_id, OBJ_TYPE_DISK, comp_type); 2848711890bcSjc156560 2849711890bcSjc156560 return (ret); 2850711890bcSjc156560 } 2851711890bcSjc156560 2852711890bcSjc156560 static int 2853711890bcSjc156560 obj_disk_complist(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 2854711890bcSjc156560 int comp_num, raid_obj_id_t *comp_list, raid_obj_type_id_t comp_type) 2855711890bcSjc156560 { 2856711890bcSjc156560 disk_attr_t *attr; 2857711890bcSjc156560 controller_attr_t *ctl_attrp; 2858711890bcSjc156560 raid_obj_id_t controller_obj_id; 2859711890bcSjc156560 raid_lib_t *raid_lib; 2860711890bcSjc156560 int ret, i, fd; 2861711890bcSjc156560 uint32_t *ids; 2862711890bcSjc156560 2863711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK) 2864711890bcSjc156560 return (ERR_DEVICE_TYPE); 2865711890bcSjc156560 2866711890bcSjc156560 if (comp_type != OBJ_TYPE_DISK_SEG && 2867711890bcSjc156560 comp_type != OBJ_TYPE_HSP && 2868*b449fa8aSyw161884 comp_type != OBJ_TYPE_TASK && 2869*b449fa8aSyw161884 comp_type != OBJ_TYPE_PROP) 2870711890bcSjc156560 return (0); 2871711890bcSjc156560 2872711890bcSjc156560 if (comp_num <= 0 || comp_list == NULL) 2873711890bcSjc156560 return (ERR_OP_ILLEGAL); 2874711890bcSjc156560 2875711890bcSjc156560 for (i = 0; i < comp_num; ++i) 2876711890bcSjc156560 if (raid_obj_get_type(raid_tab, *(comp_list + i)) != 2877711890bcSjc156560 comp_type) 2878711890bcSjc156560 return (ERR_DEVICE_TYPE); 2879711890bcSjc156560 ret = obj_get_attr(raid_tab, obj_id, (void **)(&attr)); 2880711890bcSjc156560 if ((ret != SUCCESS) || (attr == NULL)) { 2881711890bcSjc156560 return (ERR_DEVICE_INVALID); 2882711890bcSjc156560 } 2883711890bcSjc156560 if (attr->state == DISK_STATE_FAILED) { 2884711890bcSjc156560 return (SUCCESS); 2885711890bcSjc156560 } 2886711890bcSjc156560 2887711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2888711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2889711890bcSjc156560 return (ERR_DEVICE_INVALID); 2890711890bcSjc156560 2891711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2892711890bcSjc156560 if (ctl_attrp == NULL) { 2893711890bcSjc156560 return (ERR_DEVICE_INVALID); 2894711890bcSjc156560 } 2895711890bcSjc156560 2896711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2897711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2898711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2899711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2900711890bcSjc156560 2901711890bcSjc156560 ids = malloc(comp_num * sizeof (uint32_t)); 2902711890bcSjc156560 if (ids == NULL) 2903711890bcSjc156560 return (ERR_NOMEM); 2904711890bcSjc156560 2905711890bcSjc156560 ret = raid_lib->complist(ctl_attrp->controller_id, 2906711890bcSjc156560 attr->disk_id, OBJ_TYPE_DISK, comp_type, comp_num, ids); 2907711890bcSjc156560 2908711890bcSjc156560 if (ret < SUCCESS) { 2909711890bcSjc156560 free(ids); 2910711890bcSjc156560 return (ret); 2911711890bcSjc156560 } 2912711890bcSjc156560 2913711890bcSjc156560 for (i = 0; i < comp_num; ++ i) { 2914711890bcSjc156560 diskseg_attr_t *diskseg_attr; 2915711890bcSjc156560 hsp_attr_t *hsp_attr; 2916711890bcSjc156560 task_attr_t *task_attr; 2917*b449fa8aSyw161884 property_attr_t *prop_attr; 2918711890bcSjc156560 void *attr_buf; 2919711890bcSjc156560 2920711890bcSjc156560 attr_buf = raid_obj_get_data_ptr(raid_tab, *(comp_list + i)); 2921711890bcSjc156560 if (attr_buf == NULL) { 2922711890bcSjc156560 free(ids); 2923711890bcSjc156560 return (ERR_DEVICE_INVALID); 2924711890bcSjc156560 } 2925711890bcSjc156560 2926711890bcSjc156560 switch (comp_type) { 2927711890bcSjc156560 case OBJ_TYPE_DISK_SEG: 2928711890bcSjc156560 diskseg_attr = attr_buf; 2929711890bcSjc156560 diskseg_attr->seq_no = *(ids + i); 2930711890bcSjc156560 break; 2931711890bcSjc156560 case OBJ_TYPE_HSP: 2932711890bcSjc156560 hsp_attr = attr_buf; 2933711890bcSjc156560 hsp_attr->associated_id = *(ids + i); 2934711890bcSjc156560 break; 2935711890bcSjc156560 case OBJ_TYPE_TASK: 2936711890bcSjc156560 task_attr = attr_buf; 2937711890bcSjc156560 task_attr->task_id = *(ids + i); 2938711890bcSjc156560 break; 2939*b449fa8aSyw161884 case OBJ_TYPE_PROP: 2940*b449fa8aSyw161884 prop_attr = attr_buf; 2941*b449fa8aSyw161884 prop_attr->prop_id = *(ids + i); 2942*b449fa8aSyw161884 break; 2943711890bcSjc156560 default: 2944711890bcSjc156560 free(ids); 2945711890bcSjc156560 return (ERR_DEVICE_INVALID); 2946711890bcSjc156560 } 2947711890bcSjc156560 } 2948711890bcSjc156560 2949711890bcSjc156560 2950711890bcSjc156560 free(ids); 2951711890bcSjc156560 return (ret); 2952711890bcSjc156560 } 2953711890bcSjc156560 2954711890bcSjc156560 static int 2955711890bcSjc156560 obj_disk_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 2956711890bcSjc156560 { 2957711890bcSjc156560 disk_attr_t *attr; 2958711890bcSjc156560 controller_attr_t *ctl_attrp; 2959711890bcSjc156560 raid_lib_t *raid_lib; 2960711890bcSjc156560 int ret = SUCCESS, fd; 2961711890bcSjc156560 raid_obj_id_t controller_obj_id; 2962711890bcSjc156560 2963711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK) 2964711890bcSjc156560 return (ERR_DEVICE_TYPE); 2965711890bcSjc156560 2966711890bcSjc156560 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 2967711890bcSjc156560 return (SUCCESS); 2968711890bcSjc156560 2969711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 2970711890bcSjc156560 if (attr == NULL) 2971711890bcSjc156560 return (ERR_DEVICE_INVALID); 2972711890bcSjc156560 2973711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 2974711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 2975711890bcSjc156560 return (ERR_DEVICE_INVALID); 2976711890bcSjc156560 2977711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 2978711890bcSjc156560 if (ctl_attrp == NULL) { 2979711890bcSjc156560 return (ERR_DEVICE_INVALID); 2980711890bcSjc156560 } 2981711890bcSjc156560 2982711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 2983711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 2984711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 2985711890bcSjc156560 return (ERR_DRIVER_CLOSED); 2986711890bcSjc156560 2987711890bcSjc156560 ret = raid_lib->get_attr(ctl_attrp->controller_id, 2988711890bcSjc156560 attr->disk_id, 0, OBJ_TYPE_DISK, attr); 2989711890bcSjc156560 2990711890bcSjc156560 if (ret < SUCCESS) 2991711890bcSjc156560 return (ret); 2992711890bcSjc156560 2993711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 2994711890bcSjc156560 2995711890bcSjc156560 return (ret); 2996711890bcSjc156560 } 2997711890bcSjc156560 2998711890bcSjc156560 static int 2999711890bcSjc156560 obj_hsp_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3000711890bcSjc156560 { 3001711890bcSjc156560 hsp_attr_t *attr; 3002711890bcSjc156560 3003711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_HSP) 3004711890bcSjc156560 return (ERR_DEVICE_TYPE); 3005711890bcSjc156560 3006711890bcSjc156560 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3007711890bcSjc156560 return (SUCCESS); 3008711890bcSjc156560 3009711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3010711890bcSjc156560 if (attr == NULL) 3011711890bcSjc156560 return (ERR_DEVICE_INVALID); 3012711890bcSjc156560 3013711890bcSjc156560 if (attr->associated_id == (uint32_t)OBJ_ATTR_NONE) 3014711890bcSjc156560 attr->type = HSP_TYPE_GLOBAL; 3015711890bcSjc156560 else 3016711890bcSjc156560 attr->type = HSP_TYPE_LOCAL; 3017711890bcSjc156560 3018711890bcSjc156560 return (SUCCESS); 3019711890bcSjc156560 } 3020711890bcSjc156560 3021711890bcSjc156560 static int 3022711890bcSjc156560 obj_arraypart_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3023711890bcSjc156560 { 3024711890bcSjc156560 arraypart_attr_t *attr; 3025711890bcSjc156560 array_attr_t *array_attr; 3026711890bcSjc156560 controller_attr_t *ctl_attrp; 3027711890bcSjc156560 raid_lib_t *raid_lib; 3028711890bcSjc156560 int ret = SUCCESS, fd; 3029711890bcSjc156560 raid_obj_id_t controller_obj_id, array_obj_id; 3030711890bcSjc156560 3031711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_ARRAY_PART) 3032711890bcSjc156560 return (ERR_DEVICE_TYPE); 3033711890bcSjc156560 3034711890bcSjc156560 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3035711890bcSjc156560 return (SUCCESS); 3036711890bcSjc156560 3037711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3038711890bcSjc156560 if (attr == NULL) 3039711890bcSjc156560 return (ERR_DEVICE_INVALID); 3040711890bcSjc156560 3041711890bcSjc156560 array_obj_id = raid_obj_get_container(raid_tab, obj_id); 3042711890bcSjc156560 if (array_obj_id < OBJ_NONE) 3043711890bcSjc156560 return (ERR_DEVICE_INVALID); 3044711890bcSjc156560 3045711890bcSjc156560 array_attr = raid_obj_get_data_ptr(raid_tab, array_obj_id); 3046711890bcSjc156560 if (array_attr == NULL) 3047711890bcSjc156560 return (ERR_DEVICE_INVALID); 3048711890bcSjc156560 3049711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3050711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 3051711890bcSjc156560 return (ERR_DEVICE_INVALID); 3052711890bcSjc156560 3053711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3054711890bcSjc156560 if (ctl_attrp == NULL) { 3055711890bcSjc156560 return (ERR_DEVICE_INVALID); 3056711890bcSjc156560 } 3057711890bcSjc156560 3058711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3059711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3060711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3061711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3062711890bcSjc156560 3063711890bcSjc156560 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3064711890bcSjc156560 array_attr->array_id, attr->disk_id, 3065711890bcSjc156560 OBJ_TYPE_ARRAY_PART, attr); 3066711890bcSjc156560 3067711890bcSjc156560 if (ret < SUCCESS) 3068711890bcSjc156560 return (ret); 3069711890bcSjc156560 3070711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 3071711890bcSjc156560 3072711890bcSjc156560 return (ret); 3073711890bcSjc156560 } 3074711890bcSjc156560 3075711890bcSjc156560 static int 3076711890bcSjc156560 obj_diskseg_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3077711890bcSjc156560 { 3078711890bcSjc156560 diskseg_attr_t *attr; 3079711890bcSjc156560 disk_attr_t *disk_attr; 3080711890bcSjc156560 controller_attr_t *ctl_attrp; 3081711890bcSjc156560 raid_lib_t *raid_lib; 3082711890bcSjc156560 int ret = SUCCESS, fd; 3083711890bcSjc156560 raid_obj_id_t controller_obj_id, disk_obj_id; 3084711890bcSjc156560 3085711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_DISK_SEG) 3086711890bcSjc156560 return (ERR_DEVICE_TYPE); 3087711890bcSjc156560 3088711890bcSjc156560 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3089711890bcSjc156560 return (SUCCESS); 3090711890bcSjc156560 3091711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3092711890bcSjc156560 if (attr == NULL) 3093711890bcSjc156560 return (ERR_DEVICE_INVALID); 3094711890bcSjc156560 3095711890bcSjc156560 disk_obj_id = raid_obj_get_container(raid_tab, obj_id); 3096711890bcSjc156560 if (disk_obj_id < OBJ_NONE) 3097711890bcSjc156560 return (ERR_DEVICE_INVALID); 3098711890bcSjc156560 3099711890bcSjc156560 disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id); 3100711890bcSjc156560 if (disk_attr == NULL) 3101711890bcSjc156560 return (ERR_DEVICE_INVALID); 3102711890bcSjc156560 3103711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3104711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 3105711890bcSjc156560 return (ERR_DEVICE_INVALID); 3106711890bcSjc156560 3107711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3108711890bcSjc156560 if (ctl_attrp == NULL) { 3109711890bcSjc156560 return (ERR_DEVICE_INVALID); 3110711890bcSjc156560 } 3111711890bcSjc156560 3112711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3113711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3114711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3115711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3116711890bcSjc156560 3117711890bcSjc156560 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3118711890bcSjc156560 disk_attr->disk_id, attr->seq_no, OBJ_TYPE_DISK_SEG, attr); 3119711890bcSjc156560 3120711890bcSjc156560 if (ret < SUCCESS) 3121711890bcSjc156560 return (ret); 3122711890bcSjc156560 3123711890bcSjc156560 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 3124711890bcSjc156560 3125711890bcSjc156560 return (ret); 3126711890bcSjc156560 } 3127711890bcSjc156560 3128711890bcSjc156560 static int 3129711890bcSjc156560 obj_task_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3130711890bcSjc156560 { 3131711890bcSjc156560 task_attr_t *attr; 3132711890bcSjc156560 controller_attr_t *ctl_attrp; 3133711890bcSjc156560 raid_lib_t *raid_lib; 3134711890bcSjc156560 int ret = SUCCESS, fd; 3135711890bcSjc156560 raid_obj_id_t controller_obj_id; 3136711890bcSjc156560 3137711890bcSjc156560 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_TASK) 3138711890bcSjc156560 return (ERR_DEVICE_TYPE); 3139711890bcSjc156560 3140711890bcSjc156560 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3141711890bcSjc156560 if (attr == NULL) 3142711890bcSjc156560 return (ERR_DEVICE_INVALID); 3143711890bcSjc156560 3144711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3145711890bcSjc156560 if (controller_obj_id < OBJ_NONE) 3146711890bcSjc156560 return (ERR_DEVICE_INVALID); 3147711890bcSjc156560 3148711890bcSjc156560 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3149711890bcSjc156560 if (ctl_attrp == NULL) { 3150711890bcSjc156560 return (ERR_DEVICE_INVALID); 3151711890bcSjc156560 } 3152711890bcSjc156560 3153711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3154711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3155711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3156711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3157711890bcSjc156560 3158711890bcSjc156560 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3159711890bcSjc156560 attr->task_id, OBJ_ATTR_NONE, OBJ_TYPE_TASK, attr); 3160711890bcSjc156560 3161711890bcSjc156560 return (ret); 3162711890bcSjc156560 } 3163711890bcSjc156560 3164711890bcSjc156560 static int 3165*b449fa8aSyw161884 obj_prop_get_attr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 3166*b449fa8aSyw161884 { 3167*b449fa8aSyw161884 property_attr_t *attr, *attr_new; 3168*b449fa8aSyw161884 disk_attr_t *disk_attr; 3169*b449fa8aSyw161884 controller_attr_t *ctl_attrp; 3170*b449fa8aSyw161884 raid_lib_t *raid_lib; 3171*b449fa8aSyw161884 int ret = SUCCESS, fd; 3172*b449fa8aSyw161884 raid_obj_id_t controller_obj_id, disk_obj_id; 3173*b449fa8aSyw161884 3174*b449fa8aSyw161884 if (raid_obj_get_type(raid_tab, obj_id) != OBJ_TYPE_PROP) 3175*b449fa8aSyw161884 return (ERR_DEVICE_TYPE); 3176*b449fa8aSyw161884 3177*b449fa8aSyw161884 if (raid_obj_get_status(raid_tab, obj_id) & OBJ_STATUS_OPENED) 3178*b449fa8aSyw161884 return (SUCCESS); 3179*b449fa8aSyw161884 3180*b449fa8aSyw161884 attr = raid_obj_get_data_ptr(raid_tab, obj_id); 3181*b449fa8aSyw161884 if (attr == NULL) 3182*b449fa8aSyw161884 return (ERR_DEVICE_INVALID); 3183*b449fa8aSyw161884 3184*b449fa8aSyw161884 disk_obj_id = raid_obj_get_container(raid_tab, obj_id); 3185*b449fa8aSyw161884 if (disk_obj_id < OBJ_NONE) 3186*b449fa8aSyw161884 return (ERR_DEVICE_INVALID); 3187*b449fa8aSyw161884 3188*b449fa8aSyw161884 disk_attr = raid_obj_get_data_ptr(raid_tab, disk_obj_id); 3189*b449fa8aSyw161884 if (disk_attr == NULL) 3190*b449fa8aSyw161884 return (ERR_DEVICE_INVALID); 3191*b449fa8aSyw161884 3192*b449fa8aSyw161884 controller_obj_id = obj_get_controller(raid_tab, obj_id); 3193*b449fa8aSyw161884 if (controller_obj_id < OBJ_NONE) 3194*b449fa8aSyw161884 return (ERR_DEVICE_INVALID); 3195*b449fa8aSyw161884 3196*b449fa8aSyw161884 ctl_attrp = raid_obj_get_data_ptr(raid_tab, controller_obj_id); 3197*b449fa8aSyw161884 if (ctl_attrp == NULL) { 3198*b449fa8aSyw161884 return (ERR_DEVICE_INVALID); 3199*b449fa8aSyw161884 } 3200*b449fa8aSyw161884 3201*b449fa8aSyw161884 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3202*b449fa8aSyw161884 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3203*b449fa8aSyw161884 if ((raid_lib == NULL) || (fd == 0)) 3204*b449fa8aSyw161884 return (ERR_DRIVER_CLOSED); 3205*b449fa8aSyw161884 3206*b449fa8aSyw161884 /* Get the property size at first */ 3207*b449fa8aSyw161884 attr->prop_size = 0; 3208*b449fa8aSyw161884 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3209*b449fa8aSyw161884 disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr); 3210*b449fa8aSyw161884 3211*b449fa8aSyw161884 if (ret < SUCCESS) 3212*b449fa8aSyw161884 return (ret); 3213*b449fa8aSyw161884 3214*b449fa8aSyw161884 /* Allocate memory for property and fill the buffer */ 3215*b449fa8aSyw161884 attr_new = realloc(attr, sizeof (property_attr_t) + attr->prop_size); 3216*b449fa8aSyw161884 if (attr_new == NULL) 3217*b449fa8aSyw161884 return (ERR_NOMEM); 3218*b449fa8aSyw161884 3219*b449fa8aSyw161884 (void) raid_obj_set_data_ptr(raid_tab, obj_id, attr_new); 3220*b449fa8aSyw161884 3221*b449fa8aSyw161884 ret = raid_lib->get_attr(ctl_attrp->controller_id, 3222*b449fa8aSyw161884 disk_attr->disk_id, OBJ_ATTR_NONE, OBJ_TYPE_PROP, attr_new); 3223*b449fa8aSyw161884 3224*b449fa8aSyw161884 if (ret < SUCCESS) 3225*b449fa8aSyw161884 return (ret); 3226*b449fa8aSyw161884 3227*b449fa8aSyw161884 (void) raid_obj_set_status(raid_tab, obj_id, OBJ_STATUS_OPENED); 3228*b449fa8aSyw161884 3229*b449fa8aSyw161884 return (ret); 3230*b449fa8aSyw161884 } 3231*b449fa8aSyw161884 3232*b449fa8aSyw161884 static int 3233711890bcSjc156560 obj_array_create(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id, 3234711890bcSjc156560 int num_of_comp, raid_obj_id_t *disk_list, char **plugin_err_str) 3235711890bcSjc156560 { 3236711890bcSjc156560 controller_attr_t *controller_attr; 3237711890bcSjc156560 array_attr_t *array_attr, array_attr2; 3238711890bcSjc156560 disk_attr_t *disk_attr; 3239711890bcSjc156560 arraypart_attr_t *arraypart_attrs; 3240711890bcSjc156560 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE; 3241711890bcSjc156560 raid_lib_t *raid_lib; 3242711890bcSjc156560 int i, j, ret, fd; 3243711890bcSjc156560 int disk_cnt = 0, disk_set_num = 0, set_num = 0, layer_cnt = 0; 3244711890bcSjc156560 uint64_t min_disk_capacity = 0; 3245711890bcSjc156560 3246711890bcSjc156560 array_attr = raid_obj_get_data_ptr(raid_tab, array_obj_id); 3247711890bcSjc156560 if (array_attr == NULL) 3248711890bcSjc156560 return (ERR_DEVICE_INVALID); 3249711890bcSjc156560 3250711890bcSjc156560 /* Check the disk layout expression */ 3251711890bcSjc156560 if (disk_list[0] != OBJ_SEPARATOR_BEGIN || 3252711890bcSjc156560 disk_list[num_of_comp - 1] != OBJ_SEPARATOR_END) 3253711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3254711890bcSjc156560 for (i = 0; i < num_of_comp; ++i) { 3255711890bcSjc156560 if (disk_list[i] == OBJ_SEPARATOR_BEGIN) { 3256711890bcSjc156560 if (disk_cnt != 0) 3257711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3258711890bcSjc156560 ++layer_cnt; 3259711890bcSjc156560 continue; 3260711890bcSjc156560 } 3261711890bcSjc156560 if (disk_list[i] == OBJ_SEPARATOR_END) { 3262711890bcSjc156560 if (disk_set_num == 0) 3263711890bcSjc156560 disk_set_num = disk_cnt; 3264711890bcSjc156560 else if (disk_set_num != disk_cnt && disk_cnt != 0) 3265711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3266711890bcSjc156560 disk_cnt = 0; 3267711890bcSjc156560 ++set_num; 3268711890bcSjc156560 --layer_cnt; 3269711890bcSjc156560 continue; 3270711890bcSjc156560 } 3271711890bcSjc156560 switch (array_attr->raid_level) { 3272711890bcSjc156560 case RAID_LEVEL_0: 3273711890bcSjc156560 case RAID_LEVEL_1: 3274711890bcSjc156560 case RAID_LEVEL_1E: 3275711890bcSjc156560 case RAID_LEVEL_5: 3276711890bcSjc156560 if (layer_cnt != 1) 3277711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3278711890bcSjc156560 break; 3279711890bcSjc156560 case RAID_LEVEL_10: 3280711890bcSjc156560 case RAID_LEVEL_50: 3281711890bcSjc156560 if (layer_cnt != 2) 3282711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3283711890bcSjc156560 break; 3284711890bcSjc156560 default: 3285711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3286711890bcSjc156560 } 3287711890bcSjc156560 ++disk_cnt; 3288711890bcSjc156560 } 3289711890bcSjc156560 3290711890bcSjc156560 if (layer_cnt != 0) 3291711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3292711890bcSjc156560 3293711890bcSjc156560 switch (array_attr->raid_level) { 3294711890bcSjc156560 case RAID_LEVEL_0: 3295711890bcSjc156560 if (disk_set_num < 2 || set_num != 1) 3296711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3297711890bcSjc156560 break; 3298711890bcSjc156560 case RAID_LEVEL_1: 3299711890bcSjc156560 if (disk_set_num != 2 || set_num != 1) 3300711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3301711890bcSjc156560 break; 3302711890bcSjc156560 case RAID_LEVEL_1E: 3303711890bcSjc156560 case RAID_LEVEL_5: 3304711890bcSjc156560 if (disk_set_num < 3 || set_num != 1) 3305711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3306711890bcSjc156560 break; 3307711890bcSjc156560 case RAID_LEVEL_10: 3308711890bcSjc156560 if (disk_set_num != 2 || set_num < 2) 3309711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3310711890bcSjc156560 break; 3311711890bcSjc156560 case RAID_LEVEL_50: 3312711890bcSjc156560 if (disk_set_num < 3 || set_num < 2) 3313711890bcSjc156560 return (ERR_ARRAY_LAYOUT); 3314711890bcSjc156560 break; 3315711890bcSjc156560 default: 3316711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3317711890bcSjc156560 } 3318711890bcSjc156560 3319711890bcSjc156560 arraypart_attrs = calloc(num_of_comp, sizeof (arraypart_attr_t)); 3320711890bcSjc156560 if (arraypart_attrs == NULL) 3321711890bcSjc156560 return (ERR_NOMEM); 3322711890bcSjc156560 3323711890bcSjc156560 for (i = 0; i < num_of_comp; ++i) { 3324711890bcSjc156560 /* Keep seperators */ 3325711890bcSjc156560 if (*(disk_list + i) == OBJ_SEPARATOR_BEGIN) { 3326711890bcSjc156560 arraypart_attrs[i].disk_id = 3327711890bcSjc156560 (uint32_t)OBJ_SEPARATOR_BEGIN; 3328711890bcSjc156560 continue; 3329711890bcSjc156560 } 3330711890bcSjc156560 3331711890bcSjc156560 if (*(disk_list + i) == OBJ_SEPARATOR_END) { 3332711890bcSjc156560 arraypart_attrs[i].disk_id = 3333711890bcSjc156560 (uint32_t)OBJ_SEPARATOR_END; 3334711890bcSjc156560 continue; 3335711890bcSjc156560 } 3336711890bcSjc156560 3337711890bcSjc156560 disk_cnt++; 3338711890bcSjc156560 /* Check if it's a disk */ 3339711890bcSjc156560 if (raid_obj_get_type(raid_tab, *(disk_list + i)) != 3340711890bcSjc156560 OBJ_TYPE_DISK) 3341711890bcSjc156560 return (ERR_DEVICE_TYPE); 3342711890bcSjc156560 3343711890bcSjc156560 /* Check if it's duplicated with other disks */ 3344711890bcSjc156560 for (j = 0; j < i; ++j) 3345711890bcSjc156560 if (*(disk_list + j) == *(disk_list + i)) { 3346711890bcSjc156560 free(arraypart_attrs); 3347711890bcSjc156560 return (ERR_DEVICE_DUP); 3348711890bcSjc156560 } 3349711890bcSjc156560 3350711890bcSjc156560 /* Check disk status */ 3351711890bcSjc156560 ret = obj_get_attr(raid_tab, *(disk_list + i), 3352711890bcSjc156560 (void **)(&disk_attr)); 3353711890bcSjc156560 if (ret != SUCCESS) 3354711890bcSjc156560 return (ret); 3355711890bcSjc156560 3356711890bcSjc156560 if (disk_attr->state != DISK_STATE_GOOD) { 3357711890bcSjc156560 free(arraypart_attrs); 3358711890bcSjc156560 return (ERR_DISK_STATE); 3359711890bcSjc156560 } 3360711890bcSjc156560 3361711890bcSjc156560 /* All disks must belong to the same controller */ 3362711890bcSjc156560 obj_id = obj_get_controller(raid_tab, *(disk_list + i)); 3363711890bcSjc156560 if (obj_id <= OBJ_NONE) 3364711890bcSjc156560 return (obj_id); 3365711890bcSjc156560 if (controller_obj_id == OBJ_NONE) { 3366711890bcSjc156560 controller_obj_id = obj_id; 3367711890bcSjc156560 ret = obj_get_attr(raid_tab, controller_obj_id, 3368711890bcSjc156560 (void **)(&controller_attr)); 3369711890bcSjc156560 } else if (obj_id != controller_obj_id) { 3370711890bcSjc156560 free(arraypart_attrs); 3371711890bcSjc156560 return (ERR_DRIVER_ACROSS); 3372711890bcSjc156560 } 3373711890bcSjc156560 3374711890bcSjc156560 /* Check if the disk contains too many segments */ 3375711890bcSjc156560 obj_id = obj_get_comp(raid_tab, *(disk_list + i), 3376711890bcSjc156560 OBJ_TYPE_DISK_SEG); 3377711890bcSjc156560 j = 0; 3378711890bcSjc156560 while (obj_id > OBJ_NONE) { 3379711890bcSjc156560 ++j; 3380711890bcSjc156560 obj_id = obj_get_sibling(raid_tab, obj_id); 3381711890bcSjc156560 } 3382711890bcSjc156560 if (j > controller_attr->max_seg_per_disk) { 3383711890bcSjc156560 free(arraypart_attrs); 3384711890bcSjc156560 return (ERR_DISK_SEG_AMOUNT); 3385711890bcSjc156560 } 3386711890bcSjc156560 3387711890bcSjc156560 /* Check if controller is a hostraid controller */ 3388711890bcSjc156560 if (controller_attr->capability & RAID_CAP_DISK_TRANS) { 3389711890bcSjc156560 /* 3390711890bcSjc156560 * For hostraid, the first disk should 3391711890bcSjc156560 * be with of minimum capacity 3392711890bcSjc156560 */ 3393711890bcSjc156560 if (min_disk_capacity == 0) { 3394711890bcSjc156560 min_disk_capacity = disk_attr->capacity; 3395711890bcSjc156560 3396711890bcSjc156560 /* Can not specify capacity for hostraid */ 3397711890bcSjc156560 if (array_attr->capacity != 0) { 3398711890bcSjc156560 free(arraypart_attrs); 3399700682b8Syw161884 return (ERR_OP_ILLEGAL); 3400711890bcSjc156560 } 3401711890bcSjc156560 } else if (min_disk_capacity > disk_attr->capacity) { 3402711890bcSjc156560 free(arraypart_attrs); 3403711890bcSjc156560 return (ERR_DISK_SPACE); 3404711890bcSjc156560 } 3405711890bcSjc156560 3406711890bcSjc156560 /* Disk should not be used for hostraid */ 3407711890bcSjc156560 obj_id = obj_get_comp(raid_tab, *(disk_list + i), 3408711890bcSjc156560 OBJ_TYPE_DISK_SEG); 3409711890bcSjc156560 if (obj_id < OBJ_NONE) { 3410711890bcSjc156560 free(arraypart_attrs); 3411711890bcSjc156560 return (obj_id); 3412711890bcSjc156560 } else if (obj_id > OBJ_NONE) { 3413711890bcSjc156560 free(arraypart_attrs); 3414711890bcSjc156560 return (ERR_DISK_NOT_EMPTY); 3415711890bcSjc156560 } 3416711890bcSjc156560 } 3417711890bcSjc156560 3418711890bcSjc156560 arraypart_attrs[i].disk_id = disk_attr->disk_id; 3419711890bcSjc156560 arraypart_attrs[i].offset = OBJ_ATTR_NONE; 3420711890bcSjc156560 arraypart_attrs[i].size = OBJ_ATTR_NONE; 3421711890bcSjc156560 } 3422711890bcSjc156560 3423711890bcSjc156560 /* Check if array amount exceeds limit */ 3424711890bcSjc156560 if (controller_attr->max_array_num <= 3425711890bcSjc156560 obj_controller_compnum(raid_tab, controller_obj_id, 3426711890bcSjc156560 OBJ_TYPE_ARRAY)) 3427711890bcSjc156560 return (ERR_ARRAY_AMOUNT); 3428711890bcSjc156560 3429711890bcSjc156560 3430711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3431711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3432711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3433711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3434711890bcSjc156560 3435711890bcSjc156560 /* Check if the controller can support the array RAID level */ 3436711890bcSjc156560 switch (array_attr->raid_level) { 3437711890bcSjc156560 case RAID_LEVEL_0: 3438711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_RAID0)) { 3439711890bcSjc156560 free(arraypart_attrs); 3440711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3441711890bcSjc156560 } 3442711890bcSjc156560 break; 3443711890bcSjc156560 case RAID_LEVEL_1: 3444711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_RAID1)) { 3445711890bcSjc156560 free(arraypart_attrs); 3446711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3447711890bcSjc156560 } 3448711890bcSjc156560 break; 3449711890bcSjc156560 case RAID_LEVEL_1E: 3450711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_RAID1E)) { 3451711890bcSjc156560 free(arraypart_attrs); 3452711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3453711890bcSjc156560 } 3454711890bcSjc156560 break; 3455711890bcSjc156560 case RAID_LEVEL_5: 3456711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_RAID5)) { 3457711890bcSjc156560 free(arraypart_attrs); 3458711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3459711890bcSjc156560 } 3460711890bcSjc156560 break; 3461711890bcSjc156560 case RAID_LEVEL_10: 3462711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_RAID10)) { 3463711890bcSjc156560 free(arraypart_attrs); 3464711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3465711890bcSjc156560 } 3466711890bcSjc156560 break; 3467711890bcSjc156560 case RAID_LEVEL_50: 3468711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_RAID50)) { 3469711890bcSjc156560 free(arraypart_attrs); 3470711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3471711890bcSjc156560 } 3472711890bcSjc156560 break; 3473711890bcSjc156560 default: 3474711890bcSjc156560 free(arraypart_attrs); 3475711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3476711890bcSjc156560 } 3477711890bcSjc156560 3478711890bcSjc156560 /* Check if plug in can calculate the maximum size */ 3479711890bcSjc156560 (void) memcpy(&array_attr2, array_attr, sizeof (array_attr_t)); 3480711890bcSjc156560 array_attr2.capacity = OBJ_ATTR_NONE; 3481711890bcSjc156560 ret = raid_lib->array_create(controller_attr->controller_id, 3482711890bcSjc156560 &array_attr2, num_of_comp, arraypart_attrs, plugin_err_str); 3483711890bcSjc156560 3484711890bcSjc156560 /* If plugin/driver will not calculate space */ 3485711890bcSjc156560 if (ret == ERR_OP_NO_IMPL) { 3486711890bcSjc156560 /* Calculate the maximum capacity */ 3487711890bcSjc156560 array_attr2.capacity = raid_space_noalign(raid_tab, 3488711890bcSjc156560 array_attr2.raid_level, num_of_comp, disk_list, 3489711890bcSjc156560 arraypart_attrs); 3490711890bcSjc156560 3491711890bcSjc156560 /* 3492711890bcSjc156560 * If controller is capable to allocate space, 3493711890bcSjc156560 * set offset and size attributes to OBJ_ATTR_NONE 3494711890bcSjc156560 * and let the controller to determine these value 3495711890bcSjc156560 */ 3496711890bcSjc156560 if (controller_attr->capability & RAID_CAP_SMART_ALLOC) 3497711890bcSjc156560 for (i = 0; i < num_of_comp; ++i) { 3498711890bcSjc156560 arraypart_attrs[i].offset = 3499711890bcSjc156560 OBJ_ATTR_NONE; 3500711890bcSjc156560 arraypart_attrs[i].size = 3501711890bcSjc156560 OBJ_ATTR_NONE; 3502711890bcSjc156560 } 3503711890bcSjc156560 3504711890bcSjc156560 /* There's no enough space for specified capacity */ 3505711890bcSjc156560 if (array_attr->capacity > array_attr2.capacity) { 3506711890bcSjc156560 free(arraypart_attrs); 3507711890bcSjc156560 return (ERR_ARRAY_SIZE); 3508711890bcSjc156560 } 3509711890bcSjc156560 3510711890bcSjc156560 /* capacity == 0, allocate maximum space */ 3511711890bcSjc156560 if (array_attr->capacity == 0) 3512711890bcSjc156560 array_attr->capacity = array_attr2.capacity; 3513711890bcSjc156560 } else if (ret < SUCCESS) { 3514711890bcSjc156560 free(arraypart_attrs); 3515711890bcSjc156560 return (ret); 3516711890bcSjc156560 } else if (array_attr2.capacity < array_attr->capacity) { 3517711890bcSjc156560 /* Return the maximum size */ 3518711890bcSjc156560 array_attr->capacity = array_attr2.capacity; 3519711890bcSjc156560 free(arraypart_attrs); 3520711890bcSjc156560 return (ERR_ARRAY_SIZE); 3521711890bcSjc156560 } 3522711890bcSjc156560 3523711890bcSjc156560 if (array_attr->capacity < ARRAYPART_MIN_SIZE * disk_cnt) { 3524711890bcSjc156560 free(arraypart_attrs); 3525711890bcSjc156560 return (ERR_ARRAY_SIZE); 3526711890bcSjc156560 } 3527711890bcSjc156560 3528711890bcSjc156560 3529711890bcSjc156560 ret = raid_lib->array_create(controller_attr->controller_id, 3530711890bcSjc156560 array_attr, num_of_comp, arraypart_attrs, plugin_err_str); 3531711890bcSjc156560 free(arraypart_attrs); 3532711890bcSjc156560 3533711890bcSjc156560 if (ret != SUCCESS) 3534711890bcSjc156560 return (ret); 3535711890bcSjc156560 3536711890bcSjc156560 /* Add array object into device tree so that we can map the handle */ 3537711890bcSjc156560 (void) raid_obj_add_org(raid_tab, array_obj_id, controller_obj_id); 3538711890bcSjc156560 3539711890bcSjc156560 return (ret); 3540711890bcSjc156560 } 3541711890bcSjc156560 3542711890bcSjc156560 static int 3543711890bcSjc156560 obj_array_delete(raid_obj_tab_t *raid_tab, raid_obj_id_t array_obj_id, 3544711890bcSjc156560 char **plugin_err_str) 3545711890bcSjc156560 { 3546711890bcSjc156560 raid_obj_id_t controller_obj_id; 3547711890bcSjc156560 controller_attr_t *controller_attr; 3548711890bcSjc156560 array_attr_t *array_attr; 3549711890bcSjc156560 raid_lib_t *raid_lib; 355072e1c055Sjc156560 int ret, fd; 3551711890bcSjc156560 uint32_t *disk_ids = NULL; 3552711890bcSjc156560 3553711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, array_obj_id); 3554711890bcSjc156560 if (controller_obj_id <= OBJ_NONE) 3555711890bcSjc156560 return (controller_obj_id); 3556711890bcSjc156560 3557711890bcSjc156560 ret = obj_get_attr(raid_tab, controller_obj_id, 3558711890bcSjc156560 (void **)(&controller_attr)); 3559711890bcSjc156560 if (ret < SUCCESS) { 3560711890bcSjc156560 return (ret); 3561711890bcSjc156560 } 3562711890bcSjc156560 ret = obj_get_attr(raid_tab, array_obj_id, (void **)(&array_attr)); 3563711890bcSjc156560 if (ret < SUCCESS) 3564711890bcSjc156560 return (ret); 3565711890bcSjc156560 3566711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3567711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3568711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3569711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3570711890bcSjc156560 3571711890bcSjc156560 ret = raid_lib->array_delete(controller_attr->controller_id, 3572711890bcSjc156560 array_attr->array_id, plugin_err_str); 3573711890bcSjc156560 if (ret < SUCCESS) { 3574711890bcSjc156560 if (disk_ids) 3575711890bcSjc156560 free(disk_ids); 3576711890bcSjc156560 return (ret); 3577711890bcSjc156560 } 3578711890bcSjc156560 3579711890bcSjc156560 if (disk_ids) 3580711890bcSjc156560 free(disk_ids); 3581711890bcSjc156560 return (ret); 3582711890bcSjc156560 } 3583711890bcSjc156560 3584711890bcSjc156560 static int 3585711890bcSjc156560 obj_hsp_bind(raid_obj_tab_t *raid_tab, int num, raid_obj_id_t *obj_ids, 3586711890bcSjc156560 char **plugin_err_str) 3587711890bcSjc156560 { 3588711890bcSjc156560 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE; 3589711890bcSjc156560 raid_obj_id_t array_obj_id, disk_obj_id; 3590711890bcSjc156560 hsp_relation_t *hsp_relation; 3591711890bcSjc156560 controller_attr_t *controller_attr; 3592711890bcSjc156560 array_attr_t *array_attr; 3593711890bcSjc156560 arraypart_attr_t *arraypart_attr; 3594711890bcSjc156560 disk_attr_t *disk_attr; 3595711890bcSjc156560 diskseg_attr_t *diskseg_attr; 3596711890bcSjc156560 hsp_attr_t *hsp_attr; 3597711890bcSjc156560 raid_lib_t *raid_lib; 3598711890bcSjc156560 int ret, fd, i, j = 0; 3599711890bcSjc156560 3600711890bcSjc156560 hsp_relation = malloc(sizeof (hsp_relation_t) * num); 3601711890bcSjc156560 if (hsp_relation == NULL) 3602711890bcSjc156560 return (ERR_NOMEM); 3603711890bcSjc156560 3604711890bcSjc156560 for (i = 0; i < num; ++i) { 3605711890bcSjc156560 array_obj_id = *(obj_ids + i * 2); 3606711890bcSjc156560 disk_obj_id = *(obj_ids + i * 2 + 1); 3607711890bcSjc156560 3608711890bcSjc156560 if (raid_obj_get_type(raid_tab, disk_obj_id) != OBJ_TYPE_DISK || 3609711890bcSjc156560 (array_obj_id != OBJ_ATTR_NONE && 3610711890bcSjc156560 raid_obj_get_type(raid_tab, array_obj_id) != 3611711890bcSjc156560 OBJ_TYPE_ARRAY)) { 3612711890bcSjc156560 free(hsp_relation); 3613711890bcSjc156560 return (ERR_DEVICE_TYPE); 3614711890bcSjc156560 } 3615711890bcSjc156560 3616711890bcSjc156560 /* Get controller attributes */ 3617711890bcSjc156560 if (controller_obj_id == OBJ_NONE) 3618711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, 3619711890bcSjc156560 disk_obj_id); 3620711890bcSjc156560 else if (controller_obj_id != obj_get_controller(raid_tab, 3621711890bcSjc156560 disk_obj_id)) { 3622711890bcSjc156560 free(hsp_relation); 3623711890bcSjc156560 return (ERR_DRIVER_ACROSS); 3624711890bcSjc156560 } 3625711890bcSjc156560 3626711890bcSjc156560 ret = obj_get_attr(raid_tab, controller_obj_id, 3627711890bcSjc156560 (void **)(&controller_attr)); 3628711890bcSjc156560 3629711890bcSjc156560 /* Get disk attributes */ 3630711890bcSjc156560 ret = obj_get_attr(raid_tab, disk_obj_id, 3631711890bcSjc156560 (void **)(&disk_attr)); 3632711890bcSjc156560 if (disk_attr->state == DISK_STATE_FAILED) { 3633711890bcSjc156560 free(hsp_relation); 3634711890bcSjc156560 return (ERR_DISK_STATE); 3635711890bcSjc156560 } 3636711890bcSjc156560 3637711890bcSjc156560 /* If it's not a hsp disk, check if there's occupied space */ 3638711890bcSjc156560 if (obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP) == 3639711890bcSjc156560 OBJ_NONE) { 3640711890bcSjc156560 obj_id = obj_get_comp(raid_tab, disk_obj_id, 3641711890bcSjc156560 OBJ_TYPE_DISK_SEG); 3642711890bcSjc156560 while (obj_id != OBJ_NONE) { 3643711890bcSjc156560 ret = obj_get_attr(raid_tab, obj_id, 3644711890bcSjc156560 (void **)(&diskseg_attr)); 3645711890bcSjc156560 if (!(diskseg_attr->state & 3646711890bcSjc156560 DISKSEG_STATE_RESERVED)) { 3647711890bcSjc156560 free(hsp_relation); 3648711890bcSjc156560 return (ERR_DISK_NOT_EMPTY); 3649711890bcSjc156560 } 3650711890bcSjc156560 obj_id = obj_get_sibling(raid_tab, obj_id); 3651711890bcSjc156560 } 3652711890bcSjc156560 } 3653711890bcSjc156560 3654711890bcSjc156560 if (array_obj_id != OBJ_ATTR_NONE) { 3655711890bcSjc156560 /* If local hsp is supported */ 3656711890bcSjc156560 if (!(controller_attr->capability & RAID_CAP_L_HSP)) { 3657711890bcSjc156560 free(hsp_relation); 3658711890bcSjc156560 return (ERR_OP_ILLEGAL); 3659711890bcSjc156560 } 3660711890bcSjc156560 3661711890bcSjc156560 if (raid_obj_get_type(raid_tab, array_obj_id) != 3662711890bcSjc156560 OBJ_TYPE_ARRAY) { 3663711890bcSjc156560 free(hsp_relation); 3664711890bcSjc156560 return (ERR_DEVICE_TYPE); 3665711890bcSjc156560 } 3666711890bcSjc156560 3667711890bcSjc156560 /* Get array attributes */ 3668711890bcSjc156560 ret = obj_get_attr(raid_tab, array_obj_id, 3669711890bcSjc156560 (void **)(&array_attr)); 3670711890bcSjc156560 /* RAID 0 array can not use hsp */ 3671711890bcSjc156560 if (array_attr->raid_level == RAID_LEVEL_0) { 3672711890bcSjc156560 free(hsp_relation); 3673711890bcSjc156560 return (ERR_ARRAY_LEVEL); 3674711890bcSjc156560 } 3675711890bcSjc156560 3676711890bcSjc156560 /* If It's belong to another controller */ 3677711890bcSjc156560 if (controller_obj_id != obj_get_controller(raid_tab, 3678711890bcSjc156560 array_obj_id)) { 3679711890bcSjc156560 free(hsp_relation); 3680711890bcSjc156560 return (ERR_DRIVER_ACROSS); 3681711890bcSjc156560 } 3682711890bcSjc156560 3683711890bcSjc156560 /* Get an array part attributes */ 3684711890bcSjc156560 if ((array_attr->raid_level == RAID_LEVEL_10) || 3685711890bcSjc156560 (array_attr->raid_level == RAID_LEVEL_50)) 3686711890bcSjc156560 obj_id = obj_get_comp(raid_tab, array_obj_id, 3687711890bcSjc156560 OBJ_TYPE_ARRAY); 3688711890bcSjc156560 else 3689711890bcSjc156560 obj_id = array_obj_id; 3690711890bcSjc156560 obj_id = obj_get_comp(raid_tab, obj_id, 3691711890bcSjc156560 OBJ_TYPE_ARRAY_PART); 3692711890bcSjc156560 ret = obj_get_attr(raid_tab, obj_id, 3693711890bcSjc156560 (void **)(&arraypart_attr)); 3694711890bcSjc156560 3695711890bcSjc156560 /* Check if disk space is enough for array */ 3696711890bcSjc156560 if (arraypart_attr->size > disk_attr->capacity) { 3697711890bcSjc156560 free(hsp_relation); 3698711890bcSjc156560 return (ERR_DISK_SPACE); 3699711890bcSjc156560 } 3700711890bcSjc156560 if (controller_attr->capability & RAID_CAP_ARRAY_ALIGN) 3701711890bcSjc156560 if ((arraypart_attr->size + 3702711890bcSjc156560 arraypart_attr->offset) > 3703711890bcSjc156560 disk_attr->capacity) { 3704711890bcSjc156560 free(hsp_relation); 3705711890bcSjc156560 return (ERR_DISK_SPACE); 3706711890bcSjc156560 } 3707711890bcSjc156560 } else if (!(controller_attr->capability & RAID_CAP_G_HSP)) { 3708711890bcSjc156560 /* if global hsp is supported */ 3709711890bcSjc156560 free(hsp_relation); 3710711890bcSjc156560 return (ERR_OP_ILLEGAL); 3711711890bcSjc156560 } 3712711890bcSjc156560 3713711890bcSjc156560 /* 3714711890bcSjc156560 * If the array is already associated with the 3715711890bcSjc156560 * local hsp, or it's a global hsp, ignore it 3716711890bcSjc156560 */ 3717711890bcSjc156560 obj_id = obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP); 3718711890bcSjc156560 if (obj_id > OBJ_NONE) { 3719711890bcSjc156560 if (obj_get_attr(raid_tab, obj_id, 3720711890bcSjc156560 (void **)&hsp_attr) >= SUCCESS) { 3721711890bcSjc156560 if (((hsp_attr->type == HSP_TYPE_GLOBAL) && 3722711890bcSjc156560 (array_obj_id != OBJ_ATTR_NONE)) || 3723711890bcSjc156560 ((hsp_attr->type == HSP_TYPE_LOCAL) && 3724711890bcSjc156560 (array_obj_id == OBJ_ATTR_NONE))) { 3725711890bcSjc156560 free(hsp_relation); 3726711890bcSjc156560 return (ERR_OP_ILLEGAL); 3727711890bcSjc156560 } 3728711890bcSjc156560 } 3729711890bcSjc156560 } 3730711890bcSjc156560 3731711890bcSjc156560 if (array_obj_id != OBJ_ATTR_NONE) 3732711890bcSjc156560 hsp_relation[j].array_id = array_attr->array_id; 3733711890bcSjc156560 else 3734711890bcSjc156560 hsp_relation[j].array_id = (uint32_t)OBJ_ATTR_NONE; 3735711890bcSjc156560 hsp_relation[j].disk_id = disk_attr->disk_id; 3736711890bcSjc156560 ++ j; 3737711890bcSjc156560 } 3738711890bcSjc156560 3739711890bcSjc156560 3740711890bcSjc156560 if (j == 0) 3741711890bcSjc156560 return (SUCCESS); 3742711890bcSjc156560 3743711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3744711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3745711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3746711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3747711890bcSjc156560 3748711890bcSjc156560 if (raid_lib->hsp_bind == NULL) { 3749711890bcSjc156560 free(hsp_relation); 3750711890bcSjc156560 return (ERR_OP_NO_IMPL); 3751711890bcSjc156560 } 3752711890bcSjc156560 3753711890bcSjc156560 ret = raid_lib->hsp_bind(controller_attr->controller_id, 3754711890bcSjc156560 j, hsp_relation, plugin_err_str); 3755711890bcSjc156560 3756711890bcSjc156560 free(hsp_relation); 3757711890bcSjc156560 return (ret); 3758711890bcSjc156560 } 3759711890bcSjc156560 3760711890bcSjc156560 static int 3761711890bcSjc156560 obj_hsp_unbind(raid_obj_tab_t *raid_tab, int num, raid_obj_id_t *obj_ids, 3762711890bcSjc156560 char **plugin_err_str) 3763711890bcSjc156560 { 3764711890bcSjc156560 raid_obj_id_t obj_id, controller_obj_id = OBJ_NONE; 3765711890bcSjc156560 raid_obj_id_t array_obj_id, disk_obj_id; 3766711890bcSjc156560 hsp_relation_t *hsp_relation; 3767711890bcSjc156560 controller_attr_t *controller_attr; 3768711890bcSjc156560 array_attr_t *array_attr; 3769711890bcSjc156560 disk_attr_t *disk_attr; 3770711890bcSjc156560 hsp_attr_t *hsp_attr; 3771711890bcSjc156560 raid_lib_t *raid_lib; 3772711890bcSjc156560 int ret, fd, i, j = 0; 3773711890bcSjc156560 3774711890bcSjc156560 hsp_relation = malloc(sizeof (hsp_relation_t) * num); 3775711890bcSjc156560 if (hsp_relation == NULL) 3776711890bcSjc156560 return (ERR_NOMEM); 3777711890bcSjc156560 3778711890bcSjc156560 for (i = 0; i < num; ++i) { 3779711890bcSjc156560 array_obj_id = *(obj_ids + i * 2); 3780711890bcSjc156560 disk_obj_id = *(obj_ids + i * 2 + 1); 3781711890bcSjc156560 3782711890bcSjc156560 if (raid_obj_get_type(raid_tab, disk_obj_id) != OBJ_TYPE_DISK) { 3783711890bcSjc156560 free(hsp_relation); 3784711890bcSjc156560 return (ERR_DEVICE_TYPE); 3785711890bcSjc156560 } 3786711890bcSjc156560 3787711890bcSjc156560 /* Get controller attributes */ 3788711890bcSjc156560 if (controller_obj_id == OBJ_NONE) 3789711890bcSjc156560 controller_obj_id = obj_get_controller(raid_tab, 3790711890bcSjc156560 disk_obj_id); 3791711890bcSjc156560 else if (controller_obj_id != obj_get_controller(raid_tab, 3792711890bcSjc156560 disk_obj_id)) { 3793711890bcSjc156560 free(hsp_relation); 3794711890bcSjc156560 return (ERR_DRIVER_ACROSS); 3795711890bcSjc156560 } 3796711890bcSjc156560 3797711890bcSjc156560 ret = obj_get_attr(raid_tab, controller_obj_id, 3798711890bcSjc156560 (void **)(&controller_attr)); 3799711890bcSjc156560 3800711890bcSjc156560 /* Get disk attributes */ 3801711890bcSjc156560 ret = obj_get_attr(raid_tab, disk_obj_id, 3802711890bcSjc156560 (void **)(&disk_attr)); 3803711890bcSjc156560 if (disk_attr->state == DISK_STATE_FAILED) { 3804711890bcSjc156560 free(hsp_relation); 3805711890bcSjc156560 return (ERR_DISK_STATE); 3806711890bcSjc156560 } 3807711890bcSjc156560 3808711890bcSjc156560 /* If it's not a hsp disk */ 3809711890bcSjc156560 obj_id = obj_get_comp(raid_tab, disk_obj_id, OBJ_TYPE_HSP); 3810711890bcSjc156560 if (obj_id == OBJ_NONE) { 3811711890bcSjc156560 free(hsp_relation); 3812711890bcSjc156560 return (ERR_DISK_STATE); 3813711890bcSjc156560 } 3814711890bcSjc156560 ret = obj_get_attr(raid_tab, obj_id, (void **)(&hsp_attr)); 3815711890bcSjc156560 3816711890bcSjc156560 if (array_obj_id != OBJ_ATTR_NONE) { 3817711890bcSjc156560 if (raid_obj_get_type(raid_tab, array_obj_id) != 3818711890bcSjc156560 OBJ_TYPE_ARRAY) { 3819711890bcSjc156560 free(hsp_relation); 3820711890bcSjc156560 return (ERR_DEVICE_TYPE); 3821711890bcSjc156560 } 3822711890bcSjc156560 3823711890bcSjc156560 /* Get array attributes */ 3824711890bcSjc156560 ret = obj_get_attr(raid_tab, array_obj_id, 3825711890bcSjc156560 (void **)(&array_attr)); 3826711890bcSjc156560 3827711890bcSjc156560 /* If It's belong to another controller */ 3828711890bcSjc156560 if (controller_obj_id != obj_get_controller(raid_tab, 3829711890bcSjc156560 array_obj_id)) { 3830711890bcSjc156560 free(hsp_relation); 3831711890bcSjc156560 return (ERR_DRIVER_ACROSS); 3832711890bcSjc156560 } 3833711890bcSjc156560 3834711890bcSjc156560 /* If want to remove an array from a global hsp */ 3835711890bcSjc156560 if (hsp_attr->type == HSP_TYPE_GLOBAL) { 3836711890bcSjc156560 free(hsp_relation); 3837711890bcSjc156560 return (ERR_OP_ILLEGAL); 3838711890bcSjc156560 } 3839711890bcSjc156560 3840711890bcSjc156560 do { 3841711890bcSjc156560 (void) obj_get_attr(raid_tab, obj_id, 3842711890bcSjc156560 (void **)(&hsp_attr)); 3843711890bcSjc156560 3844711890bcSjc156560 if (hsp_attr->associated_id == 3845711890bcSjc156560 array_attr->array_id || 3846711890bcSjc156560 hsp_attr->type == HSP_TYPE_GLOBAL) 3847711890bcSjc156560 break; 3848711890bcSjc156560 3849711890bcSjc156560 obj_id = obj_get_sibling(raid_tab, obj_id); 3850711890bcSjc156560 } while (obj_id > OBJ_NONE); 3851711890bcSjc156560 } else if (hsp_attr->type != HSP_TYPE_GLOBAL) { 3852711890bcSjc156560 /* if global hsp is supported */ 3853711890bcSjc156560 free(hsp_relation); 3854711890bcSjc156560 return (ERR_OP_ILLEGAL); 3855711890bcSjc156560 } 3856711890bcSjc156560 3857711890bcSjc156560 /* 3858711890bcSjc156560 * If array is associated with a local hsp, or remove a 3859711890bcSjc156560 * global hsp disk 3860711890bcSjc156560 */ 3861711890bcSjc156560 if ((obj_id && (array_obj_id != OBJ_ATTR_NONE)) || 3862711890bcSjc156560 (array_obj_id == OBJ_ATTR_NONE)) { 3863711890bcSjc156560 if (array_obj_id != OBJ_ATTR_NONE) 3864711890bcSjc156560 hsp_relation[j].array_id = array_attr->array_id; 3865711890bcSjc156560 else 3866711890bcSjc156560 hsp_relation[j].array_id = 3867711890bcSjc156560 (uint32_t)OBJ_ATTR_NONE; 3868711890bcSjc156560 hsp_relation[j].disk_id = disk_attr->disk_id; 3869711890bcSjc156560 ++ j; 3870711890bcSjc156560 } else { 3871711890bcSjc156560 free(hsp_relation); 3872711890bcSjc156560 return (ERR_OP_ILLEGAL); 3873711890bcSjc156560 } 3874711890bcSjc156560 } 3875711890bcSjc156560 3876711890bcSjc156560 3877711890bcSjc156560 raid_lib = raid_obj_get_lib(raid_tab, controller_obj_id); 3878711890bcSjc156560 fd = raid_obj_get_fd(raid_tab, controller_obj_id); 3879711890bcSjc156560 if ((raid_lib == NULL) || (fd == 0)) 3880711890bcSjc156560 return (ERR_DRIVER_CLOSED); 3881711890bcSjc156560 3882711890bcSjc156560 if (raid_lib->hsp_unbind == NULL) { 3883711890bcSjc156560 free(hsp_relation); 3884711890bcSjc156560 return (ERR_OP_NO_IMPL); 3885711890bcSjc156560 } 3886711890bcSjc156560 3887711890bcSjc156560 ret = raid_lib->hsp_unbind(controller_attr->controller_id, 3888711890bcSjc156560 j, hsp_relation, plugin_err_str); 3889711890bcSjc156560 3890711890bcSjc156560 free(hsp_relation); 3891711890bcSjc156560 return (ret); 3892711890bcSjc156560 } 3893711890bcSjc156560 3894711890bcSjc156560 /* 3895711890bcSjc156560 * Object maintennance routines 3896711890bcSjc156560 */ 3897711890bcSjc156560 static int 3898711890bcSjc156560 raid_obj_create_system_obj(raid_obj_tab_t *raid_tab) 3899711890bcSjc156560 { 3900711890bcSjc156560 raid_obj_t *raid_obj; 3901711890bcSjc156560 int ret; 3902711890bcSjc156560 3903711890bcSjc156560 raid_obj = calloc(1, sizeof (raid_obj_t)); 3904711890bcSjc156560 if (raid_obj == NULL) 3905711890bcSjc156560 return (ERR_NOMEM); 3906711890bcSjc156560 3907711890bcSjc156560 raid_obj->obj_id = OBJ_SYSTEM; 3908711890bcSjc156560 raid_obj->obj_type_id = OBJ_TYPE_SYSTEM; 3909711890bcSjc156560 raid_obj->data = NULL; 3910711890bcSjc156560 3911711890bcSjc156560 ret = raid_obj_tab_insert(raid_tab, raid_obj->obj_id, raid_obj); 3912711890bcSjc156560 if (ret == ERR_DEVICE_DUP) { 3913711890bcSjc156560 free(raid_obj); 3914711890bcSjc156560 return (ERR_DEVICE_UNCLEAN); 3915711890bcSjc156560 } 3916711890bcSjc156560 3917711890bcSjc156560 return (SUCCESS); 3918711890bcSjc156560 } 3919711890bcSjc156560 3920711890bcSjc156560 static raid_obj_id_t 3921711890bcSjc156560 raid_obj_id_new(raid_obj_tab_t *raid_tab) 3922711890bcSjc156560 { 3923711890bcSjc156560 ++ raid_tab->obj_id_cnt; 3924711890bcSjc156560 if (raid_tab->obj_id_cnt <= 0) 3925711890bcSjc156560 return (ERR_DEVICE_OVERFLOW); 3926711890bcSjc156560 3927711890bcSjc156560 return (raid_tab->obj_id_cnt); 3928711890bcSjc156560 } 3929711890bcSjc156560 3930711890bcSjc156560 static void * 3931711890bcSjc156560 raid_obj_attr_new(raid_obj_type_id_t obj_type) 3932711890bcSjc156560 { 3933711890bcSjc156560 void *obj_attr = NULL; 3934711890bcSjc156560 3935711890bcSjc156560 switch (obj_type) { 3936711890bcSjc156560 case OBJ_TYPE_CONTROLLER: 3937711890bcSjc156560 obj_attr = calloc(1, sizeof (controller_attr_t)); 3938711890bcSjc156560 break; 3939711890bcSjc156560 case OBJ_TYPE_ARRAY: 3940711890bcSjc156560 obj_attr = calloc(1, sizeof (array_attr_t)); 3941711890bcSjc156560 break; 3942711890bcSjc156560 case OBJ_TYPE_DISK: 3943711890bcSjc156560 obj_attr = calloc(1, sizeof (disk_attr_t)); 3944711890bcSjc156560 break; 3945711890bcSjc156560 case OBJ_TYPE_HSP: 3946711890bcSjc156560 obj_attr = calloc(1, sizeof (hsp_attr_t)); 3947711890bcSjc156560 break; 3948711890bcSjc156560 case OBJ_TYPE_ARRAY_PART: 3949711890bcSjc156560 obj_attr = calloc(1, sizeof (arraypart_attr_t)); 3950711890bcSjc156560 break; 3951711890bcSjc156560 case OBJ_TYPE_DISK_SEG: 3952711890bcSjc156560 obj_attr = calloc(1, sizeof (diskseg_attr_t)); 3953711890bcSjc156560 break; 3954711890bcSjc156560 case OBJ_TYPE_TASK: 3955711890bcSjc156560 obj_attr = calloc(1, sizeof (task_attr_t)); 3956711890bcSjc156560 break; 3957*b449fa8aSyw161884 case OBJ_TYPE_PROP: 3958*b449fa8aSyw161884 obj_attr = calloc(1, sizeof (property_attr_t)); 3959*b449fa8aSyw161884 break; 3960711890bcSjc156560 default: 3961711890bcSjc156560 break; 3962711890bcSjc156560 } 3963711890bcSjc156560 3964711890bcSjc156560 return (obj_attr); 3965711890bcSjc156560 } 3966711890bcSjc156560 3967711890bcSjc156560 static raid_obj_id_t 3968711890bcSjc156560 raid_obj_create(raid_obj_tab_t *raid_tab, raid_obj_type_id_t obj_type) 3969711890bcSjc156560 { 3970711890bcSjc156560 raid_obj_t *raid_obj; 3971711890bcSjc156560 int ret; 3972711890bcSjc156560 void *data_ptr; 3973711890bcSjc156560 3974711890bcSjc156560 raid_obj = calloc(1, sizeof (raid_obj_t)); 3975711890bcSjc156560 if (raid_obj == NULL) 3976711890bcSjc156560 return (ERR_NOMEM); 3977711890bcSjc156560 3978711890bcSjc156560 raid_obj->obj_id = raid_obj_id_new(raid_tab); 3979711890bcSjc156560 if (raid_obj->obj_id < OBJ_NONE) 3980711890bcSjc156560 return (ERR_DEVICE_OVERFLOW); 3981711890bcSjc156560 3982711890bcSjc156560 ret = raid_obj_tab_insert(raid_tab, raid_obj->obj_id, raid_obj); 3983711890bcSjc156560 if (ret == ERR_DEVICE_DUP) { 3984711890bcSjc156560 free(raid_obj); 3985711890bcSjc156560 return (ERR_DEVICE_DUP); 3986711890bcSjc156560 } 3987711890bcSjc156560 3988711890bcSjc156560 data_ptr = raid_obj_attr_new(obj_type); 3989711890bcSjc156560 if (data_ptr == NULL) { 3990711890bcSjc156560 (void) raid_obj_delete(raid_tab, raid_obj->obj_id); 3991711890bcSjc156560 return (ERR_NOMEM); 3992711890bcSjc156560 } 3993711890bcSjc156560 3994711890bcSjc156560 (void) raid_obj_set_data_ptr(raid_tab, raid_obj->obj_id, data_ptr); 3995711890bcSjc156560 3996711890bcSjc156560 (void) raid_obj_set_type(raid_tab, raid_obj->obj_id, obj_type); 3997711890bcSjc156560 return (raid_obj->obj_id); 3998711890bcSjc156560 } 3999711890bcSjc156560 4000711890bcSjc156560 static int 4001711890bcSjc156560 raid_obj_delete(raid_obj_tab_t *raid_tab, raid_obj_id_t raid_obj_id) 4002711890bcSjc156560 { 4003711890bcSjc156560 raid_obj_t *obj; 4004711890bcSjc156560 4005711890bcSjc156560 obj = raid_obj_tab_remove(raid_tab, raid_obj_id); 4006711890bcSjc156560 if (obj != NULL) { 4007711890bcSjc156560 free(obj->data); 4008711890bcSjc156560 free(obj); 4009711890bcSjc156560 return (SUCCESS); 4010711890bcSjc156560 } 4011711890bcSjc156560 4012711890bcSjc156560 return (ERR_DEVICE_NOENT); 4013711890bcSjc156560 } 4014711890bcSjc156560 4015711890bcSjc156560 static int 4016711890bcSjc156560 raid_obj_add_org(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4017711890bcSjc156560 raid_obj_id_t container_id) 4018711890bcSjc156560 { 4019711890bcSjc156560 raid_obj_id_t tmp, tmp1; 4020711890bcSjc156560 4021711890bcSjc156560 tmp = raid_obj_get_comp(raid_tab, container_id); 4022711890bcSjc156560 if (tmp < OBJ_NONE) 4023711890bcSjc156560 return (ERR_DEVICE_NOENT); 4024711890bcSjc156560 4025711890bcSjc156560 if (tmp == OBJ_NONE) { 4026711890bcSjc156560 (void) raid_obj_set_container(raid_tab, obj_id, container_id); 4027711890bcSjc156560 (void) raid_obj_set_comp(raid_tab, container_id, obj_id); 4028711890bcSjc156560 return (SUCCESS); 4029711890bcSjc156560 } 4030711890bcSjc156560 4031711890bcSjc156560 while ((tmp1 = raid_obj_get_sibling(raid_tab, tmp)) != OBJ_NONE) 4032711890bcSjc156560 tmp = tmp1; 4033711890bcSjc156560 4034711890bcSjc156560 if (raid_obj_set_sibling(raid_tab, tmp, obj_id) < SUCCESS) 4035711890bcSjc156560 return (ERR_DEVICE_NOENT); 4036711890bcSjc156560 (void) raid_obj_set_container(raid_tab, obj_id, container_id); 4037711890bcSjc156560 4038711890bcSjc156560 return (SUCCESS); 4039711890bcSjc156560 } 4040711890bcSjc156560 4041711890bcSjc156560 static raid_obj_type_id_t 4042711890bcSjc156560 raid_obj_get_type(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4043711890bcSjc156560 { 4044711890bcSjc156560 raid_obj_t *obj; 4045711890bcSjc156560 4046711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4047711890bcSjc156560 if (obj == NULL) 4048711890bcSjc156560 return (ERR_DEVICE_NOENT); 4049711890bcSjc156560 4050711890bcSjc156560 if ((obj->obj_type_id < OBJ_TYPE_SYSTEM) || 4051711890bcSjc156560 (obj->obj_type_id >= OBJ_TYPE_ALL)) 4052711890bcSjc156560 return (ERR_DEVICE_INVALID); 4053711890bcSjc156560 4054711890bcSjc156560 return (obj->obj_type_id); 4055711890bcSjc156560 } 4056711890bcSjc156560 4057711890bcSjc156560 static int 4058711890bcSjc156560 raid_obj_set_type(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4059711890bcSjc156560 raid_obj_type_id_t type) 4060711890bcSjc156560 { 4061711890bcSjc156560 raid_obj_t *obj; 4062711890bcSjc156560 4063711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4064711890bcSjc156560 if (obj == NULL) 4065711890bcSjc156560 return (ERR_DEVICE_NOENT); 4066711890bcSjc156560 4067711890bcSjc156560 if ((type < OBJ_TYPE_SYSTEM) || (type >= OBJ_TYPE_ALL)) 4068711890bcSjc156560 return (ERR_DEVICE_TYPE); 4069711890bcSjc156560 4070711890bcSjc156560 obj->obj_type_id = type; 4071711890bcSjc156560 return (SUCCESS); 4072711890bcSjc156560 } 4073711890bcSjc156560 4074711890bcSjc156560 static raid_obj_status_t 4075711890bcSjc156560 raid_obj_get_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4076711890bcSjc156560 { 4077711890bcSjc156560 raid_obj_t *obj; 4078711890bcSjc156560 4079711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4080711890bcSjc156560 if (obj == NULL) 4081711890bcSjc156560 return (ERR_DEVICE_NOENT); 4082711890bcSjc156560 4083711890bcSjc156560 return (obj->status); 4084711890bcSjc156560 } 4085711890bcSjc156560 4086711890bcSjc156560 static int 4087711890bcSjc156560 raid_obj_set_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4088711890bcSjc156560 raid_obj_status_t status) 4089711890bcSjc156560 { 4090711890bcSjc156560 raid_obj_t *obj; 4091711890bcSjc156560 4092711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4093711890bcSjc156560 if (obj == NULL) 4094711890bcSjc156560 return (ERR_DEVICE_NOENT); 4095711890bcSjc156560 4096711890bcSjc156560 obj->status = obj->status | status; 4097711890bcSjc156560 4098711890bcSjc156560 return (SUCCESS); 4099711890bcSjc156560 } 4100711890bcSjc156560 4101711890bcSjc156560 static int 4102711890bcSjc156560 raid_obj_clear_status(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4103711890bcSjc156560 raid_obj_status_t status) 4104711890bcSjc156560 { 4105711890bcSjc156560 raid_obj_t *obj; 4106711890bcSjc156560 4107711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4108711890bcSjc156560 if (obj == NULL) 4109711890bcSjc156560 return (ERR_DEVICE_NOENT); 4110711890bcSjc156560 4111711890bcSjc156560 obj->status = obj->status & ~status; 4112711890bcSjc156560 4113711890bcSjc156560 return (SUCCESS); 4114711890bcSjc156560 } 4115711890bcSjc156560 4116711890bcSjc156560 static raid_obj_id_t 4117711890bcSjc156560 raid_obj_get_container(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4118711890bcSjc156560 { 4119711890bcSjc156560 raid_obj_t *obj; 4120711890bcSjc156560 4121711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4122711890bcSjc156560 if (obj == NULL) 4123711890bcSjc156560 return (ERR_DEVICE_NOENT); 4124711890bcSjc156560 4125711890bcSjc156560 return (obj->container); 4126711890bcSjc156560 } 4127711890bcSjc156560 4128711890bcSjc156560 static int 4129711890bcSjc156560 raid_obj_set_container(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4130711890bcSjc156560 raid_obj_id_t container_id) 4131711890bcSjc156560 { 4132711890bcSjc156560 raid_obj_t *obj; 4133711890bcSjc156560 4134711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4135711890bcSjc156560 if (obj == NULL) 4136711890bcSjc156560 return (ERR_DEVICE_NOENT); 4137711890bcSjc156560 4138711890bcSjc156560 obj->container = container_id; 4139711890bcSjc156560 return (SUCCESS); 4140711890bcSjc156560 } 4141711890bcSjc156560 4142711890bcSjc156560 static raid_obj_id_t 4143711890bcSjc156560 raid_obj_get_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4144711890bcSjc156560 { 4145711890bcSjc156560 raid_obj_t *obj; 4146711890bcSjc156560 4147711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4148711890bcSjc156560 if (obj == NULL) 4149711890bcSjc156560 return (ERR_DEVICE_NOENT); 4150711890bcSjc156560 4151711890bcSjc156560 return (obj->component); 4152711890bcSjc156560 } 4153711890bcSjc156560 4154711890bcSjc156560 static int 4155711890bcSjc156560 raid_obj_set_comp(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4156711890bcSjc156560 raid_obj_id_t comp) 4157711890bcSjc156560 { 4158711890bcSjc156560 raid_obj_t *obj; 4159711890bcSjc156560 4160711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4161711890bcSjc156560 if (obj == NULL) 4162711890bcSjc156560 return (ERR_DEVICE_NOENT); 4163711890bcSjc156560 4164711890bcSjc156560 obj->component = comp; 4165711890bcSjc156560 return (SUCCESS); 4166711890bcSjc156560 } 4167711890bcSjc156560 4168711890bcSjc156560 static raid_obj_id_t 4169711890bcSjc156560 raid_obj_get_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4170711890bcSjc156560 { 4171711890bcSjc156560 raid_obj_t *obj; 4172711890bcSjc156560 4173711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4174711890bcSjc156560 if (obj == NULL) 4175711890bcSjc156560 return (ERR_DEVICE_NOENT); 4176711890bcSjc156560 4177711890bcSjc156560 return (obj->sibling); 4178711890bcSjc156560 } 4179711890bcSjc156560 4180711890bcSjc156560 static int 4181711890bcSjc156560 raid_obj_set_sibling(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4182711890bcSjc156560 raid_obj_id_t sibling) 4183711890bcSjc156560 { 4184711890bcSjc156560 raid_obj_t *obj; 4185711890bcSjc156560 4186711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4187711890bcSjc156560 if (obj == NULL) 4188711890bcSjc156560 return (ERR_DEVICE_NOENT); 4189711890bcSjc156560 4190711890bcSjc156560 obj->sibling = sibling; 4191711890bcSjc156560 4192711890bcSjc156560 return (SUCCESS); 4193711890bcSjc156560 } 4194711890bcSjc156560 4195711890bcSjc156560 static void * 4196711890bcSjc156560 raid_obj_get_data_ptr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4197711890bcSjc156560 { 4198711890bcSjc156560 raid_obj_t *obj; 4199711890bcSjc156560 4200711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4201711890bcSjc156560 if (obj == NULL) 4202711890bcSjc156560 return (NULL); 4203711890bcSjc156560 4204711890bcSjc156560 return (obj->data); 4205711890bcSjc156560 } 4206711890bcSjc156560 4207711890bcSjc156560 static int 4208711890bcSjc156560 raid_obj_set_data_ptr(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4209711890bcSjc156560 void *data) 4210711890bcSjc156560 { 4211711890bcSjc156560 raid_obj_t *obj; 4212711890bcSjc156560 4213711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4214711890bcSjc156560 if (obj == NULL) 4215711890bcSjc156560 return (ERR_DEVICE_NOENT); 4216711890bcSjc156560 4217711890bcSjc156560 obj->data = data; 4218711890bcSjc156560 4219711890bcSjc156560 return (SUCCESS); 4220711890bcSjc156560 } 4221711890bcSjc156560 4222711890bcSjc156560 static raid_obj_handle_t 4223711890bcSjc156560 raid_obj_get_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id) 4224711890bcSjc156560 { 4225711890bcSjc156560 raid_obj_t *obj; 4226711890bcSjc156560 4227711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4228711890bcSjc156560 if (obj == NULL) 4229711890bcSjc156560 return (ERR_DEVICE_NOENT); 4230711890bcSjc156560 4231711890bcSjc156560 return (obj->handle); 4232711890bcSjc156560 } 4233711890bcSjc156560 4234711890bcSjc156560 static int 4235711890bcSjc156560 raid_obj_set_handle(raid_obj_tab_t *raid_tab, raid_obj_id_t obj_id, 4236711890bcSjc156560 raid_obj_handle_t handle) 4237711890bcSjc156560 { 4238711890bcSjc156560 raid_obj_t *obj; 4239711890bcSjc156560 4240711890bcSjc156560 obj = raid_obj_tab_find(raid_tab, obj_id); 4241711890bcSjc156560 if (obj == NULL) 4242711890bcSjc156560 return (ERR_DEVICE_NOENT); 4243711890bcSjc156560 4244711890bcSjc156560 obj->handle = handle; 4245711890bcSjc156560 return (SUCCESS); 4246711890bcSjc156560 } 4247711890bcSjc156560 /* 4248711890bcSjc156560 * Object list maintennance routines 4249711890bcSjc156560 */ 4250711890bcSjc156560 static void 4251711890bcSjc156560 raid_list_create(raid_list_t *list, size_t offset) 4252711890bcSjc156560 { 4253711890bcSjc156560 list->head = NULL; 4254711890bcSjc156560 list->tail = NULL; 4255711890bcSjc156560 list->offset = offset; 4256711890bcSjc156560 } 4257711890bcSjc156560 4258711890bcSjc156560 static void * 4259711890bcSjc156560 raid_list_head(raid_list_t *list) 4260711890bcSjc156560 { 4261711890bcSjc156560 return (list->head); 4262711890bcSjc156560 } 4263711890bcSjc156560 4264711890bcSjc156560 static void * 4265711890bcSjc156560 raid_list_next(raid_list_t *list, void *obj) 4266711890bcSjc156560 { 4267711890bcSjc156560 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj); 4268711890bcSjc156560 4269711890bcSjc156560 return (el->next); 4270711890bcSjc156560 } 4271711890bcSjc156560 4272711890bcSjc156560 static void 4273711890bcSjc156560 raid_list_insert_tail(raid_list_t *list, void *obj) 4274711890bcSjc156560 { 4275711890bcSjc156560 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj), *el1; 4276711890bcSjc156560 4277711890bcSjc156560 el->prev = list->tail; 4278711890bcSjc156560 list->tail = obj; 4279711890bcSjc156560 4280711890bcSjc156560 el->next = NULL; 4281711890bcSjc156560 4282711890bcSjc156560 if (list->head == NULL) 4283711890bcSjc156560 list->head = obj; 4284711890bcSjc156560 4285711890bcSjc156560 if (el->prev != NULL) { 4286711890bcSjc156560 el1 = LIST_OBJ_TO_EL(list, el->prev); 4287711890bcSjc156560 el1->next = obj; 4288711890bcSjc156560 } 4289711890bcSjc156560 } 4290711890bcSjc156560 4291711890bcSjc156560 static void 4292711890bcSjc156560 raid_list_remove(raid_list_t *list, void *obj) 4293711890bcSjc156560 { 4294711890bcSjc156560 raid_list_el_t *el = LIST_OBJ_TO_EL(list, obj), *el1; 4295711890bcSjc156560 4296711890bcSjc156560 if (list->head == obj) 4297711890bcSjc156560 list->head = el->next; 4298711890bcSjc156560 4299711890bcSjc156560 if (list->tail == obj) 4300711890bcSjc156560 list->tail = el->prev; 4301711890bcSjc156560 4302711890bcSjc156560 if (el->next != NULL) { 4303711890bcSjc156560 el1 = LIST_OBJ_TO_EL(list, el->next); 4304711890bcSjc156560 el1->prev = el->prev; 4305711890bcSjc156560 } 4306711890bcSjc156560 4307711890bcSjc156560 if (el->prev != NULL) { 4308711890bcSjc156560 el1 = LIST_OBJ_TO_EL(list, el->prev); 4309711890bcSjc156560 el1->next = el->next; 4310711890bcSjc156560 } 4311711890bcSjc156560 4312711890bcSjc156560 el->prev = el->next = NULL; 4313711890bcSjc156560 } 4314711890bcSjc156560 4315711890bcSjc156560 static void * 4316711890bcSjc156560 raid_list_remove_head(raid_list_t *list) 4317711890bcSjc156560 { 4318711890bcSjc156560 void *obj = list->head; 4319711890bcSjc156560 4320711890bcSjc156560 if (obj != NULL) 4321711890bcSjc156560 raid_list_remove(list, obj); 4322711890bcSjc156560 4323711890bcSjc156560 return (obj); 4324711890bcSjc156560 } 4325711890bcSjc156560 4326711890bcSjc156560 static void * 4327711890bcSjc156560 raid_list_find(raid_list_t *list, raid_obj_id_t obj_id) 4328711890bcSjc156560 { 4329711890bcSjc156560 raid_obj_t *obj; 4330711890bcSjc156560 4331711890bcSjc156560 for (obj = raid_list_head(list); obj != NULL; 4332711890bcSjc156560 obj = raid_list_next(list, obj)) 4333711890bcSjc156560 if (obj->obj_id == obj_id) 4334711890bcSjc156560 break; 4335711890bcSjc156560 4336711890bcSjc156560 return (obj); 4337711890bcSjc156560 } 4338711890bcSjc156560 4339711890bcSjc156560 static int 4340711890bcSjc156560 raid_obj_tab_create(raid_obj_tab_t *tab, size_t hash_slots) 4341711890bcSjc156560 { 4342711890bcSjc156560 unsigned i; 4343711890bcSjc156560 4344711890bcSjc156560 if (hash_slots == 0) 4345711890bcSjc156560 return (ERR_OP_ILLEGAL); 4346711890bcSjc156560 4347711890bcSjc156560 tab->slots = hash_slots; 4348711890bcSjc156560 4349711890bcSjc156560 if ((tab->table = calloc(hash_slots, sizeof (raid_list_t))) == NULL) 4350711890bcSjc156560 return (ERR_NOMEM); 4351711890bcSjc156560 4352711890bcSjc156560 for (i = 0; i < hash_slots; i++) 4353711890bcSjc156560 raid_list_create(&tab->table[i], offsetof(raid_obj_t, el)); 4354711890bcSjc156560 4355711890bcSjc156560 return (SUCCESS); 4356711890bcSjc156560 } 4357711890bcSjc156560 4358711890bcSjc156560 static void 4359711890bcSjc156560 raid_obj_tab_destroy(raid_obj_tab_t *tab) 4360711890bcSjc156560 { 4361711890bcSjc156560 unsigned i; 4362711890bcSjc156560 4363711890bcSjc156560 for (i = 0; i < tab->slots; i++) { 4364711890bcSjc156560 struct raid_obj_t *obj; 4365711890bcSjc156560 4366711890bcSjc156560 while ((obj = raid_list_remove_head(&tab->table[i])) != NULL) 4367711890bcSjc156560 free(obj); 4368711890bcSjc156560 4369711890bcSjc156560 raid_list_destroy(&tab->table[i]); 4370711890bcSjc156560 } 4371711890bcSjc156560 4372711890bcSjc156560 if (tab->table) 4373711890bcSjc156560 free(tab->table); 4374711890bcSjc156560 4375711890bcSjc156560 tab->table = NULL; 4376711890bcSjc156560 tab->slots = 0; 4377711890bcSjc156560 tab->obj_id_cnt = 0; 4378711890bcSjc156560 } 4379711890bcSjc156560 4380711890bcSjc156560 static int 4381711890bcSjc156560 raid_obj_tab_insert(raid_obj_tab_t *tab, raid_obj_id_t id, void *obj) 4382711890bcSjc156560 { 4383711890bcSjc156560 raid_list_t *list; 4384711890bcSjc156560 4385711890bcSjc156560 list = OBJ_TAB_SLOT(tab, id); 4386711890bcSjc156560 4387711890bcSjc156560 if (raid_list_find(list, id) != NULL) 4388711890bcSjc156560 return (ERR_DEVICE_DUP); 4389711890bcSjc156560 4390711890bcSjc156560 raid_list_insert_tail(list, obj); 4391711890bcSjc156560 4392711890bcSjc156560 return (SUCCESS); 4393711890bcSjc156560 } 4394711890bcSjc156560 4395711890bcSjc156560 static void * 4396711890bcSjc156560 raid_obj_tab_remove(raid_obj_tab_t *tab, raid_obj_id_t id) 4397711890bcSjc156560 { 4398711890bcSjc156560 raid_list_t *list; 4399711890bcSjc156560 raid_obj_t *obj; 4400711890bcSjc156560 4401711890bcSjc156560 list = OBJ_TAB_SLOT(tab, id); 4402711890bcSjc156560 4403711890bcSjc156560 if ((obj = raid_list_find(list, id)) != NULL) 4404711890bcSjc156560 raid_list_remove(list, obj); 4405711890bcSjc156560 4406711890bcSjc156560 return (obj); 4407711890bcSjc156560 } 4408711890bcSjc156560 4409711890bcSjc156560 static void * 4410711890bcSjc156560 raid_obj_tab_find(raid_obj_tab_t *tab, raid_obj_id_t id) 4411711890bcSjc156560 { 4412711890bcSjc156560 raid_list_t *list; 4413711890bcSjc156560 raid_obj_t *obj; 4414711890bcSjc156560 4415711890bcSjc156560 list = OBJ_TAB_SLOT(tab, id); 4416711890bcSjc156560 obj = raid_list_find(list, id); 4417711890bcSjc156560 4418711890bcSjc156560 return (obj); 4419711890bcSjc156560 } 4420711890bcSjc156560 4421711890bcSjc156560 static void 4422711890bcSjc156560 raid_list_destroy(raid_list_t *list) 4423711890bcSjc156560 { 4424711890bcSjc156560 list->head = NULL; 4425711890bcSjc156560 list->tail = NULL; 4426711890bcSjc156560 list->offset = 0; 4427711890bcSjc156560 } 4428711890bcSjc156560 4429711890bcSjc156560 /* 4430711890bcSjc156560 * Plug-in maintennance routines 4431711890bcSjc156560 */ 4432711890bcSjc156560 static int 4433711890bcSjc156560 controller_id_to_path(uint32_t controller_id, char *path) 4434711890bcSjc156560 { 4435711890bcSjc156560 char buf[MAX_PATH_LEN] = {0}, buf1[MAX_PATH_LEN] = {0}, *colon; 4436711890bcSjc156560 4437711890bcSjc156560 (void) snprintf(buf, MAX_PATH_LEN, "%s/c%d", CFGDIR, controller_id); 4438711890bcSjc156560 if (readlink(buf, buf1, sizeof (buf1)) < 0) 4439711890bcSjc156560 return (ERR_DRIVER_NOT_FOUND); 4440711890bcSjc156560 4441711890bcSjc156560 if (buf1[0] != '/') 4442711890bcSjc156560 (void) snprintf(buf, sizeof (buf), "%s/", CFGDIR); 4443711890bcSjc156560 else 4444711890bcSjc156560 buf[0] = 0; 4445711890bcSjc156560 (void) strlcat(buf, buf1, MAX_PATH_LEN); 4446711890bcSjc156560 4447711890bcSjc156560 colon = strrchr(buf, ':'); 4448711890bcSjc156560 if (colon == NULL) 4449711890bcSjc156560 return (ERR_DRIVER_NOT_FOUND); 4450711890bcSjc156560 else 4451711890bcSjc156560 *colon = 0; 4452711890bcSjc156560 4453711890bcSjc156560 (void) snprintf(path, MAX_PATH_LEN, "%s:devctl", buf); 4454711890bcSjc156560 4455711890bcSjc156560 if (access(path, F_OK) < 0) 4456711890bcSjc156560 return (ERR_DRIVER_NOT_FOUND); 4457711890bcSjc156560 4458711890bcSjc156560 return (SUCCESS); 4459711890bcSjc156560 } 4460711890bcSjc156560 4461711890bcSjc156560 static char * 4462711890bcSjc156560 controller_id_to_driver_name(uint32_t controller_id) 4463711890bcSjc156560 { 4464711890bcSjc156560 char buf[MAX_PATH_LEN]; 4465711890bcSjc156560 di_node_t di_node; 4466711890bcSjc156560 char *name, *tmp; 4467711890bcSjc156560 int ret; 4468711890bcSjc156560 4469711890bcSjc156560 ret = controller_id_to_path(controller_id, buf); 4470711890bcSjc156560 if (ret < SUCCESS) 4471711890bcSjc156560 return (NULL); 4472711890bcSjc156560 4473711890bcSjc156560 tmp = strrchr(buf, ':'); 4474711890bcSjc156560 if (tmp != NULL) 4475711890bcSjc156560 *tmp = 0; 4476711890bcSjc156560 4477711890bcSjc156560 tmp = strstr(buf, "pci"); 4478711890bcSjc156560 if (tmp == NULL) 4479711890bcSjc156560 return (NULL); 4480711890bcSjc156560 4481711890bcSjc156560 di_node = di_init(tmp, DINFOPROP); 4482711890bcSjc156560 if (di_node == DI_NODE_NIL) 4483711890bcSjc156560 return (NULL); 4484711890bcSjc156560 4485711890bcSjc156560 name = di_driver_name(di_node); 4486711890bcSjc156560 4487711890bcSjc156560 return (name); 4488711890bcSjc156560 } 4489711890bcSjc156560 4490711890bcSjc156560 static void 4491711890bcSjc156560 raid_plugin_init() 4492711890bcSjc156560 { 4493711890bcSjc156560 raid_lib_t *raid_lib = raid_lib_sys; 4494711890bcSjc156560 4495711890bcSjc156560 while (raid_lib) { 4496711890bcSjc156560 raid_lib_sys = raid_lib->next; 4497711890bcSjc156560 (void) dlclose(raid_lib->lib_handle); 4498711890bcSjc156560 free(raid_lib); 4499711890bcSjc156560 raid_lib = raid_lib_sys; 4500711890bcSjc156560 } 4501711890bcSjc156560 } 4502711890bcSjc156560 4503711890bcSjc156560 static raid_lib_t * 4504711890bcSjc156560 raid_plugin_load(char *driver_name) 4505711890bcSjc156560 { 4506711890bcSjc156560 char buf[MAX_PATH_LEN] = {0}; 4507711890bcSjc156560 raid_lib_t *supplib; 4508711890bcSjc156560 void *sym; 4509711890bcSjc156560 4510711890bcSjc156560 supplib = calloc(1, sizeof (raid_lib_t)); 4511711890bcSjc156560 if (supplib == NULL) 4512711890bcSjc156560 return (NULL); 4513711890bcSjc156560 4514711890bcSjc156560 (void) snprintf(buf, MAX_PATH_LEN, "%s/%s.so.1", 4515711890bcSjc156560 SUPP_PLUGIN_DIR, driver_name); 4516711890bcSjc156560 4517711890bcSjc156560 supplib->lib_handle = dlopen(buf, RTLD_LAZY); 4518711890bcSjc156560 if (supplib->lib_handle == NULL) { 4519711890bcSjc156560 free(supplib); 4520711890bcSjc156560 return (NULL); 4521711890bcSjc156560 } 4522711890bcSjc156560 4523711890bcSjc156560 supplib->name = driver_name; 4524711890bcSjc156560 4525711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_version")) == NULL) 4526711890bcSjc156560 supplib->version = RDCFG_PLUGIN_V1; 4527711890bcSjc156560 else { 4528711890bcSjc156560 supplib->version = *((uint32_t *)sym); 4529711890bcSjc156560 if (supplib->version != RDCFG_PLUGIN_V1) { 4530711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4531711890bcSjc156560 free(supplib); 4532711890bcSjc156560 return (NULL); 4533711890bcSjc156560 } 4534711890bcSjc156560 } 4535711890bcSjc156560 4536711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_open_controller")) == 4537711890bcSjc156560 NULL) { 4538711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4539711890bcSjc156560 free(supplib); 4540711890bcSjc156560 return (NULL); 4541711890bcSjc156560 } else 4542711890bcSjc156560 supplib->open_controller = (int(*)(uint32_t, char **))sym; 4543711890bcSjc156560 4544711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_close_controller")) == 4545711890bcSjc156560 NULL) { 4546711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4547711890bcSjc156560 free(supplib); 4548711890bcSjc156560 return (NULL); 4549711890bcSjc156560 } else 4550711890bcSjc156560 supplib->close_controller = (int (*)(uint32_t, char **))sym; 4551711890bcSjc156560 4552711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_compnum")) == NULL) { 4553711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4554711890bcSjc156560 free(supplib); 4555711890bcSjc156560 return (NULL); 4556711890bcSjc156560 } else 4557711890bcSjc156560 supplib->compnum = (int (*)(uint32_t, uint32_t, 4558711890bcSjc156560 raid_obj_type_id_t, raid_obj_type_id_t))sym; 4559711890bcSjc156560 4560711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_complist")) == NULL) { 4561711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4562711890bcSjc156560 free(supplib); 4563711890bcSjc156560 return (NULL); 4564711890bcSjc156560 } else 4565711890bcSjc156560 supplib->complist = (int (*)(uint32_t, uint32_t, 4566711890bcSjc156560 raid_obj_type_id_t, raid_obj_type_id_t, int, void *))sym; 4567711890bcSjc156560 4568711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_get_attr")) == NULL) { 4569711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4570711890bcSjc156560 free(supplib); 4571711890bcSjc156560 return (NULL); 4572711890bcSjc156560 } else 4573711890bcSjc156560 supplib->get_attr = (int (*)(uint32_t, uint32_t, uint32_t, 4574711890bcSjc156560 raid_obj_type_id_t, void*))sym; 4575711890bcSjc156560 4576711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_array_create")) == NULL) { 4577711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4578711890bcSjc156560 free(supplib); 4579711890bcSjc156560 return (NULL); 4580711890bcSjc156560 } else 4581711890bcSjc156560 supplib->array_create = (int (*)(uint32_t, array_attr_t *, int, 4582711890bcSjc156560 arraypart_attr_t *, char **))sym; 4583711890bcSjc156560 4584711890bcSjc156560 if ((sym = dlsym(supplib->lib_handle, "rdcfg_array_delete")) == NULL) { 4585711890bcSjc156560 (void) dlclose(supplib->lib_handle); 4586711890bcSjc156560 free(supplib); 4587711890bcSjc156560 return (NULL); 4588711890bcSjc156560 } else 4589711890bcSjc156560 supplib->array_delete = 4590711890bcSjc156560 (int (*)(uint32_t, uint32_t, char **))sym; 4591711890bcSjc156560 4592711890bcSjc156560 supplib->hsp_bind = (int (*)(uint32_t, uint32_t, hsp_relation_t *, 4593711890bcSjc156560 char **))dlsym(supplib->lib_handle, "rdcfg_hsp_bind"); 4594711890bcSjc156560 supplib->hsp_unbind = (int (*)(uint32_t, uint32_t, hsp_relation_t *, 4595711890bcSjc156560 char **))dlsym(supplib->lib_handle, "rdcfg_hsp_unbind"); 4596711890bcSjc156560 supplib->set_attr = (int (*)(uint32_t, uint32_t, uint32_t, uint32_t *, 4597711890bcSjc156560 char **))dlsym(supplib->lib_handle, "rdcfg_set_attr"); 4598711890bcSjc156560 supplib->flash_fw = (int (*)(uint32_t, char *, uint32_t, char **)) 4599711890bcSjc156560 dlsym(supplib->lib_handle, "rdcfg_flash_fw"); 4600711890bcSjc156560 4601711890bcSjc156560 supplib->next = raid_lib_sys; 4602711890bcSjc156560 raid_lib_sys = supplib; 4603711890bcSjc156560 return (supplib); 4604711890bcSjc156560 } 4605711890bcSjc156560 4606711890bcSjc156560 static raid_lib_t * 4607711890bcSjc156560 raid_find_lib(raid_obj_tab_t *raid_tab, raid_obj_id_t controller_obj_id) 4608711890bcSjc156560 { 4609711890bcSjc156560 controller_attr_t *controller_attr; 4610711890bcSjc156560 raid_lib_t *raid_lib; 4611711890bcSjc156560 char *driver_name; 4612711890bcSjc156560 raid_obj_handle_t handle; 4613711890bcSjc156560 4614711890bcSjc156560 /* Check if it's mapped to handle structure */ 4615711890bcSjc156560 handle = raid_obj_to_handle(raid_tab, controller_obj_id); 4616711890bcSjc156560 if (raid_handle_sys.handles[handle].raid_lib != NULL) 4617711890bcSjc156560 return (raid_handle_sys.handles[handle].raid_lib); 4618711890bcSjc156560 4619711890bcSjc156560 (void) obj_get_attr(raid_tab, controller_obj_id, 4620711890bcSjc156560 (void **)(&controller_attr)); 4621711890bcSjc156560 4622711890bcSjc156560 /* Check if the plugin module is already loaded */ 4623711890bcSjc156560 driver_name = controller_id_to_driver_name( 4624711890bcSjc156560 controller_attr->controller_id); 4625711890bcSjc156560 if (driver_name == NULL) 4626711890bcSjc156560 return (NULL); 4627711890bcSjc156560 4628711890bcSjc156560 raid_lib = raid_lib_sys; 4629711890bcSjc156560 while (raid_lib != NULL) { 4630711890bcSjc156560 if (raid_lib->name != NULL && 4631711890bcSjc156560 strcmp(driver_name, raid_lib->name) == 0) 4632711890bcSjc156560 return (raid_lib); 4633711890bcSjc156560 4634711890bcSjc156560 raid_lib = raid_lib->next; 4635711890bcSjc156560 } 4636711890bcSjc156560 4637711890bcSjc156560 /* Loading the plugin module */ 4638711890bcSjc156560 raid_lib = raid_plugin_load(driver_name); 4639711890bcSjc156560 4640711890bcSjc156560 return (raid_lib); 4641711890bcSjc156560 } 4642