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