17836SJohn.Forte@Sun.COM /* 27836SJohn.Forte@Sun.COM * CDDL HEADER START 37836SJohn.Forte@Sun.COM * 47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 77836SJohn.Forte@Sun.COM * 87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 117836SJohn.Forte@Sun.COM * and limitations under the License. 127836SJohn.Forte@Sun.COM * 137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 187836SJohn.Forte@Sun.COM * 197836SJohn.Forte@Sun.COM * CDDL HEADER END 207836SJohn.Forte@Sun.COM */ 217836SJohn.Forte@Sun.COM /* 22*9585STim.Szeto@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237836SJohn.Forte@Sun.COM * Use is subject to license terms. 247836SJohn.Forte@Sun.COM */ 257836SJohn.Forte@Sun.COM 267836SJohn.Forte@Sun.COM #include <stdlib.h> 277836SJohn.Forte@Sun.COM #include <stdio.h> 287836SJohn.Forte@Sun.COM #include <wchar.h> 297836SJohn.Forte@Sun.COM #include <strings.h> 307836SJohn.Forte@Sun.COM #include <sys/types.h> 317836SJohn.Forte@Sun.COM #include <sys/stat.h> 327836SJohn.Forte@Sun.COM #include <fcntl.h> 337836SJohn.Forte@Sun.COM #include <unistd.h> 347836SJohn.Forte@Sun.COM #include <libintl.h> 357836SJohn.Forte@Sun.COM #include <errno.h> 367836SJohn.Forte@Sun.COM #include <string.h> 377836SJohn.Forte@Sun.COM #include <assert.h> 387836SJohn.Forte@Sun.COM #include <libnvpair.h> 397836SJohn.Forte@Sun.COM #include <pthread.h> 407836SJohn.Forte@Sun.COM #include <syslog.h> 417836SJohn.Forte@Sun.COM #include <libstmf.h> 427836SJohn.Forte@Sun.COM #include <netinet/in.h> 437836SJohn.Forte@Sun.COM #include <inttypes.h> 447836SJohn.Forte@Sun.COM #include <store.h> 457836SJohn.Forte@Sun.COM #include <locale.h> 46*9585STim.Szeto@Sun.COM #include <math.h> 47*9585STim.Szeto@Sun.COM #include <libstmf_impl.h> 487836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h> 49*9585STim.Szeto@Sun.COM #include <sys/stmf_sbd_ioctl.h> 507836SJohn.Forte@Sun.COM 517836SJohn.Forte@Sun.COM #define STMF_PATH "/devices/pseudo/stmf@0:admin" 52*9585STim.Szeto@Sun.COM #define SBD_PATH "/devices/pseudo/stmf_sbd@0:admin" 537836SJohn.Forte@Sun.COM 547836SJohn.Forte@Sun.COM #define EUI "eui." 557836SJohn.Forte@Sun.COM #define WWN "wwn." 567836SJohn.Forte@Sun.COM #define IQN "iqn." 57*9585STim.Szeto@Sun.COM #define LU_ASCII_GUID_SIZE 32 58*9585STim.Szeto@Sun.COM #define LU_GUID_SIZE 16 59*9585STim.Szeto@Sun.COM #define OUI_ASCII_SIZE 6 60*9585STim.Szeto@Sun.COM #define OUI_SIZE 3 617836SJohn.Forte@Sun.COM #define IDENT_LENGTH_BYTE 3 627836SJohn.Forte@Sun.COM 63*9585STim.Szeto@Sun.COM /* various initial allocation values */ 64*9585STim.Szeto@Sun.COM #define ALLOC_LU 8192 65*9585STim.Szeto@Sun.COM #define ALLOC_TARGET_PORT 2048 66*9585STim.Szeto@Sun.COM #define ALLOC_PROVIDER 64 67*9585STim.Szeto@Sun.COM #define ALLOC_GROUP 2048 68*9585STim.Szeto@Sun.COM #define ALLOC_SESSION 2048 69*9585STim.Szeto@Sun.COM #define ALLOC_VE 256 70*9585STim.Szeto@Sun.COM #define ALLOC_PP_DATA_SIZE 128*1024 71*9585STim.Szeto@Sun.COM #define ALLOC_GRP_MEMBER 256 72*9585STim.Szeto@Sun.COM 737836SJohn.Forte@Sun.COM #define MAX_ISCSI_NAME 223 74*9585STim.Szeto@Sun.COM #define MAX_SERIAL_SIZE 252 + 1 75*9585STim.Szeto@Sun.COM #define MAX_LU_ALIAS_SIZE 256 76*9585STim.Szeto@Sun.COM #define MAX_SBD_PROPS MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE 777836SJohn.Forte@Sun.COM 787836SJohn.Forte@Sun.COM #define OPEN_STMF 0 797836SJohn.Forte@Sun.COM #define OPEN_EXCL_STMF O_EXCL 807836SJohn.Forte@Sun.COM 81*9585STim.Szeto@Sun.COM #define OPEN_SBD 0 82*9585STim.Szeto@Sun.COM #define OPEN_EXCL_SBD O_EXCL 83*9585STim.Szeto@Sun.COM 847836SJohn.Forte@Sun.COM #define LOGICAL_UNIT_TYPE 0 857836SJohn.Forte@Sun.COM #define TARGET_TYPE 1 867836SJohn.Forte@Sun.COM #define STMF_SERVICE_TYPE 2 877836SJohn.Forte@Sun.COM 88*9585STim.Szeto@Sun.COM #define HOST_GROUP 1 89*9585STim.Szeto@Sun.COM #define TARGET_GROUP 2 90*9585STim.Szeto@Sun.COM 91*9585STim.Szeto@Sun.COM /* set default persistence here */ 92*9585STim.Szeto@Sun.COM #define STMF_DEFAULT_PERSIST STMF_PERSIST_SMF 93*9585STim.Szeto@Sun.COM 94*9585STim.Szeto@Sun.COM #define MAX_PROVIDER_RETRY 30 95*9585STim.Szeto@Sun.COM 967836SJohn.Forte@Sun.COM static int openStmf(int, int *fd); 97*9585STim.Szeto@Sun.COM static int openSbd(int, int *fd); 987836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *); 997836SJohn.Forte@Sun.COM static int loadStore(int fd); 1007836SJohn.Forte@Sun.COM static int initializeConfig(); 1017836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *); 1027836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *); 1037836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *); 1047836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *); 1057836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *); 1067836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *); 1077836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int); 108*9585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *); 109*9585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *); 110*9585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *); 111*9585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid); 112*9585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *); 113*9585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl); 114*9585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *); 115*9585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *); 116*9585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *); 117*9585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t); 118*9585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *); 119*9585STim.Szeto@Sun.COM static int checkHexUpper(char *); 120*9585STim.Szeto@Sun.COM static int strToShift(const char *); 121*9585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *); 122*9585STim.Szeto@Sun.COM static void diskError(uint32_t, int *); 123*9585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *); 124*9585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *); 125*9585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *); 126*9585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t); 127*9585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod(); 128*9585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int); 129*9585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int); 130*9585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int); 131*9585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *); 132*9585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *); 133*9585STim.Szeto@Sun.COM 134*9585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER; 135*9585STim.Szeto@Sun.COM static int iPersistType = 0; 136*9585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */ 137*9585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE; 1387836SJohn.Forte@Sun.COM 1397836SJohn.Forte@Sun.COM /* 1407836SJohn.Forte@Sun.COM * Open for stmf module 1417836SJohn.Forte@Sun.COM * 1427836SJohn.Forte@Sun.COM * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF) 1437836SJohn.Forte@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1447836SJohn.Forte@Sun.COM */ 1457836SJohn.Forte@Sun.COM static int 1467836SJohn.Forte@Sun.COM openStmf(int flag, int *fd) 1477836SJohn.Forte@Sun.COM { 1487836SJohn.Forte@Sun.COM int ret = STMF_STATUS_ERROR; 1497836SJohn.Forte@Sun.COM 1507836SJohn.Forte@Sun.COM if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1517836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 1527836SJohn.Forte@Sun.COM } else { 1537836SJohn.Forte@Sun.COM if (errno == EBUSY) { 1547836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 155*9585STim.Szeto@Sun.COM } else if (errno == EACCES) { 156*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1577836SJohn.Forte@Sun.COM } else { 1587836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 1597836SJohn.Forte@Sun.COM } 1607836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)", 1617836SJohn.Forte@Sun.COM STMF_PATH, errno); 1627836SJohn.Forte@Sun.COM } 1637836SJohn.Forte@Sun.COM 1647836SJohn.Forte@Sun.COM return (ret); 1657836SJohn.Forte@Sun.COM } 1667836SJohn.Forte@Sun.COM 1677836SJohn.Forte@Sun.COM /* 168*9585STim.Szeto@Sun.COM * Open for sbd module 169*9585STim.Szeto@Sun.COM * 170*9585STim.Szeto@Sun.COM * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF) 171*9585STim.Szeto@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 172*9585STim.Szeto@Sun.COM */ 173*9585STim.Szeto@Sun.COM static int 174*9585STim.Szeto@Sun.COM openSbd(int flag, int *fd) 175*9585STim.Szeto@Sun.COM { 176*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 177*9585STim.Szeto@Sun.COM 178*9585STim.Szeto@Sun.COM if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 179*9585STim.Szeto@Sun.COM ret = STMF_STATUS_SUCCESS; 180*9585STim.Szeto@Sun.COM } else { 181*9585STim.Szeto@Sun.COM if (errno == EBUSY) { 182*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 183*9585STim.Szeto@Sun.COM } else if (errno == EACCES) { 184*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 185*9585STim.Szeto@Sun.COM } else { 186*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 187*9585STim.Szeto@Sun.COM } 188*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)", 189*9585STim.Szeto@Sun.COM SBD_PATH, errno); 190*9585STim.Szeto@Sun.COM } 191*9585STim.Szeto@Sun.COM 192*9585STim.Szeto@Sun.COM return (ret); 193*9585STim.Szeto@Sun.COM } 194*9585STim.Szeto@Sun.COM 195*9585STim.Szeto@Sun.COM /* 1967836SJohn.Forte@Sun.COM * initializeConfig 1977836SJohn.Forte@Sun.COM * 1987836SJohn.Forte@Sun.COM * This routine should be called before any ioctl requiring initialization 1997836SJohn.Forte@Sun.COM * which is basically everything except stmfGetState(), setStmfState() and 2007836SJohn.Forte@Sun.COM * stmfLoadConfig(). 2017836SJohn.Forte@Sun.COM */ 2027836SJohn.Forte@Sun.COM static int 2037836SJohn.Forte@Sun.COM initializeConfig() 2047836SJohn.Forte@Sun.COM { 2057836SJohn.Forte@Sun.COM int ret; 2067836SJohn.Forte@Sun.COM stmfState state; 2077836SJohn.Forte@Sun.COM 2087836SJohn.Forte@Sun.COM 2097836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2107836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2117836SJohn.Forte@Sun.COM return (ret); 2127836SJohn.Forte@Sun.COM } 2137836SJohn.Forte@Sun.COM 2147836SJohn.Forte@Sun.COM /* if we've already initialized or in the process, return success */ 2157836SJohn.Forte@Sun.COM if (state.configState == STMF_CONFIG_STATE_INIT_DONE || 2167836SJohn.Forte@Sun.COM state.configState == STMF_CONFIG_STATE_INIT) { 2177836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 2187836SJohn.Forte@Sun.COM } 2197836SJohn.Forte@Sun.COM 2207836SJohn.Forte@Sun.COM ret = stmfLoadConfig(); 2217836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2227836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2237836SJohn.Forte@Sun.COM "initializeConfig:stmfLoadConfig:error(%d)", ret); 2247836SJohn.Forte@Sun.COM return (ret); 2257836SJohn.Forte@Sun.COM } 2267836SJohn.Forte@Sun.COM 2277836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2287836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2297836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2307836SJohn.Forte@Sun.COM "initializeConfig:stmfGetState:error(%d)", ret); 2317836SJohn.Forte@Sun.COM return (ret); 2327836SJohn.Forte@Sun.COM } 2337836SJohn.Forte@Sun.COM 2347836SJohn.Forte@Sun.COM if (state.configState != STMF_CONFIG_STATE_INIT_DONE) { 2357836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)", 2367836SJohn.Forte@Sun.COM state.configState); 2377836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 2387836SJohn.Forte@Sun.COM } 2397836SJohn.Forte@Sun.COM 2407836SJohn.Forte@Sun.COM return (ret); 2417836SJohn.Forte@Sun.COM } 2427836SJohn.Forte@Sun.COM 2437836SJohn.Forte@Sun.COM 2447836SJohn.Forte@Sun.COM /* 2457836SJohn.Forte@Sun.COM * groupIoctl 2467836SJohn.Forte@Sun.COM * 2477836SJohn.Forte@Sun.COM * Purpose: issue ioctl for create/delete on group 2487836SJohn.Forte@Sun.COM * 2497836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group cmd 2507836SJohn.Forte@Sun.COM * groupName - groupName to create or delete 2517836SJohn.Forte@Sun.COM */ 2527836SJohn.Forte@Sun.COM static int 2537836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName) 2547836SJohn.Forte@Sun.COM { 2557836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 2567836SJohn.Forte@Sun.COM int ioctlRet; 2577836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 2587836SJohn.Forte@Sun.COM stmf_group_name_t iGroupName; 2597836SJohn.Forte@Sun.COM 2607836SJohn.Forte@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 2617836SJohn.Forte@Sun.COM 2627836SJohn.Forte@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 2637836SJohn.Forte@Sun.COM 2647836SJohn.Forte@Sun.COM iGroupName.name_size = strlen((char *)groupName); 2657836SJohn.Forte@Sun.COM 2667836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 2677836SJohn.Forte@Sun.COM /* 2687836SJohn.Forte@Sun.COM * Issue ioctl to create the host group 2697836SJohn.Forte@Sun.COM */ 2707836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 2717836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (iGroupName); 2727836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 2737836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 2747836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 2757836SJohn.Forte@Sun.COM switch (errno) { 276*9585STim.Szeto@Sun.COM case EPERM: 2777836SJohn.Forte@Sun.COM case EACCES: 2787836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 2797836SJohn.Forte@Sun.COM break; 2807836SJohn.Forte@Sun.COM default: 2817836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 2827836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_EXISTS: 2837836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_EXISTS: 2847836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 2857836SJohn.Forte@Sun.COM break; 2867836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_IN_USE: 2877836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_IN_USE: 2887836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_IN_USE; 2897836SJohn.Forte@Sun.COM break; 2907836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 2917836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 2927836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 2937836SJohn.Forte@Sun.COM break; 2947836SJohn.Forte@Sun.COM default: 2957836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2967836SJohn.Forte@Sun.COM "groupIoctl:error(%d)", 2977836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 2987836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 2997836SJohn.Forte@Sun.COM break; 3007836SJohn.Forte@Sun.COM } 3017836SJohn.Forte@Sun.COM break; 3027836SJohn.Forte@Sun.COM } 3037836SJohn.Forte@Sun.COM } 3047836SJohn.Forte@Sun.COM done: 3057836SJohn.Forte@Sun.COM return (ret); 3067836SJohn.Forte@Sun.COM } 3077836SJohn.Forte@Sun.COM 3087836SJohn.Forte@Sun.COM /* 309*9585STim.Szeto@Sun.COM * groupMemberIoctl 3107836SJohn.Forte@Sun.COM * 3117836SJohn.Forte@Sun.COM * Purpose: issue ioctl for add/remove member on group 3127836SJohn.Forte@Sun.COM * 3137836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group member cmd 3147836SJohn.Forte@Sun.COM * groupName - groupName to add to or remove from 3157836SJohn.Forte@Sun.COM * devid - group member to add or remove 3167836SJohn.Forte@Sun.COM */ 3177836SJohn.Forte@Sun.COM static int 3187836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid) 3197836SJohn.Forte@Sun.COM { 3207836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 3217836SJohn.Forte@Sun.COM int ioctlRet; 3227836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 3237836SJohn.Forte@Sun.COM stmf_group_op_data_t stmfGroupData; 3247836SJohn.Forte@Sun.COM 3257836SJohn.Forte@Sun.COM bzero(&stmfGroupData, sizeof (stmfGroupData)); 3267836SJohn.Forte@Sun.COM 3277836SJohn.Forte@Sun.COM bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName)); 3287836SJohn.Forte@Sun.COM 3297836SJohn.Forte@Sun.COM stmfGroupData.group.name_size = strlen((char *)groupName); 3307836SJohn.Forte@Sun.COM stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength; 3317836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1], 3327836SJohn.Forte@Sun.COM devid->identLength); 3337836SJohn.Forte@Sun.COM 3347836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3357836SJohn.Forte@Sun.COM /* 3367836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 3377836SJohn.Forte@Sun.COM */ 3387836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3397836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData); 3407836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData; 3417836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3427836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 3437836SJohn.Forte@Sun.COM switch (errno) { 3447836SJohn.Forte@Sun.COM case EBUSY: 3457836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 3467836SJohn.Forte@Sun.COM break; 347*9585STim.Szeto@Sun.COM case EPERM: 3487836SJohn.Forte@Sun.COM case EACCES: 3497836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 3507836SJohn.Forte@Sun.COM break; 3517836SJohn.Forte@Sun.COM default: 3527836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 3537836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_ENTRY_EXISTS: 3547836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_ENTRY_EXISTS: 3557836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 3567836SJohn.Forte@Sun.COM break; 3577836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG_ENTRY: 3587836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG_ENTRY: 3597836SJohn.Forte@Sun.COM ret = 3607836SJohn.Forte@Sun.COM STMF_ERROR_MEMBER_NOT_FOUND; 3617836SJohn.Forte@Sun.COM break; 3627836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 3637836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 3647836SJohn.Forte@Sun.COM ret = 3657836SJohn.Forte@Sun.COM STMF_ERROR_GROUP_NOT_FOUND; 3667836SJohn.Forte@Sun.COM break; 3677836SJohn.Forte@Sun.COM default: 3687836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 3697836SJohn.Forte@Sun.COM "groupMemberIoctl:error" 3707836SJohn.Forte@Sun.COM "(%d)", 3717836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 3727836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 3737836SJohn.Forte@Sun.COM break; 3747836SJohn.Forte@Sun.COM } 3757836SJohn.Forte@Sun.COM break; 3767836SJohn.Forte@Sun.COM } 3777836SJohn.Forte@Sun.COM } 3787836SJohn.Forte@Sun.COM done: 3797836SJohn.Forte@Sun.COM return (ret); 3807836SJohn.Forte@Sun.COM } 3817836SJohn.Forte@Sun.COM 3827836SJohn.Forte@Sun.COM /* 383*9585STim.Szeto@Sun.COM * qsort function 384*9585STim.Szeto@Sun.COM * sort on veIndex 385*9585STim.Szeto@Sun.COM */ 386*9585STim.Szeto@Sun.COM static int 387*9585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2) 388*9585STim.Szeto@Sun.COM { 389*9585STim.Szeto@Sun.COM 390*9585STim.Szeto@Sun.COM stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2; 391*9585STim.Szeto@Sun.COM if (v1->veIndex > v2->veIndex) 392*9585STim.Szeto@Sun.COM return (1); 393*9585STim.Szeto@Sun.COM if (v1->veIndex < v2->veIndex) 394*9585STim.Szeto@Sun.COM return (-1); 395*9585STim.Szeto@Sun.COM return (0); 396*9585STim.Szeto@Sun.COM } 397*9585STim.Szeto@Sun.COM 398*9585STim.Szeto@Sun.COM /* 3997836SJohn.Forte@Sun.COM * guidCompare 4007836SJohn.Forte@Sun.COM * 4017836SJohn.Forte@Sun.COM * qsort function 4027836SJohn.Forte@Sun.COM * sort on guid 4037836SJohn.Forte@Sun.COM */ 4047836SJohn.Forte@Sun.COM static int 4057836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2) 4067836SJohn.Forte@Sun.COM { 4077836SJohn.Forte@Sun.COM 4087836SJohn.Forte@Sun.COM stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2; 4097836SJohn.Forte@Sun.COM int i; 4107836SJohn.Forte@Sun.COM 4117836SJohn.Forte@Sun.COM for (i = 0; i < sizeof (stmfGuid); i++) { 4127836SJohn.Forte@Sun.COM if (g1->guid[i] > g2->guid[i]) 4137836SJohn.Forte@Sun.COM return (1); 4147836SJohn.Forte@Sun.COM if (g1->guid[i] < g2->guid[i]) 4157836SJohn.Forte@Sun.COM return (-1); 4167836SJohn.Forte@Sun.COM } 4177836SJohn.Forte@Sun.COM 4187836SJohn.Forte@Sun.COM return (0); 4197836SJohn.Forte@Sun.COM } 4207836SJohn.Forte@Sun.COM 4217836SJohn.Forte@Sun.COM /* 4227836SJohn.Forte@Sun.COM * stmfAddToHostGroup 4237836SJohn.Forte@Sun.COM * 4247836SJohn.Forte@Sun.COM * Purpose: Adds an initiator to an existing host group 4257836SJohn.Forte@Sun.COM * 4267836SJohn.Forte@Sun.COM * hostGroupName - name of an existing host group 4277836SJohn.Forte@Sun.COM * hostName - name of initiator to add 4287836SJohn.Forte@Sun.COM */ 4297836SJohn.Forte@Sun.COM int 4307836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 4317836SJohn.Forte@Sun.COM { 4327836SJohn.Forte@Sun.COM int ret; 4337836SJohn.Forte@Sun.COM int fd; 4347836SJohn.Forte@Sun.COM 4357836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 4367836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 4377836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 4387836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 4397836SJohn.Forte@Sun.COM } 4407836SJohn.Forte@Sun.COM 4417836SJohn.Forte@Sun.COM /* call init */ 4427836SJohn.Forte@Sun.COM ret = initializeConfig(); 4437836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4447836SJohn.Forte@Sun.COM return (ret); 4457836SJohn.Forte@Sun.COM } 4467836SJohn.Forte@Sun.COM 4477836SJohn.Forte@Sun.COM /* 4487836SJohn.Forte@Sun.COM * Open control node for stmf 4497836SJohn.Forte@Sun.COM */ 4507836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4517836SJohn.Forte@Sun.COM return (ret); 4527836SJohn.Forte@Sun.COM 4537836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName, 4547836SJohn.Forte@Sun.COM hostName)) != STMF_STATUS_SUCCESS) { 4557836SJohn.Forte@Sun.COM goto done; 4567836SJohn.Forte@Sun.COM } 4577836SJohn.Forte@Sun.COM 458*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 459*9585STim.Szeto@Sun.COM goto done; 460*9585STim.Szeto@Sun.COM } 461*9585STim.Szeto@Sun.COM 4627836SJohn.Forte@Sun.COM ret = psAddHostGroupMember((char *)hostGroupName, 4637836SJohn.Forte@Sun.COM (char *)hostName->ident); 4647836SJohn.Forte@Sun.COM switch (ret) { 4657836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 4667836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 4677836SJohn.Forte@Sun.COM break; 4687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 4697836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 4707836SJohn.Forte@Sun.COM break; 4717836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 4727836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 4737836SJohn.Forte@Sun.COM break; 4747836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 4757836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 4767836SJohn.Forte@Sun.COM break; 4777836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 4787836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 4797836SJohn.Forte@Sun.COM break; 4807836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 4817836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 4827836SJohn.Forte@Sun.COM break; 4837836SJohn.Forte@Sun.COM default: 4847836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 4857836SJohn.Forte@Sun.COM "stmfAddToHostGroup:psAddHostGroupMember:error(%d)", 4867836SJohn.Forte@Sun.COM ret); 4877836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 4887836SJohn.Forte@Sun.COM break; 4897836SJohn.Forte@Sun.COM } 4907836SJohn.Forte@Sun.COM 4917836SJohn.Forte@Sun.COM done: 4927836SJohn.Forte@Sun.COM (void) close(fd); 4937836SJohn.Forte@Sun.COM return (ret); 4947836SJohn.Forte@Sun.COM } 4957836SJohn.Forte@Sun.COM 4967836SJohn.Forte@Sun.COM /* 4977836SJohn.Forte@Sun.COM * stmfAddToTargetGroup 4987836SJohn.Forte@Sun.COM * 4997836SJohn.Forte@Sun.COM * Purpose: Adds a local port to an existing target group 5007836SJohn.Forte@Sun.COM * 5017836SJohn.Forte@Sun.COM * targetGroupName - name of an existing target group 5027836SJohn.Forte@Sun.COM * targetName - name of target to add 5037836SJohn.Forte@Sun.COM */ 5047836SJohn.Forte@Sun.COM int 5057836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 5067836SJohn.Forte@Sun.COM { 5077836SJohn.Forte@Sun.COM int ret; 5087836SJohn.Forte@Sun.COM int fd; 5097836SJohn.Forte@Sun.COM stmfState state; 5107836SJohn.Forte@Sun.COM 5117836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 5127836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 5137836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 5147836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 5157836SJohn.Forte@Sun.COM } 5167836SJohn.Forte@Sun.COM 5177836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 5187836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 5197836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 5207836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 5217836SJohn.Forte@Sun.COM } 5227836SJohn.Forte@Sun.COM } else { 5237836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 5247836SJohn.Forte@Sun.COM } 5257836SJohn.Forte@Sun.COM 5267836SJohn.Forte@Sun.COM /* call init */ 5277836SJohn.Forte@Sun.COM ret = initializeConfig(); 5287836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 5297836SJohn.Forte@Sun.COM return (ret); 5307836SJohn.Forte@Sun.COM } 5317836SJohn.Forte@Sun.COM 5327836SJohn.Forte@Sun.COM /* 5337836SJohn.Forte@Sun.COM * Open control node for stmf 5347836SJohn.Forte@Sun.COM */ 5357836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 5367836SJohn.Forte@Sun.COM return (ret); 5377836SJohn.Forte@Sun.COM 5387836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 5397836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 5407836SJohn.Forte@Sun.COM goto done; 5417836SJohn.Forte@Sun.COM } 5427836SJohn.Forte@Sun.COM 543*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 544*9585STim.Szeto@Sun.COM goto done; 545*9585STim.Szeto@Sun.COM } 546*9585STim.Szeto@Sun.COM 5477836SJohn.Forte@Sun.COM ret = psAddTargetGroupMember((char *)targetGroupName, 5487836SJohn.Forte@Sun.COM (char *)targetName->ident); 5497836SJohn.Forte@Sun.COM switch (ret) { 5507836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 5517836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 5527836SJohn.Forte@Sun.COM break; 5537836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 5547836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 5557836SJohn.Forte@Sun.COM break; 5567836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 5577836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 5587836SJohn.Forte@Sun.COM break; 5597836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 5607836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 5617836SJohn.Forte@Sun.COM break; 5627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 5637836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 5647836SJohn.Forte@Sun.COM break; 5657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 5667836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 5677836SJohn.Forte@Sun.COM break; 5687836SJohn.Forte@Sun.COM default: 5697836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 5707836SJohn.Forte@Sun.COM "stmfAddToTargetGroup:psAddTargetGroupMember:" 5717836SJohn.Forte@Sun.COM "error(%d)", ret); 5727836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 5737836SJohn.Forte@Sun.COM break; 5747836SJohn.Forte@Sun.COM } 5757836SJohn.Forte@Sun.COM 5767836SJohn.Forte@Sun.COM done: 5777836SJohn.Forte@Sun.COM (void) close(fd); 5787836SJohn.Forte@Sun.COM return (ret); 5797836SJohn.Forte@Sun.COM } 5807836SJohn.Forte@Sun.COM 5817836SJohn.Forte@Sun.COM /* 5827836SJohn.Forte@Sun.COM * addViewEntryIoctl 5837836SJohn.Forte@Sun.COM * 5847836SJohn.Forte@Sun.COM * Purpose: Issues ioctl to add a view entry 5857836SJohn.Forte@Sun.COM * 5867836SJohn.Forte@Sun.COM * lu - Logical Unit identifier to which the view entry is added 5877836SJohn.Forte@Sun.COM * viewEntry - view entry to add 5887836SJohn.Forte@Sun.COM * init - When set to B_TRUE, we are in the init state, i.e. don't call open 5897836SJohn.Forte@Sun.COM */ 5907836SJohn.Forte@Sun.COM static int 5917836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry) 5927836SJohn.Forte@Sun.COM { 5937836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 5947836SJohn.Forte@Sun.COM int ioctlRet; 5957836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 5967836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 5977836SJohn.Forte@Sun.COM 5987836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 5997836SJohn.Forte@Sun.COM /* 6007836SJohn.Forte@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 6017836SJohn.Forte@Sun.COM * false on input 6027836SJohn.Forte@Sun.COM */ 6037836SJohn.Forte@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 6047836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 6057836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 6067836SJohn.Forte@Sun.COM 6077836SJohn.Forte@Sun.COM if (viewEntry->allHosts == B_FALSE) { 6087836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 6097836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6107836SJohn.Forte@Sun.COM ioctlViewEntry.ve_host_group.name_size = 6117836SJohn.Forte@Sun.COM strlen((char *)viewEntry->hostGroup); 6127836SJohn.Forte@Sun.COM } 6137836SJohn.Forte@Sun.COM if (viewEntry->allTargets == B_FALSE) { 6147836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, 6157836SJohn.Forte@Sun.COM &ioctlViewEntry.ve_target_group.name, 6167836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6177836SJohn.Forte@Sun.COM ioctlViewEntry.ve_target_group.name_size = 6187836SJohn.Forte@Sun.COM strlen((char *)viewEntry->targetGroup); 6197836SJohn.Forte@Sun.COM } 6207836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 6217836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 6227836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 6237836SJohn.Forte@Sun.COM } 6247836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 6257836SJohn.Forte@Sun.COM 6267836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 6277836SJohn.Forte@Sun.COM /* 6287836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 6297836SJohn.Forte@Sun.COM */ 6307836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 6317836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 6327836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6337836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 6347836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6357836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl); 6367836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 6377836SJohn.Forte@Sun.COM switch (errno) { 6387836SJohn.Forte@Sun.COM case EBUSY: 6397836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 6407836SJohn.Forte@Sun.COM break; 641*9585STim.Szeto@Sun.COM case EPERM: 642*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 643*9585STim.Szeto@Sun.COM break; 6447836SJohn.Forte@Sun.COM case EACCES: 6457836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6467836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6477836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6487836SJohn.Forte@Sun.COM break; 6497836SJohn.Forte@Sun.COM default: 6507836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 6517836SJohn.Forte@Sun.COM break; 6527836SJohn.Forte@Sun.COM } 6537836SJohn.Forte@Sun.COM break; 6547836SJohn.Forte@Sun.COM default: 6557836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6567836SJohn.Forte@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 6577836SJohn.Forte@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 6587836SJohn.Forte@Sun.COM break; 6597836SJohn.Forte@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 6607836SJohn.Forte@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 6617836SJohn.Forte@Sun.COM break; 6627836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6637836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6647836SJohn.Forte@Sun.COM break; 6657836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 6667836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_HG; 6677836SJohn.Forte@Sun.COM break; 6687836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 6697836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_TG; 6707836SJohn.Forte@Sun.COM break; 6717836SJohn.Forte@Sun.COM default: 6727836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 6737836SJohn.Forte@Sun.COM "addViewEntryIoctl" 6747836SJohn.Forte@Sun.COM ":error(%d)", 6757836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 6767836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 6777836SJohn.Forte@Sun.COM break; 6787836SJohn.Forte@Sun.COM } 6797836SJohn.Forte@Sun.COM break; 6807836SJohn.Forte@Sun.COM } 6817836SJohn.Forte@Sun.COM goto done; 6827836SJohn.Forte@Sun.COM } 6837836SJohn.Forte@Sun.COM 6847836SJohn.Forte@Sun.COM /* copy lu nbr back to caller's view entry on success */ 6857836SJohn.Forte@Sun.COM viewEntry->veIndex = ioctlViewEntry.ve_ndx; 6867836SJohn.Forte@Sun.COM if (ioctlViewEntry.ve_lu_number_valid) { 6877836SJohn.Forte@Sun.COM bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 6887836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 6897836SJohn.Forte@Sun.COM } 6907836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 6917836SJohn.Forte@Sun.COM 6927836SJohn.Forte@Sun.COM done: 6937836SJohn.Forte@Sun.COM return (ret); 6947836SJohn.Forte@Sun.COM } 6957836SJohn.Forte@Sun.COM 6967836SJohn.Forte@Sun.COM /* 6977836SJohn.Forte@Sun.COM * stmfAddViewEntry 6987836SJohn.Forte@Sun.COM * 6997836SJohn.Forte@Sun.COM * Purpose: Adds a view entry to a logical unit 7007836SJohn.Forte@Sun.COM * 7017836SJohn.Forte@Sun.COM * lu - guid of the logical unit to which the view entry is added 7027836SJohn.Forte@Sun.COM * viewEntry - view entry structure to add 7037836SJohn.Forte@Sun.COM */ 7047836SJohn.Forte@Sun.COM int 7057836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry) 7067836SJohn.Forte@Sun.COM { 7077836SJohn.Forte@Sun.COM int ret; 7087836SJohn.Forte@Sun.COM int fd; 7097836SJohn.Forte@Sun.COM stmfViewEntry iViewEntry; 7107836SJohn.Forte@Sun.COM 7117836SJohn.Forte@Sun.COM if (lu == NULL || viewEntry == NULL) { 7127836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 7137836SJohn.Forte@Sun.COM } 7147836SJohn.Forte@Sun.COM 7157836SJohn.Forte@Sun.COM /* initialize and set internal view entry */ 7167836SJohn.Forte@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 7177836SJohn.Forte@Sun.COM 7187836SJohn.Forte@Sun.COM if (!viewEntry->allHosts) { 7197836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 7207836SJohn.Forte@Sun.COM sizeof (iViewEntry.hostGroup)); 7217836SJohn.Forte@Sun.COM } else { 7227836SJohn.Forte@Sun.COM iViewEntry.allHosts = B_TRUE; 7237836SJohn.Forte@Sun.COM } 7247836SJohn.Forte@Sun.COM 7257836SJohn.Forte@Sun.COM if (!viewEntry->allTargets) { 7267836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 7277836SJohn.Forte@Sun.COM sizeof (iViewEntry.targetGroup)); 7287836SJohn.Forte@Sun.COM } else { 7297836SJohn.Forte@Sun.COM iViewEntry.allTargets = B_TRUE; 7307836SJohn.Forte@Sun.COM } 7317836SJohn.Forte@Sun.COM 7327836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 7337836SJohn.Forte@Sun.COM iViewEntry.luNbrValid = B_TRUE; 7347836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 7357836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 7367836SJohn.Forte@Sun.COM } 7377836SJohn.Forte@Sun.COM 7387836SJohn.Forte@Sun.COM /* 7397836SJohn.Forte@Sun.COM * set users return view entry index valid flag to false 7407836SJohn.Forte@Sun.COM * in case of failure 7417836SJohn.Forte@Sun.COM */ 7427836SJohn.Forte@Sun.COM viewEntry->veIndexValid = B_FALSE; 7437836SJohn.Forte@Sun.COM 7447836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 7457836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 7467836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 7477836SJohn.Forte@Sun.COM } 7487836SJohn.Forte@Sun.COM 7497836SJohn.Forte@Sun.COM /* call init */ 7507836SJohn.Forte@Sun.COM ret = initializeConfig(); 7517836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7527836SJohn.Forte@Sun.COM return (ret); 7537836SJohn.Forte@Sun.COM } 7547836SJohn.Forte@Sun.COM 7557836SJohn.Forte@Sun.COM /* 7567836SJohn.Forte@Sun.COM * Open control node for stmf 7577836SJohn.Forte@Sun.COM */ 7587836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 7597836SJohn.Forte@Sun.COM return (ret); 7607836SJohn.Forte@Sun.COM 7617836SJohn.Forte@Sun.COM /* 7627836SJohn.Forte@Sun.COM * First add the view entry to the driver 7637836SJohn.Forte@Sun.COM */ 7647836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, lu, &iViewEntry); 7657836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7667836SJohn.Forte@Sun.COM goto done; 7677836SJohn.Forte@Sun.COM } 7687836SJohn.Forte@Sun.COM 769*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 770*9585STim.Szeto@Sun.COM goto done; 771*9585STim.Szeto@Sun.COM } 772*9585STim.Szeto@Sun.COM 7737836SJohn.Forte@Sun.COM /* 7747836SJohn.Forte@Sun.COM * If the add to driver was successful, add it to the persistent 7757836SJohn.Forte@Sun.COM * store. 7767836SJohn.Forte@Sun.COM */ 7777836SJohn.Forte@Sun.COM ret = psAddViewEntry(lu, &iViewEntry); 7787836SJohn.Forte@Sun.COM switch (ret) { 7797836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 7807836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 7817836SJohn.Forte@Sun.COM break; 7827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 7837836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 7847836SJohn.Forte@Sun.COM break; 7857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 7867836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 7877836SJohn.Forte@Sun.COM break; 7887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 7897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 7907836SJohn.Forte@Sun.COM break; 7917836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 7927836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 7937836SJohn.Forte@Sun.COM break; 7947836SJohn.Forte@Sun.COM default: 7957836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 7967836SJohn.Forte@Sun.COM "stmfAddViewEntry:psAddViewEntry:error(%d)", ret); 7977836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 7987836SJohn.Forte@Sun.COM break; 7997836SJohn.Forte@Sun.COM } 8007836SJohn.Forte@Sun.COM 8017836SJohn.Forte@Sun.COM done: 8027836SJohn.Forte@Sun.COM (void) close(fd); 8037836SJohn.Forte@Sun.COM 8047836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 8057836SJohn.Forte@Sun.COM /* set caller's view entry on success */ 8067836SJohn.Forte@Sun.COM viewEntry->veIndexValid = iViewEntry.veIndexValid; 8077836SJohn.Forte@Sun.COM viewEntry->veIndex = iViewEntry.veIndex; 8087836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 8097836SJohn.Forte@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 8107836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 8117836SJohn.Forte@Sun.COM } 8127836SJohn.Forte@Sun.COM return (ret); 8137836SJohn.Forte@Sun.COM } 8147836SJohn.Forte@Sun.COM 8157836SJohn.Forte@Sun.COM /* 8167836SJohn.Forte@Sun.COM * stmfClearProviderData 8177836SJohn.Forte@Sun.COM * 8187836SJohn.Forte@Sun.COM * Purpose: delete all provider data for specified provider 8197836SJohn.Forte@Sun.COM * 8207836SJohn.Forte@Sun.COM * providerName - name of provider for which data should be deleted 8217836SJohn.Forte@Sun.COM */ 8227836SJohn.Forte@Sun.COM int 8237836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType) 8247836SJohn.Forte@Sun.COM { 8257836SJohn.Forte@Sun.COM int ret; 8267836SJohn.Forte@Sun.COM int fd; 8277836SJohn.Forte@Sun.COM int ioctlRet; 8287836SJohn.Forte@Sun.COM int savedErrno; 8297836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 8307836SJohn.Forte@Sun.COM stmf_ppioctl_data_t ppi; 8317836SJohn.Forte@Sun.COM 8327836SJohn.Forte@Sun.COM /* call init */ 8337836SJohn.Forte@Sun.COM ret = initializeConfig(); 8347836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 8357836SJohn.Forte@Sun.COM return (ret); 8367836SJohn.Forte@Sun.COM } 8377836SJohn.Forte@Sun.COM 8387836SJohn.Forte@Sun.COM if (providerName == NULL) { 8397836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8407836SJohn.Forte@Sun.COM } 8417836SJohn.Forte@Sun.COM 8427836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 8437836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 8447836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8457836SJohn.Forte@Sun.COM } 8467836SJohn.Forte@Sun.COM 8477836SJohn.Forte@Sun.COM /* 8487836SJohn.Forte@Sun.COM * Open control node for stmf 8497836SJohn.Forte@Sun.COM */ 8507836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 8517836SJohn.Forte@Sun.COM return (ret); 8527836SJohn.Forte@Sun.COM 8537836SJohn.Forte@Sun.COM bzero(&ppi, sizeof (ppi)); 8547836SJohn.Forte@Sun.COM 8557836SJohn.Forte@Sun.COM (void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name)); 8567836SJohn.Forte@Sun.COM 8577836SJohn.Forte@Sun.COM switch (providerType) { 8587836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 8597836SJohn.Forte@Sun.COM ppi.ppi_lu_provider = 1; 8607836SJohn.Forte@Sun.COM break; 8617836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 8627836SJohn.Forte@Sun.COM ppi.ppi_port_provider = 1; 8637836SJohn.Forte@Sun.COM break; 8647836SJohn.Forte@Sun.COM default: 8657836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 8667836SJohn.Forte@Sun.COM goto done; 8677836SJohn.Forte@Sun.COM } 8687836SJohn.Forte@Sun.COM 8697836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 8707836SJohn.Forte@Sun.COM 8717836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 8727836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 8737836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 8747836SJohn.Forte@Sun.COM 8757836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl); 8767836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 8777836SJohn.Forte@Sun.COM savedErrno = errno; 8787836SJohn.Forte@Sun.COM switch (savedErrno) { 8797836SJohn.Forte@Sun.COM case EBUSY: 8807836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 8817836SJohn.Forte@Sun.COM break; 882*9585STim.Szeto@Sun.COM case EPERM: 8837836SJohn.Forte@Sun.COM case EACCES: 8847836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 8857836SJohn.Forte@Sun.COM break; 8867836SJohn.Forte@Sun.COM default: 8877836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 8887836SJohn.Forte@Sun.COM "stmfClearProviderData:ioctl error(%d)", 8897836SJohn.Forte@Sun.COM ioctlRet); 8907836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 8917836SJohn.Forte@Sun.COM break; 8927836SJohn.Forte@Sun.COM } 8937836SJohn.Forte@Sun.COM if (savedErrno != ENOENT) { 8947836SJohn.Forte@Sun.COM goto done; 8957836SJohn.Forte@Sun.COM } 8967836SJohn.Forte@Sun.COM } 8977836SJohn.Forte@Sun.COM 898*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 899*9585STim.Szeto@Sun.COM goto done; 900*9585STim.Szeto@Sun.COM } 901*9585STim.Szeto@Sun.COM 9027836SJohn.Forte@Sun.COM ret = psClearProviderData(providerName, providerType); 9037836SJohn.Forte@Sun.COM switch (ret) { 9047836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 9057836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 9067836SJohn.Forte@Sun.COM break; 9077836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 9087836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 9097836SJohn.Forte@Sun.COM break; 9107836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 9117836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9127836SJohn.Forte@Sun.COM break; 9137836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 9147836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 9157836SJohn.Forte@Sun.COM break; 9167836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 9177836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 9187836SJohn.Forte@Sun.COM break; 9197836SJohn.Forte@Sun.COM default: 9207836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9217836SJohn.Forte@Sun.COM "stmfClearProviderData:psClearProviderData" 9227836SJohn.Forte@Sun.COM ":error(%d)", ret); 9237836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9247836SJohn.Forte@Sun.COM break; 9257836SJohn.Forte@Sun.COM } 9267836SJohn.Forte@Sun.COM 9277836SJohn.Forte@Sun.COM done: 9287836SJohn.Forte@Sun.COM (void) close(fd); 9297836SJohn.Forte@Sun.COM return (ret); 9307836SJohn.Forte@Sun.COM } 9317836SJohn.Forte@Sun.COM 9327836SJohn.Forte@Sun.COM /* 9337836SJohn.Forte@Sun.COM * stmfCreateHostGroup 9347836SJohn.Forte@Sun.COM * 9357836SJohn.Forte@Sun.COM * Purpose: Create a new initiator group 9367836SJohn.Forte@Sun.COM * 9377836SJohn.Forte@Sun.COM * hostGroupName - name of host group to create 9387836SJohn.Forte@Sun.COM */ 9397836SJohn.Forte@Sun.COM int 9407836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName) 9417836SJohn.Forte@Sun.COM { 9427836SJohn.Forte@Sun.COM int ret; 9437836SJohn.Forte@Sun.COM int fd; 9447836SJohn.Forte@Sun.COM 9457836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 9467836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 9477836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 9487836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 9497836SJohn.Forte@Sun.COM } 9507836SJohn.Forte@Sun.COM 9517836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 9527836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 9537836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 9547836SJohn.Forte@Sun.COM } 9557836SJohn.Forte@Sun.COM 9567836SJohn.Forte@Sun.COM /* call init */ 9577836SJohn.Forte@Sun.COM ret = initializeConfig(); 9587836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 9597836SJohn.Forte@Sun.COM return (ret); 9607836SJohn.Forte@Sun.COM } 9617836SJohn.Forte@Sun.COM 9627836SJohn.Forte@Sun.COM /* 9637836SJohn.Forte@Sun.COM * Open control node for stmf 9647836SJohn.Forte@Sun.COM */ 9657836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 9667836SJohn.Forte@Sun.COM return (ret); 9677836SJohn.Forte@Sun.COM 9687836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 9697836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 9707836SJohn.Forte@Sun.COM goto done; 9717836SJohn.Forte@Sun.COM } 9727836SJohn.Forte@Sun.COM 973*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 974*9585STim.Szeto@Sun.COM goto done; 975*9585STim.Szeto@Sun.COM } 976*9585STim.Szeto@Sun.COM 9777836SJohn.Forte@Sun.COM ret = psCreateHostGroup((char *)hostGroupName); 9787836SJohn.Forte@Sun.COM switch (ret) { 9797836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 9807836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 9817836SJohn.Forte@Sun.COM break; 9827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 9837836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 9847836SJohn.Forte@Sun.COM break; 9857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 9867836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9877836SJohn.Forte@Sun.COM break; 9887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 9897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 9907836SJohn.Forte@Sun.COM break; 9917836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 9927836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 9937836SJohn.Forte@Sun.COM break; 9947836SJohn.Forte@Sun.COM default: 9957836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9967836SJohn.Forte@Sun.COM "stmfCreateHostGroup:psCreateHostGroup:error(%d)", 9977836SJohn.Forte@Sun.COM ret); 9987836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9997836SJohn.Forte@Sun.COM break; 10007836SJohn.Forte@Sun.COM } 10017836SJohn.Forte@Sun.COM 10027836SJohn.Forte@Sun.COM done: 10037836SJohn.Forte@Sun.COM (void) close(fd); 10047836SJohn.Forte@Sun.COM return (ret); 10057836SJohn.Forte@Sun.COM } 10067836SJohn.Forte@Sun.COM 10077836SJohn.Forte@Sun.COM /* 1008*9585STim.Szeto@Sun.COM * stmfCreateLu 1009*9585STim.Szeto@Sun.COM * 1010*9585STim.Szeto@Sun.COM * Purpose: Create a logical unit 1011*9585STim.Szeto@Sun.COM * 1012*9585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 1013*9585STim.Szeto@Sun.COM * 1014*9585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 1015*9585STim.Szeto@Sun.COM * unit 1016*9585STim.Szeto@Sun.COM */ 1017*9585STim.Szeto@Sun.COM int 1018*9585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid) 1019*9585STim.Szeto@Sun.COM { 1020*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1021*9585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 1022*9585STim.Szeto@Sun.COM 1023*9585STim.Szeto@Sun.COM if (hdl == NULL) { 1024*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1025*9585STim.Szeto@Sun.COM } 1026*9585STim.Szeto@Sun.COM 1027*9585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 1028*9585STim.Szeto@Sun.COM ret = createDiskLu((diskResource *)luPropsHdl->resource, 1029*9585STim.Szeto@Sun.COM luGuid); 1030*9585STim.Szeto@Sun.COM } else { 1031*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1032*9585STim.Szeto@Sun.COM } 1033*9585STim.Szeto@Sun.COM 1034*9585STim.Szeto@Sun.COM return (ret); 1035*9585STim.Szeto@Sun.COM } 1036*9585STim.Szeto@Sun.COM 1037*9585STim.Szeto@Sun.COM /* 1038*9585STim.Szeto@Sun.COM * stmfCreateLuResource 1039*9585STim.Szeto@Sun.COM * 1040*9585STim.Szeto@Sun.COM * Purpose: Create resource handle for a logical unit 1041*9585STim.Szeto@Sun.COM * 1042*9585STim.Szeto@Sun.COM * dType - Type of logical unit resource to create 1043*9585STim.Szeto@Sun.COM * Can be: STMF_DISK 1044*9585STim.Szeto@Sun.COM * 1045*9585STim.Szeto@Sun.COM * hdl - pointer to luResource 1046*9585STim.Szeto@Sun.COM */ 1047*9585STim.Szeto@Sun.COM int 1048*9585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl) 1049*9585STim.Szeto@Sun.COM { 1050*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1051*9585STim.Szeto@Sun.COM 1052*9585STim.Szeto@Sun.COM if (dType != STMF_DISK || hdl == NULL) { 1053*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1054*9585STim.Szeto@Sun.COM } 1055*9585STim.Szeto@Sun.COM 1056*9585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 1057*9585STim.Szeto@Sun.COM if (*hdl == NULL) { 1058*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 1059*9585STim.Szeto@Sun.COM } 1060*9585STim.Szeto@Sun.COM 1061*9585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 1062*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1063*9585STim.Szeto@Sun.COM free(*hdl); 1064*9585STim.Szeto@Sun.COM return (ret); 1065*9585STim.Szeto@Sun.COM } 1066*9585STim.Szeto@Sun.COM 1067*9585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 1068*9585STim.Szeto@Sun.COM } 1069*9585STim.Szeto@Sun.COM 1070*9585STim.Szeto@Sun.COM /* 1071*9585STim.Szeto@Sun.COM * Creates a disk logical unit 1072*9585STim.Szeto@Sun.COM * 1073*9585STim.Szeto@Sun.COM * disk - pointer to diskResource structure that represents the properties 1074*9585STim.Szeto@Sun.COM * for the disk logical unit to be created. 1075*9585STim.Szeto@Sun.COM */ 1076*9585STim.Szeto@Sun.COM static int 1077*9585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid) 1078*9585STim.Szeto@Sun.COM { 1079*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1080*9585STim.Szeto@Sun.COM int dataFileNameLen = 0; 1081*9585STim.Szeto@Sun.COM int metaFileNameLen = 0; 1082*9585STim.Szeto@Sun.COM int serialNumLen = 0; 1083*9585STim.Szeto@Sun.COM int luAliasLen = 0; 1084*9585STim.Szeto@Sun.COM int sluBufSize = 0; 1085*9585STim.Szeto@Sun.COM int bufOffset = 0; 1086*9585STim.Szeto@Sun.COM int fd = 0; 1087*9585STim.Szeto@Sun.COM int ioctlRet; 1088*9585STim.Szeto@Sun.COM int savedErrno; 1089*9585STim.Szeto@Sun.COM stmfGuid guid; 1090*9585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 1091*9585STim.Szeto@Sun.COM 1092*9585STim.Szeto@Sun.COM sbd_create_and_reg_lu_t *sbdLu = NULL; 1093*9585STim.Szeto@Sun.COM 1094*9585STim.Szeto@Sun.COM /* 1095*9585STim.Szeto@Sun.COM * Open control node for sbd 1096*9585STim.Szeto@Sun.COM */ 1097*9585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 1098*9585STim.Szeto@Sun.COM return (ret); 1099*9585STim.Szeto@Sun.COM 1100*9585STim.Szeto@Sun.COM /* data file name must be specified */ 1101*9585STim.Szeto@Sun.COM if (disk->luDataFileNameValid) { 1102*9585STim.Szeto@Sun.COM dataFileNameLen = strlen(disk->luDataFileName); 1103*9585STim.Szeto@Sun.COM } else { 1104*9585STim.Szeto@Sun.COM (void) close(fd); 1105*9585STim.Szeto@Sun.COM return (STMF_ERROR_MISSING_PROP_VAL); 1106*9585STim.Szeto@Sun.COM } 1107*9585STim.Szeto@Sun.COM 1108*9585STim.Szeto@Sun.COM sluBufSize += dataFileNameLen + 1; 1109*9585STim.Szeto@Sun.COM 1110*9585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 1111*9585STim.Szeto@Sun.COM metaFileNameLen = strlen(disk->luMetaFileName); 1112*9585STim.Szeto@Sun.COM sluBufSize += metaFileNameLen + 1; 1113*9585STim.Szeto@Sun.COM } 1114*9585STim.Szeto@Sun.COM 1115*9585STim.Szeto@Sun.COM serialNumLen = strlen(disk->serialNum); 1116*9585STim.Szeto@Sun.COM sluBufSize += serialNumLen; 1117*9585STim.Szeto@Sun.COM 1118*9585STim.Szeto@Sun.COM if (disk->luAliasValid) { 1119*9585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 1120*9585STim.Szeto@Sun.COM sluBufSize += luAliasLen + 1; 1121*9585STim.Szeto@Sun.COM } 1122*9585STim.Szeto@Sun.COM 1123*9585STim.Szeto@Sun.COM /* 1124*9585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 1125*9585STim.Szeto@Sun.COM * concatenation of variable length fields 1126*9585STim.Szeto@Sun.COM */ 1127*9585STim.Szeto@Sun.COM sbdLu = (sbd_create_and_reg_lu_t *)calloc(1, 1128*9585STim.Szeto@Sun.COM sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8); 1129*9585STim.Szeto@Sun.COM if (sbdLu == NULL) { 1130*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 1131*9585STim.Szeto@Sun.COM } 1132*9585STim.Szeto@Sun.COM 1133*9585STim.Szeto@Sun.COM sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) + 1134*9585STim.Szeto@Sun.COM sluBufSize - 8; 1135*9585STim.Szeto@Sun.COM 1136*9585STim.Szeto@Sun.COM if (metaFileNameLen) { 1137*9585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_valid = 1; 1138*9585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_off = bufOffset; 1139*9585STim.Szeto@Sun.COM bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]), 1140*9585STim.Szeto@Sun.COM metaFileNameLen + 1); 1141*9585STim.Szeto@Sun.COM bufOffset += metaFileNameLen + 1; 1142*9585STim.Szeto@Sun.COM } 1143*9585STim.Szeto@Sun.COM 1144*9585STim.Szeto@Sun.COM bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]), 1145*9585STim.Szeto@Sun.COM dataFileNameLen + 1); 1146*9585STim.Szeto@Sun.COM sbdLu->slu_data_fname_off = bufOffset; 1147*9585STim.Szeto@Sun.COM bufOffset += dataFileNameLen + 1; 1148*9585STim.Szeto@Sun.COM 1149*9585STim.Szeto@Sun.COM /* currently, serial # is not passed null terminated to the driver */ 1150*9585STim.Szeto@Sun.COM if (disk->serialNumValid) { 1151*9585STim.Szeto@Sun.COM sbdLu->slu_serial_valid = 1; 1152*9585STim.Szeto@Sun.COM sbdLu->slu_serial_off = bufOffset; 1153*9585STim.Szeto@Sun.COM sbdLu->slu_serial_size = serialNumLen; 1154*9585STim.Szeto@Sun.COM bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]), 1155*9585STim.Szeto@Sun.COM serialNumLen); 1156*9585STim.Szeto@Sun.COM bufOffset += serialNumLen; 1157*9585STim.Szeto@Sun.COM } 1158*9585STim.Szeto@Sun.COM 1159*9585STim.Szeto@Sun.COM if (disk->luAliasValid) { 1160*9585STim.Szeto@Sun.COM sbdLu->slu_alias_valid = 1; 1161*9585STim.Szeto@Sun.COM sbdLu->slu_alias_off = bufOffset; 1162*9585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]), 1163*9585STim.Szeto@Sun.COM luAliasLen + 1); 1164*9585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 1165*9585STim.Szeto@Sun.COM } 1166*9585STim.Szeto@Sun.COM 1167*9585STim.Szeto@Sun.COM if (disk->luSizeValid) { 1168*9585STim.Szeto@Sun.COM sbdLu->slu_lu_size_valid = 1; 1169*9585STim.Szeto@Sun.COM sbdLu->slu_lu_size = disk->luSize; 1170*9585STim.Szeto@Sun.COM } 1171*9585STim.Szeto@Sun.COM 1172*9585STim.Szeto@Sun.COM if (disk->luGuidValid) { 1173*9585STim.Szeto@Sun.COM sbdLu->slu_guid_valid = 1; 1174*9585STim.Szeto@Sun.COM bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid)); 1175*9585STim.Szeto@Sun.COM } 1176*9585STim.Szeto@Sun.COM 1177*9585STim.Szeto@Sun.COM if (disk->vidValid) { 1178*9585STim.Szeto@Sun.COM sbdLu->slu_vid_valid = 1; 1179*9585STim.Szeto@Sun.COM bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid)); 1180*9585STim.Szeto@Sun.COM } 1181*9585STim.Szeto@Sun.COM 1182*9585STim.Szeto@Sun.COM if (disk->pidValid) { 1183*9585STim.Szeto@Sun.COM sbdLu->slu_pid_valid = 1; 1184*9585STim.Szeto@Sun.COM bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid)); 1185*9585STim.Szeto@Sun.COM } 1186*9585STim.Szeto@Sun.COM 1187*9585STim.Szeto@Sun.COM if (disk->revValid) { 1188*9585STim.Szeto@Sun.COM sbdLu->slu_rev_valid = 1; 1189*9585STim.Szeto@Sun.COM bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev)); 1190*9585STim.Szeto@Sun.COM } 1191*9585STim.Szeto@Sun.COM 1192*9585STim.Szeto@Sun.COM if (disk->companyIdValid) { 1193*9585STim.Szeto@Sun.COM sbdLu->slu_company_id_valid = 1; 1194*9585STim.Szeto@Sun.COM sbdLu->slu_company_id = disk->companyId; 1195*9585STim.Szeto@Sun.COM } 1196*9585STim.Szeto@Sun.COM 1197*9585STim.Szeto@Sun.COM if (disk->blkSizeValid) { 1198*9585STim.Szeto@Sun.COM sbdLu->slu_blksize_valid = 1; 1199*9585STim.Szeto@Sun.COM sbdLu->slu_blksize = disk->blkSize; 1200*9585STim.Szeto@Sun.COM } 1201*9585STim.Szeto@Sun.COM 1202*9585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 1203*9585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 1204*9585STim.Szeto@Sun.COM sbdLu->slu_write_protected = 1; 1205*9585STim.Szeto@Sun.COM } 1206*9585STim.Szeto@Sun.COM } 1207*9585STim.Szeto@Sun.COM 1208*9585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 1209*9585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable_valid = 1; 1210*9585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 1211*9585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable = 1; 1212*9585STim.Szeto@Sun.COM } 1213*9585STim.Szeto@Sun.COM } 1214*9585STim.Szeto@Sun.COM 1215*9585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 1216*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size; 1217*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 1218*9585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size; 1219*9585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 1220*9585STim.Szeto@Sun.COM 1221*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl); 1222*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 1223*9585STim.Szeto@Sun.COM savedErrno = errno; 1224*9585STim.Szeto@Sun.COM switch (savedErrno) { 1225*9585STim.Szeto@Sun.COM case EBUSY: 1226*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1227*9585STim.Szeto@Sun.COM break; 1228*9585STim.Szeto@Sun.COM case EPERM: 1229*9585STim.Szeto@Sun.COM case EACCES: 1230*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1231*9585STim.Szeto@Sun.COM break; 1232*9585STim.Szeto@Sun.COM default: 1233*9585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 1234*9585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 1235*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1236*9585STim.Szeto@Sun.COM "createDiskLu:ioctl " 1237*9585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 1238*9585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 1239*9585STim.Szeto@Sun.COM } 1240*9585STim.Szeto@Sun.COM break; 1241*9585STim.Szeto@Sun.COM } 1242*9585STim.Szeto@Sun.COM } 1243*9585STim.Szeto@Sun.COM 1244*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1245*9585STim.Szeto@Sun.COM goto done; 1246*9585STim.Szeto@Sun.COM } 1247*9585STim.Szeto@Sun.COM 1248*9585STim.Szeto@Sun.COM /* 1249*9585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 1250*9585STim.Szeto@Sun.COM * NULL 1251*9585STim.Szeto@Sun.COM */ 1252*9585STim.Szeto@Sun.COM if (createdGuid) { 1253*9585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, createdGuid->guid, 1254*9585STim.Szeto@Sun.COM sizeof (sbdLu->slu_guid)); 1255*9585STim.Szeto@Sun.COM } 1256*9585STim.Szeto@Sun.COM 1257*9585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid)); 1258*9585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 1259*9585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luMetaFileName); 1260*9585STim.Szeto@Sun.COM } else { 1261*9585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luDataFileName); 1262*9585STim.Szeto@Sun.COM } 1263*9585STim.Szeto@Sun.COM done: 1264*9585STim.Szeto@Sun.COM free(sbdLu); 1265*9585STim.Szeto@Sun.COM (void) close(fd); 1266*9585STim.Szeto@Sun.COM return (ret); 1267*9585STim.Szeto@Sun.COM } 1268*9585STim.Szeto@Sun.COM 1269*9585STim.Szeto@Sun.COM 1270*9585STim.Szeto@Sun.COM /* 1271*9585STim.Szeto@Sun.COM * stmfImportLu 1272*9585STim.Szeto@Sun.COM * 1273*9585STim.Szeto@Sun.COM * Purpose: Import a previously created logical unit 1274*9585STim.Szeto@Sun.COM * 1275*9585STim.Szeto@Sun.COM * dType - Type of logical unit 1276*9585STim.Szeto@Sun.COM * Can be: STMF_DISK 1277*9585STim.Szeto@Sun.COM * 1278*9585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the imported logical 1279*9585STim.Szeto@Sun.COM * unit 1280*9585STim.Szeto@Sun.COM * 1281*9585STim.Szeto@Sun.COM * fname - A file name where the metadata resides 1282*9585STim.Szeto@Sun.COM * 1283*9585STim.Szeto@Sun.COM */ 1284*9585STim.Szeto@Sun.COM int 1285*9585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid) 1286*9585STim.Szeto@Sun.COM { 1287*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1288*9585STim.Szeto@Sun.COM 1289*9585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 1290*9585STim.Szeto@Sun.COM ret = importDiskLu(fname, luGuid); 1291*9585STim.Szeto@Sun.COM } else { 1292*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1293*9585STim.Szeto@Sun.COM } 1294*9585STim.Szeto@Sun.COM 1295*9585STim.Szeto@Sun.COM return (ret); 1296*9585STim.Szeto@Sun.COM } 1297*9585STim.Szeto@Sun.COM 1298*9585STim.Szeto@Sun.COM /* 1299*9585STim.Szeto@Sun.COM * importDiskLu 1300*9585STim.Szeto@Sun.COM * 1301*9585STim.Szeto@Sun.COM * filename - filename to import 1302*9585STim.Szeto@Sun.COM * createdGuid - if not NULL, on success contains the imported guid 1303*9585STim.Szeto@Sun.COM * 1304*9585STim.Szeto@Sun.COM */ 1305*9585STim.Szeto@Sun.COM static int 1306*9585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid) 1307*9585STim.Szeto@Sun.COM { 1308*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1309*9585STim.Szeto@Sun.COM int fd = 0; 1310*9585STim.Szeto@Sun.COM int ioctlRet; 1311*9585STim.Szeto@Sun.COM int savedErrno; 1312*9585STim.Szeto@Sun.COM int metaFileNameLen; 1313*9585STim.Szeto@Sun.COM stmfGuid iGuid; 1314*9585STim.Szeto@Sun.COM int iluBufSize = 0; 1315*9585STim.Szeto@Sun.COM sbd_import_lu_t *sbdLu = NULL; 1316*9585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 1317*9585STim.Szeto@Sun.COM 1318*9585STim.Szeto@Sun.COM if (fname == NULL) { 1319*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1320*9585STim.Szeto@Sun.COM } 1321*9585STim.Szeto@Sun.COM 1322*9585STim.Szeto@Sun.COM /* 1323*9585STim.Szeto@Sun.COM * Open control node for sbd 1324*9585STim.Szeto@Sun.COM */ 1325*9585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 1326*9585STim.Szeto@Sun.COM return (ret); 1327*9585STim.Szeto@Sun.COM 1328*9585STim.Szeto@Sun.COM metaFileNameLen = strlen(fname); 1329*9585STim.Szeto@Sun.COM iluBufSize += metaFileNameLen + 1; 1330*9585STim.Szeto@Sun.COM 1331*9585STim.Szeto@Sun.COM /* 1332*9585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 1333*9585STim.Szeto@Sun.COM * concatenation of variable length fields 1334*9585STim.Szeto@Sun.COM */ 1335*9585STim.Szeto@Sun.COM sbdLu = (sbd_import_lu_t *)calloc(1, 1336*9585STim.Szeto@Sun.COM sizeof (sbd_import_lu_t) + iluBufSize - 8); 1337*9585STim.Szeto@Sun.COM if (sbdLu == NULL) { 1338*9585STim.Szeto@Sun.COM (void) close(fd); 1339*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 1340*9585STim.Szeto@Sun.COM } 1341*9585STim.Szeto@Sun.COM 1342*9585STim.Szeto@Sun.COM /* 1343*9585STim.Szeto@Sun.COM * Accept either a data file or meta data file. 1344*9585STim.Szeto@Sun.COM * sbd will do the right thing here either way. 1345*9585STim.Szeto@Sun.COM * i.e. if it's a data file, it assumes that the 1346*9585STim.Szeto@Sun.COM * meta data is shared with the data. 1347*9585STim.Szeto@Sun.COM */ 1348*9585STim.Szeto@Sun.COM (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen); 1349*9585STim.Szeto@Sun.COM 1350*9585STim.Szeto@Sun.COM sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8; 1351*9585STim.Szeto@Sun.COM 1352*9585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 1353*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size; 1354*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 1355*9585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size; 1356*9585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 1357*9585STim.Szeto@Sun.COM 1358*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl); 1359*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 1360*9585STim.Szeto@Sun.COM savedErrno = errno; 1361*9585STim.Szeto@Sun.COM switch (savedErrno) { 1362*9585STim.Szeto@Sun.COM case EBUSY: 1363*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1364*9585STim.Szeto@Sun.COM break; 1365*9585STim.Szeto@Sun.COM case EPERM: 1366*9585STim.Szeto@Sun.COM case EACCES: 1367*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1368*9585STim.Szeto@Sun.COM break; 1369*9585STim.Szeto@Sun.COM default: 1370*9585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 1371*9585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 1372*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1373*9585STim.Szeto@Sun.COM "importDiskLu:ioctl " 1374*9585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 1375*9585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 1376*9585STim.Szeto@Sun.COM } 1377*9585STim.Szeto@Sun.COM break; 1378*9585STim.Szeto@Sun.COM } 1379*9585STim.Szeto@Sun.COM } 1380*9585STim.Szeto@Sun.COM 1381*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1382*9585STim.Szeto@Sun.COM goto done; 1383*9585STim.Szeto@Sun.COM } 1384*9585STim.Szeto@Sun.COM 1385*9585STim.Szeto@Sun.COM /* 1386*9585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 1387*9585STim.Szeto@Sun.COM * NULL and add it to the persistent store for sbd 1388*9585STim.Szeto@Sun.COM */ 1389*9585STim.Szeto@Sun.COM if (createdGuid) { 1390*9585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, createdGuid->guid, 1391*9585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 1392*9585STim.Szeto@Sun.COM ret = addGuidToDiskStore(createdGuid, fname); 1393*9585STim.Szeto@Sun.COM } else { 1394*9585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, iGuid.guid, 1395*9585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 1396*9585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&iGuid, fname); 1397*9585STim.Szeto@Sun.COM } 1398*9585STim.Szeto@Sun.COM done: 1399*9585STim.Szeto@Sun.COM free(sbdLu); 1400*9585STim.Szeto@Sun.COM (void) close(fd); 1401*9585STim.Szeto@Sun.COM return (ret); 1402*9585STim.Szeto@Sun.COM } 1403*9585STim.Szeto@Sun.COM 1404*9585STim.Szeto@Sun.COM /* 1405*9585STim.Szeto@Sun.COM * diskError 1406*9585STim.Szeto@Sun.COM * 1407*9585STim.Szeto@Sun.COM * Purpose: Translate sbd driver error 1408*9585STim.Szeto@Sun.COM */ 1409*9585STim.Szeto@Sun.COM static void 1410*9585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret) 1411*9585STim.Szeto@Sun.COM { 1412*9585STim.Szeto@Sun.COM switch (stmfError) { 1413*9585STim.Szeto@Sun.COM case SBD_RET_META_CREATION_FAILED: 1414*9585STim.Szeto@Sun.COM case SBD_RET_ZFS_META_CREATE_FAILED: 1415*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_CREATION; 1416*9585STim.Szeto@Sun.COM break; 1417*9585STim.Szeto@Sun.COM case SBD_RET_INVALID_BLKSIZE: 1418*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_INVALID_BLKSIZE; 1419*9585STim.Szeto@Sun.COM break; 1420*9585STim.Szeto@Sun.COM case SBD_RET_FILE_ALREADY_REGISTERED: 1421*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_IN_USE; 1422*9585STim.Szeto@Sun.COM break; 1423*9585STim.Szeto@Sun.COM case SBD_RET_GUID_ALREADY_REGISTERED: 1424*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_GUID_IN_USE; 1425*9585STim.Szeto@Sun.COM break; 1426*9585STim.Szeto@Sun.COM case SBD_RET_META_PATH_NOT_ABSOLUTE: 1427*9585STim.Szeto@Sun.COM case SBD_RET_META_FILE_LOOKUP_FAILED: 1428*9585STim.Szeto@Sun.COM case SBD_RET_META_FILE_OPEN_FAILED: 1429*9585STim.Szeto@Sun.COM case SBD_RET_META_FILE_GETATTR_FAILED: 1430*9585STim.Szeto@Sun.COM case SBD_RET_NO_META: 1431*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_FILE_NAME; 1432*9585STim.Szeto@Sun.COM break; 1433*9585STim.Szeto@Sun.COM case SBD_RET_DATA_PATH_NOT_ABSOLUTE: 1434*9585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_LOOKUP_FAILED: 1435*9585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_OPEN_FAILED: 1436*9585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_GETATTR_FAILED: 1437*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_DATA_FILE_NAME; 1438*9585STim.Szeto@Sun.COM break; 1439*9585STim.Szeto@Sun.COM case SBD_RET_FILE_SIZE_ERROR: 1440*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_SIZE_INVALID; 1441*9585STim.Szeto@Sun.COM break; 1442*9585STim.Szeto@Sun.COM case SBD_RET_SIZE_OUT_OF_RANGE: 1443*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_SIZE_OUT_OF_RANGE; 1444*9585STim.Szeto@Sun.COM break; 1445*9585STim.Szeto@Sun.COM case SBD_RET_LU_BUSY: 1446*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_LU_BUSY; 1447*9585STim.Szeto@Sun.COM break; 1448*9585STim.Szeto@Sun.COM case SBD_RET_WRITE_CACHE_SET_FAILED: 1449*9585STim.Szeto@Sun.COM *ret = STMF_ERROR_WRITE_CACHE_SET; 1450*9585STim.Szeto@Sun.COM break; 1451*9585STim.Szeto@Sun.COM default: 1452*9585STim.Szeto@Sun.COM *ret = STMF_STATUS_ERROR; 1453*9585STim.Szeto@Sun.COM break; 1454*9585STim.Szeto@Sun.COM } 1455*9585STim.Szeto@Sun.COM } 1456*9585STim.Szeto@Sun.COM 1457*9585STim.Szeto@Sun.COM /* 1458*9585STim.Szeto@Sun.COM * Creates a logical unit resource of type STMF_DISK. 1459*9585STim.Szeto@Sun.COM * 1460*9585STim.Szeto@Sun.COM * No defaults should be set here as all defaults are derived from the 1461*9585STim.Szeto@Sun.COM * driver's default settings. 1462*9585STim.Szeto@Sun.COM */ 1463*9585STim.Szeto@Sun.COM static int 1464*9585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl) 1465*9585STim.Szeto@Sun.COM { 1466*9585STim.Szeto@Sun.COM hdl->type = STMF_DISK; 1467*9585STim.Szeto@Sun.COM 1468*9585STim.Szeto@Sun.COM hdl->resource = calloc(1, sizeof (diskResource)); 1469*9585STim.Szeto@Sun.COM if (hdl->resource == NULL) { 1470*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 1471*9585STim.Szeto@Sun.COM } 1472*9585STim.Szeto@Sun.COM 1473*9585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 1474*9585STim.Szeto@Sun.COM } 1475*9585STim.Szeto@Sun.COM 1476*9585STim.Szeto@Sun.COM /* 1477*9585STim.Szeto@Sun.COM * stmfDeleteLu 1478*9585STim.Szeto@Sun.COM * 1479*9585STim.Szeto@Sun.COM * Purpose: Delete a logical unit 1480*9585STim.Szeto@Sun.COM * 1481*9585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 1482*9585STim.Szeto@Sun.COM * 1483*9585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 1484*9585STim.Szeto@Sun.COM * unit 1485*9585STim.Szeto@Sun.COM */ 1486*9585STim.Szeto@Sun.COM int 1487*9585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid) 1488*9585STim.Szeto@Sun.COM { 1489*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1490*9585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 1491*9585STim.Szeto@Sun.COM 1492*9585STim.Szeto@Sun.COM if (luGuid == NULL) { 1493*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1494*9585STim.Szeto@Sun.COM } 1495*9585STim.Szeto@Sun.COM 1496*9585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 1497*9585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 1498*9585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 1499*9585STim.Szeto@Sun.COM return (ret); 1500*9585STim.Szeto@Sun.COM } else { 1501*9585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 1502*9585STim.Szeto@Sun.COM ret = deleteDiskLu(luGuid); 1503*9585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 1504*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 1505*9585STim.Szeto@Sun.COM } else { 1506*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1507*9585STim.Szeto@Sun.COM } 1508*9585STim.Szeto@Sun.COM } 1509*9585STim.Szeto@Sun.COM 1510*9585STim.Szeto@Sun.COM return (ret); 1511*9585STim.Szeto@Sun.COM } 1512*9585STim.Szeto@Sun.COM 1513*9585STim.Szeto@Sun.COM static int 1514*9585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid) 1515*9585STim.Szeto@Sun.COM { 1516*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1517*9585STim.Szeto@Sun.COM int fd; 1518*9585STim.Szeto@Sun.COM int savedErrno; 1519*9585STim.Szeto@Sun.COM int ioctlRet; 1520*9585STim.Szeto@Sun.COM sbd_delete_lu_t deleteLu = {0}; 1521*9585STim.Szeto@Sun.COM 1522*9585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 1523*9585STim.Szeto@Sun.COM 1524*9585STim.Szeto@Sun.COM /* 1525*9585STim.Szeto@Sun.COM * Open control node for sbd 1526*9585STim.Szeto@Sun.COM */ 1527*9585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 1528*9585STim.Szeto@Sun.COM return (ret); 1529*9585STim.Szeto@Sun.COM 1530*9585STim.Szeto@Sun.COM ret = removeGuidFromDiskStore(luGuid); 1531*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1532*9585STim.Szeto@Sun.COM goto done; 1533*9585STim.Szeto@Sun.COM } 1534*9585STim.Szeto@Sun.COM 1535*9585STim.Szeto@Sun.COM bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid)); 1536*9585STim.Szeto@Sun.COM deleteLu.dlu_by_guid = 1; 1537*9585STim.Szeto@Sun.COM 1538*9585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 1539*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (deleteLu); 1540*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu; 1541*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl); 1542*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 1543*9585STim.Szeto@Sun.COM savedErrno = errno; 1544*9585STim.Szeto@Sun.COM switch (savedErrno) { 1545*9585STim.Szeto@Sun.COM case EBUSY: 1546*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1547*9585STim.Szeto@Sun.COM break; 1548*9585STim.Szeto@Sun.COM case EPERM: 1549*9585STim.Szeto@Sun.COM case EACCES: 1550*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1551*9585STim.Szeto@Sun.COM break; 1552*9585STim.Szeto@Sun.COM case ENOENT: 1553*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 1554*9585STim.Szeto@Sun.COM break; 1555*9585STim.Szeto@Sun.COM default: 1556*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1557*9585STim.Szeto@Sun.COM "deleteDiskLu:ioctl error(%d) (%d) (%d)", 1558*9585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 1559*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 1560*9585STim.Szeto@Sun.COM break; 1561*9585STim.Szeto@Sun.COM } 1562*9585STim.Szeto@Sun.COM } 1563*9585STim.Szeto@Sun.COM 1564*9585STim.Szeto@Sun.COM done: 1565*9585STim.Szeto@Sun.COM (void) close(fd); 1566*9585STim.Szeto@Sun.COM return (ret); 1567*9585STim.Szeto@Sun.COM } 1568*9585STim.Szeto@Sun.COM 1569*9585STim.Szeto@Sun.COM /* 1570*9585STim.Szeto@Sun.COM * stmfModifyLu 1571*9585STim.Szeto@Sun.COM * 1572*9585STim.Szeto@Sun.COM * Purpose: Modify properties of a logical unit 1573*9585STim.Szeto@Sun.COM * 1574*9585STim.Szeto@Sun.COM * luGuid - guid of registered logical unit 1575*9585STim.Szeto@Sun.COM * prop - property to modify 1576*9585STim.Szeto@Sun.COM * propVal - property value to set 1577*9585STim.Szeto@Sun.COM * 1578*9585STim.Szeto@Sun.COM */ 1579*9585STim.Szeto@Sun.COM int 1580*9585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal) 1581*9585STim.Szeto@Sun.COM { 1582*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1583*9585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 1584*9585STim.Szeto@Sun.COM 1585*9585STim.Szeto@Sun.COM if (luGuid == NULL) { 1586*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1587*9585STim.Szeto@Sun.COM } 1588*9585STim.Szeto@Sun.COM 1589*9585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 1590*9585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 1591*9585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 1592*9585STim.Szeto@Sun.COM return (ret); 1593*9585STim.Szeto@Sun.COM } else { 1594*9585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 1595*9585STim.Szeto@Sun.COM ret = modifyDiskLuProp(luGuid, NULL, prop, propVal); 1596*9585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 1597*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 1598*9585STim.Szeto@Sun.COM } else { 1599*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1600*9585STim.Szeto@Sun.COM } 1601*9585STim.Szeto@Sun.COM } 1602*9585STim.Szeto@Sun.COM 1603*9585STim.Szeto@Sun.COM return (ret); 1604*9585STim.Szeto@Sun.COM } 1605*9585STim.Szeto@Sun.COM 1606*9585STim.Szeto@Sun.COM /* 1607*9585STim.Szeto@Sun.COM * stmfModifyLuByFname 1608*9585STim.Szeto@Sun.COM * 1609*9585STim.Szeto@Sun.COM * Purpose: Modify a device by filename. Device does not need to be registered. 1610*9585STim.Szeto@Sun.COM * 1611*9585STim.Szeto@Sun.COM * dType - type of device to modify 1612*9585STim.Szeto@Sun.COM * STMF_DISK 1613*9585STim.Szeto@Sun.COM * 1614*9585STim.Szeto@Sun.COM * fname - filename or meta filename 1615*9585STim.Szeto@Sun.COM * prop - valid property identifier 1616*9585STim.Szeto@Sun.COM * propVal - property value 1617*9585STim.Szeto@Sun.COM * 1618*9585STim.Szeto@Sun.COM */ 1619*9585STim.Szeto@Sun.COM int 1620*9585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop, 1621*9585STim.Szeto@Sun.COM const char *propVal) 1622*9585STim.Szeto@Sun.COM { 1623*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1624*9585STim.Szeto@Sun.COM if (fname == NULL) { 1625*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1626*9585STim.Szeto@Sun.COM } 1627*9585STim.Szeto@Sun.COM 1628*9585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 1629*9585STim.Szeto@Sun.COM ret = modifyDiskLuProp(NULL, fname, prop, propVal); 1630*9585STim.Szeto@Sun.COM } else { 1631*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1632*9585STim.Szeto@Sun.COM } 1633*9585STim.Szeto@Sun.COM 1634*9585STim.Szeto@Sun.COM return (ret); 1635*9585STim.Szeto@Sun.COM } 1636*9585STim.Szeto@Sun.COM 1637*9585STim.Szeto@Sun.COM static int 1638*9585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop, 1639*9585STim.Szeto@Sun.COM const char *propVal) 1640*9585STim.Szeto@Sun.COM { 1641*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1642*9585STim.Szeto@Sun.COM luResource hdl = NULL; 1643*9585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl; 1644*9585STim.Szeto@Sun.COM 1645*9585STim.Szeto@Sun.COM ret = stmfCreateLuResource(STMF_DISK, &hdl); 1646*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1647*9585STim.Szeto@Sun.COM return (ret); 1648*9585STim.Szeto@Sun.COM } 1649*9585STim.Szeto@Sun.COM ret = validateModifyDiskProp(prop); 1650*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1651*9585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 1652*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROP); 1653*9585STim.Szeto@Sun.COM } 1654*9585STim.Szeto@Sun.COM ret = stmfSetLuProp(hdl, prop, propVal); 1655*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1656*9585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 1657*9585STim.Szeto@Sun.COM return (ret); 1658*9585STim.Szeto@Sun.COM } 1659*9585STim.Szeto@Sun.COM luPropsHdl = hdl; 1660*9585STim.Szeto@Sun.COM ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname); 1661*9585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 1662*9585STim.Szeto@Sun.COM return (ret); 1663*9585STim.Szeto@Sun.COM } 1664*9585STim.Szeto@Sun.COM 1665*9585STim.Szeto@Sun.COM static int 1666*9585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop) 1667*9585STim.Szeto@Sun.COM { 1668*9585STim.Szeto@Sun.COM switch (prop) { 1669*9585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 1670*9585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 1671*9585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 1672*9585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 1673*9585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 1674*9585STim.Szeto@Sun.COM break; 1675*9585STim.Szeto@Sun.COM default: 1676*9585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 1677*9585STim.Szeto@Sun.COM break; 1678*9585STim.Szeto@Sun.COM } 1679*9585STim.Szeto@Sun.COM } 1680*9585STim.Szeto@Sun.COM 1681*9585STim.Szeto@Sun.COM static int 1682*9585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname) 1683*9585STim.Szeto@Sun.COM { 1684*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1685*9585STim.Szeto@Sun.COM int luAliasLen = 0; 1686*9585STim.Szeto@Sun.COM int mluBufSize = 0; 1687*9585STim.Szeto@Sun.COM int bufOffset = 0; 1688*9585STim.Szeto@Sun.COM int fd = 0; 1689*9585STim.Szeto@Sun.COM int ioctlRet; 1690*9585STim.Szeto@Sun.COM int savedErrno; 1691*9585STim.Szeto@Sun.COM int fnameSize = 0; 1692*9585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 1693*9585STim.Szeto@Sun.COM 1694*9585STim.Szeto@Sun.COM sbd_modify_lu_t *sbdLu = NULL; 1695*9585STim.Szeto@Sun.COM 1696*9585STim.Szeto@Sun.COM if (luGuid == NULL && fname == NULL) { 1697*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1698*9585STim.Szeto@Sun.COM } 1699*9585STim.Szeto@Sun.COM 1700*9585STim.Szeto@Sun.COM if (fname) { 1701*9585STim.Szeto@Sun.COM fnameSize = strlen(fname) + 1; 1702*9585STim.Szeto@Sun.COM mluBufSize += fnameSize; 1703*9585STim.Szeto@Sun.COM } 1704*9585STim.Szeto@Sun.COM 1705*9585STim.Szeto@Sun.COM /* 1706*9585STim.Szeto@Sun.COM * Open control node for sbd 1707*9585STim.Szeto@Sun.COM */ 1708*9585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 1709*9585STim.Szeto@Sun.COM return (ret); 1710*9585STim.Szeto@Sun.COM 1711*9585STim.Szeto@Sun.COM if (disk->luAliasValid) { 1712*9585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 1713*9585STim.Szeto@Sun.COM mluBufSize += luAliasLen + 1; 1714*9585STim.Szeto@Sun.COM } 1715*9585STim.Szeto@Sun.COM 1716*9585STim.Szeto@Sun.COM /* 1717*9585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 1718*9585STim.Szeto@Sun.COM * concatenation of variable length fields 1719*9585STim.Szeto@Sun.COM */ 1720*9585STim.Szeto@Sun.COM sbdLu = (sbd_modify_lu_t *)calloc(1, 1721*9585STim.Szeto@Sun.COM sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize); 1722*9585STim.Szeto@Sun.COM if (sbdLu == NULL) { 1723*9585STim.Szeto@Sun.COM (void) close(fd); 1724*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 1725*9585STim.Szeto@Sun.COM } 1726*9585STim.Szeto@Sun.COM 1727*9585STim.Szeto@Sun.COM sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) + 1728*9585STim.Szeto@Sun.COM mluBufSize - 8 + fnameSize; 1729*9585STim.Szeto@Sun.COM 1730*9585STim.Szeto@Sun.COM if (disk->luAliasValid) { 1731*9585STim.Szeto@Sun.COM sbdLu->mlu_alias_valid = 1; 1732*9585STim.Szeto@Sun.COM sbdLu->mlu_alias_off = bufOffset; 1733*9585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]), 1734*9585STim.Szeto@Sun.COM luAliasLen + 1); 1735*9585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 1736*9585STim.Szeto@Sun.COM } 1737*9585STim.Szeto@Sun.COM 1738*9585STim.Szeto@Sun.COM if (disk->luSizeValid) { 1739*9585STim.Szeto@Sun.COM sbdLu->mlu_lu_size_valid = 1; 1740*9585STim.Szeto@Sun.COM sbdLu->mlu_lu_size = disk->luSize; 1741*9585STim.Szeto@Sun.COM } 1742*9585STim.Szeto@Sun.COM 1743*9585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 1744*9585STim.Szeto@Sun.COM sbdLu->mlu_write_protected_valid = 1; 1745*9585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 1746*9585STim.Szeto@Sun.COM sbdLu->mlu_write_protected = 1; 1747*9585STim.Szeto@Sun.COM } 1748*9585STim.Szeto@Sun.COM } 1749*9585STim.Szeto@Sun.COM 1750*9585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 1751*9585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable_valid = 1; 1752*9585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 1753*9585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable = 1; 1754*9585STim.Szeto@Sun.COM } 1755*9585STim.Szeto@Sun.COM } 1756*9585STim.Szeto@Sun.COM 1757*9585STim.Szeto@Sun.COM if (luGuid) { 1758*9585STim.Szeto@Sun.COM bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid)); 1759*9585STim.Szeto@Sun.COM sbdLu->mlu_by_guid = 1; 1760*9585STim.Szeto@Sun.COM } else { 1761*9585STim.Szeto@Sun.COM sbdLu->mlu_fname_off = bufOffset; 1762*9585STim.Szeto@Sun.COM bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1); 1763*9585STim.Szeto@Sun.COM sbdLu->mlu_by_fname = 1; 1764*9585STim.Szeto@Sun.COM } 1765*9585STim.Szeto@Sun.COM 1766*9585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 1767*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size; 1768*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 1769*9585STim.Szeto@Sun.COM 1770*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl); 1771*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 1772*9585STim.Szeto@Sun.COM savedErrno = errno; 1773*9585STim.Szeto@Sun.COM switch (savedErrno) { 1774*9585STim.Szeto@Sun.COM case EBUSY: 1775*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1776*9585STim.Szeto@Sun.COM break; 1777*9585STim.Szeto@Sun.COM case EPERM: 1778*9585STim.Szeto@Sun.COM case EACCES: 1779*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1780*9585STim.Szeto@Sun.COM break; 1781*9585STim.Szeto@Sun.COM default: 1782*9585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 1783*9585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 1784*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1785*9585STim.Szeto@Sun.COM "modifyDiskLu:ioctl " 1786*9585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 1787*9585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 1788*9585STim.Szeto@Sun.COM } 1789*9585STim.Szeto@Sun.COM break; 1790*9585STim.Szeto@Sun.COM } 1791*9585STim.Szeto@Sun.COM } 1792*9585STim.Szeto@Sun.COM 1793*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 1794*9585STim.Szeto@Sun.COM goto done; 1795*9585STim.Szeto@Sun.COM } 1796*9585STim.Szeto@Sun.COM 1797*9585STim.Szeto@Sun.COM done: 1798*9585STim.Szeto@Sun.COM free(sbdLu); 1799*9585STim.Szeto@Sun.COM (void) close(fd); 1800*9585STim.Szeto@Sun.COM return (ret); 1801*9585STim.Szeto@Sun.COM } 1802*9585STim.Szeto@Sun.COM 1803*9585STim.Szeto@Sun.COM /* 1804*9585STim.Szeto@Sun.COM * removeGuidFromDiskStore 1805*9585STim.Szeto@Sun.COM * 1806*9585STim.Szeto@Sun.COM * Purpose: delete a logical unit from the sbd provider data 1807*9585STim.Szeto@Sun.COM */ 1808*9585STim.Szeto@Sun.COM static int 1809*9585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid) 1810*9585STim.Szeto@Sun.COM { 1811*9585STim.Szeto@Sun.COM return (persistDiskGuid(guid, NULL, B_FALSE)); 1812*9585STim.Szeto@Sun.COM } 1813*9585STim.Szeto@Sun.COM 1814*9585STim.Szeto@Sun.COM 1815*9585STim.Szeto@Sun.COM /* 1816*9585STim.Szeto@Sun.COM * addGuidToDiskStore 1817*9585STim.Szeto@Sun.COM * 1818*9585STim.Szeto@Sun.COM * Purpose: add a logical unit to the sbd provider data 1819*9585STim.Szeto@Sun.COM */ 1820*9585STim.Szeto@Sun.COM static int 1821*9585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename) 1822*9585STim.Szeto@Sun.COM { 1823*9585STim.Szeto@Sun.COM return (persistDiskGuid(guid, filename, B_TRUE)); 1824*9585STim.Szeto@Sun.COM } 1825*9585STim.Szeto@Sun.COM 1826*9585STim.Szeto@Sun.COM 1827*9585STim.Szeto@Sun.COM /* 1828*9585STim.Szeto@Sun.COM * persistDiskGuid 1829*9585STim.Szeto@Sun.COM * 1830*9585STim.Szeto@Sun.COM * Purpose: Persist or unpersist a guid for the sbd provider data 1831*9585STim.Szeto@Sun.COM * 1832*9585STim.Szeto@Sun.COM */ 1833*9585STim.Szeto@Sun.COM static int 1834*9585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist) 1835*9585STim.Szeto@Sun.COM { 1836*9585STim.Szeto@Sun.COM char guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0}; 1837*9585STim.Szeto@Sun.COM nvlist_t *nvl = NULL; 1838*9585STim.Szeto@Sun.COM 1839*9585STim.Szeto@Sun.COM uint64_t setToken; 1840*9585STim.Szeto@Sun.COM boolean_t retryGetProviderData = B_FALSE; 1841*9585STim.Szeto@Sun.COM boolean_t newData = B_FALSE; 1842*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1843*9585STim.Szeto@Sun.COM int retryCnt = 0; 1844*9585STim.Szeto@Sun.COM int stmfRet; 1845*9585STim.Szeto@Sun.COM 1846*9585STim.Szeto@Sun.COM /* if we're persisting a guid, there must be a filename */ 1847*9585STim.Szeto@Sun.COM if (persist && !filename) { 1848*9585STim.Szeto@Sun.COM return (1); 1849*9585STim.Szeto@Sun.COM } 1850*9585STim.Szeto@Sun.COM 1851*9585STim.Szeto@Sun.COM /* guid is stored in lowercase ascii hex */ 1852*9585STim.Szeto@Sun.COM (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 1853*9585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" 1854*9585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x", 1855*9585STim.Szeto@Sun.COM guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3], 1856*9585STim.Szeto@Sun.COM guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7], 1857*9585STim.Szeto@Sun.COM guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11], 1858*9585STim.Szeto@Sun.COM guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]); 1859*9585STim.Szeto@Sun.COM 1860*9585STim.Szeto@Sun.COM 1861*9585STim.Szeto@Sun.COM do { 1862*9585STim.Szeto@Sun.COM retryGetProviderData = B_FALSE; 1863*9585STim.Szeto@Sun.COM stmfRet = stmfGetProviderDataProt("sbd", &nvl, 1864*9585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 1865*9585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 1866*9585STim.Szeto@Sun.COM if (persist && stmfRet == STMF_ERROR_NOT_FOUND) { 1867*9585STim.Szeto@Sun.COM ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); 1868*9585STim.Szeto@Sun.COM if (ret != 0) { 1869*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1870*9585STim.Szeto@Sun.COM "unpersistGuid:nvlist_alloc(%d)", 1871*9585STim.Szeto@Sun.COM ret); 1872*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 1873*9585STim.Szeto@Sun.COM goto done; 1874*9585STim.Szeto@Sun.COM } 1875*9585STim.Szeto@Sun.COM newData = B_TRUE; 1876*9585STim.Szeto@Sun.COM } else { 1877*9585STim.Szeto@Sun.COM ret = stmfRet; 1878*9585STim.Szeto@Sun.COM goto done; 1879*9585STim.Szeto@Sun.COM } 1880*9585STim.Szeto@Sun.COM } 1881*9585STim.Szeto@Sun.COM if (persist) { 1882*9585STim.Szeto@Sun.COM ret = nvlist_add_string(nvl, guidAsciiBuf, filename); 1883*9585STim.Szeto@Sun.COM } else { 1884*9585STim.Szeto@Sun.COM ret = nvlist_remove(nvl, guidAsciiBuf, 1885*9585STim.Szeto@Sun.COM DATA_TYPE_STRING); 1886*9585STim.Szeto@Sun.COM if (ret == ENOENT) { 1887*9585STim.Szeto@Sun.COM ret = 0; 1888*9585STim.Szeto@Sun.COM } 1889*9585STim.Szeto@Sun.COM } 1890*9585STim.Szeto@Sun.COM if (ret == 0) { 1891*9585STim.Szeto@Sun.COM if (newData) { 1892*9585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 1893*9585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, NULL); 1894*9585STim.Szeto@Sun.COM } else { 1895*9585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 1896*9585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 1897*9585STim.Szeto@Sun.COM } 1898*9585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 1899*9585STim.Szeto@Sun.COM if (stmfRet == STMF_ERROR_BUSY) { 1900*9585STim.Szeto@Sun.COM /* get/set failed, try again */ 1901*9585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 1902*9585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 1903*9585STim.Szeto@Sun.COM ret = stmfRet; 1904*9585STim.Szeto@Sun.COM break; 1905*9585STim.Szeto@Sun.COM } 1906*9585STim.Szeto@Sun.COM continue; 1907*9585STim.Szeto@Sun.COM } else if (stmfRet == 1908*9585STim.Szeto@Sun.COM STMF_ERROR_PROV_DATA_STALE) { 1909*9585STim.Szeto@Sun.COM /* update failed, try again */ 1910*9585STim.Szeto@Sun.COM nvlist_free(nvl); 1911*9585STim.Szeto@Sun.COM nvl = NULL; 1912*9585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 1913*9585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 1914*9585STim.Szeto@Sun.COM ret = stmfRet; 1915*9585STim.Szeto@Sun.COM break; 1916*9585STim.Szeto@Sun.COM } 1917*9585STim.Szeto@Sun.COM continue; 1918*9585STim.Szeto@Sun.COM } else { 1919*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1920*9585STim.Szeto@Sun.COM "unpersistGuid:error(%x)", stmfRet); 1921*9585STim.Szeto@Sun.COM ret = stmfRet; 1922*9585STim.Szeto@Sun.COM } 1923*9585STim.Szeto@Sun.COM break; 1924*9585STim.Szeto@Sun.COM } 1925*9585STim.Szeto@Sun.COM } else { 1926*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 1927*9585STim.Szeto@Sun.COM "unpersistGuid:error nvlist_add/remove(%d)", 1928*9585STim.Szeto@Sun.COM ret); 1929*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 1930*9585STim.Szeto@Sun.COM } 1931*9585STim.Szeto@Sun.COM } while (retryGetProviderData); 1932*9585STim.Szeto@Sun.COM 1933*9585STim.Szeto@Sun.COM done: 1934*9585STim.Szeto@Sun.COM nvlist_free(nvl); 1935*9585STim.Szeto@Sun.COM return (ret); 1936*9585STim.Szeto@Sun.COM } 1937*9585STim.Szeto@Sun.COM 1938*9585STim.Szeto@Sun.COM 1939*9585STim.Szeto@Sun.COM /* 1940*9585STim.Szeto@Sun.COM * stmfGetLuProp 1941*9585STim.Szeto@Sun.COM * 1942*9585STim.Szeto@Sun.COM * Purpose: Get current value for a resource property 1943*9585STim.Szeto@Sun.COM * 1944*9585STim.Szeto@Sun.COM * hdl - luResource from a previous call to stmfCreateLuResource 1945*9585STim.Szeto@Sun.COM * 1946*9585STim.Szeto@Sun.COM * resourceProp - a valid resource property type 1947*9585STim.Szeto@Sun.COM * 1948*9585STim.Szeto@Sun.COM * propVal - void pointer to a pointer of the value to be retrieved 1949*9585STim.Szeto@Sun.COM */ 1950*9585STim.Szeto@Sun.COM int 1951*9585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen) 1952*9585STim.Szeto@Sun.COM { 1953*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1954*9585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 1955*9585STim.Szeto@Sun.COM if (hdl == NULL || propLen == NULL || propVal == NULL) { 1956*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1957*9585STim.Szeto@Sun.COM } 1958*9585STim.Szeto@Sun.COM 1959*9585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 1960*9585STim.Szeto@Sun.COM ret = getDiskProp(luPropsHdl, prop, propVal, propLen); 1961*9585STim.Szeto@Sun.COM } else { 1962*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1963*9585STim.Szeto@Sun.COM } 1964*9585STim.Szeto@Sun.COM 1965*9585STim.Szeto@Sun.COM return (ret); 1966*9585STim.Szeto@Sun.COM } 1967*9585STim.Szeto@Sun.COM 1968*9585STim.Szeto@Sun.COM /* 1969*9585STim.Szeto@Sun.COM * stmfGetLuResource 1970*9585STim.Szeto@Sun.COM * 1971*9585STim.Szeto@Sun.COM * Purpose: Get a logical unit resource handle for a given logical unit. 1972*9585STim.Szeto@Sun.COM * 1973*9585STim.Szeto@Sun.COM * hdl - pointer to luResource 1974*9585STim.Szeto@Sun.COM */ 1975*9585STim.Szeto@Sun.COM int 1976*9585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl) 1977*9585STim.Szeto@Sun.COM { 1978*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 1979*9585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 1980*9585STim.Szeto@Sun.COM 1981*9585STim.Szeto@Sun.COM 1982*9585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 1983*9585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 1984*9585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 1985*9585STim.Szeto@Sun.COM return (ret); 1986*9585STim.Szeto@Sun.COM } else { 1987*9585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 1988*9585STim.Szeto@Sun.COM ret = getDiskAllProps(luGuid, hdl); 1989*9585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 1990*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 1991*9585STim.Szeto@Sun.COM } else { 1992*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 1993*9585STim.Szeto@Sun.COM } 1994*9585STim.Szeto@Sun.COM } 1995*9585STim.Szeto@Sun.COM 1996*9585STim.Szeto@Sun.COM return (ret); 1997*9585STim.Szeto@Sun.COM } 1998*9585STim.Szeto@Sun.COM 1999*9585STim.Szeto@Sun.COM /* 2000*9585STim.Szeto@Sun.COM * getDiskAllProps 2001*9585STim.Szeto@Sun.COM * 2002*9585STim.Szeto@Sun.COM * Purpose: load all disk properties from sbd driver 2003*9585STim.Szeto@Sun.COM * 2004*9585STim.Szeto@Sun.COM * luGuid - guid of disk device for which properties are to be retrieved 2005*9585STim.Szeto@Sun.COM * hdl - allocated luResource into which properties are to be copied 2006*9585STim.Szeto@Sun.COM * 2007*9585STim.Szeto@Sun.COM */ 2008*9585STim.Szeto@Sun.COM static int 2009*9585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl) 2010*9585STim.Szeto@Sun.COM { 2011*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 2012*9585STim.Szeto@Sun.COM int fd; 2013*9585STim.Szeto@Sun.COM sbd_lu_props_t *sbdProps; 2014*9585STim.Szeto@Sun.COM int ioctlRet; 2015*9585STim.Szeto@Sun.COM int savedErrno; 2016*9585STim.Szeto@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 2017*9585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 2018*9585STim.Szeto@Sun.COM 2019*9585STim.Szeto@Sun.COM /* 2020*9585STim.Szeto@Sun.COM * Open control node for sbd 2021*9585STim.Szeto@Sun.COM */ 2022*9585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 2023*9585STim.Szeto@Sun.COM return (ret); 2024*9585STim.Szeto@Sun.COM 2025*9585STim.Szeto@Sun.COM 2026*9585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 2027*9585STim.Szeto@Sun.COM if (*hdl == NULL) { 2028*9585STim.Szeto@Sun.COM (void) close(fd); 2029*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 2030*9585STim.Szeto@Sun.COM } 2031*9585STim.Szeto@Sun.COM 2032*9585STim.Szeto@Sun.COM sbdProps = calloc(1, sbdPropsSize); 2033*9585STim.Szeto@Sun.COM if (sbdProps == NULL) { 2034*9585STim.Szeto@Sun.COM free(*hdl); 2035*9585STim.Szeto@Sun.COM (void) close(fd); 2036*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 2037*9585STim.Szeto@Sun.COM } 2038*9585STim.Szeto@Sun.COM 2039*9585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 2040*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2041*9585STim.Szeto@Sun.COM free(*hdl); 2042*9585STim.Szeto@Sun.COM (void) close(fd); 2043*9585STim.Szeto@Sun.COM return (ret); 2044*9585STim.Szeto@Sun.COM } 2045*9585STim.Szeto@Sun.COM 2046*9585STim.Szeto@Sun.COM sbdProps->slp_input_guid = 1; 2047*9585STim.Szeto@Sun.COM bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid)); 2048*9585STim.Szeto@Sun.COM 2049*9585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 2050*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdPropsSize; 2051*9585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps; 2052*9585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 2053*9585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 2054*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl); 2055*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 2056*9585STim.Szeto@Sun.COM savedErrno = errno; 2057*9585STim.Szeto@Sun.COM switch (savedErrno) { 2058*9585STim.Szeto@Sun.COM case EBUSY: 2059*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 2060*9585STim.Szeto@Sun.COM break; 2061*9585STim.Szeto@Sun.COM case EPERM: 2062*9585STim.Szeto@Sun.COM case EACCES: 2063*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 2064*9585STim.Szeto@Sun.COM break; 2065*9585STim.Szeto@Sun.COM case ENOENT: 2066*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 2067*9585STim.Szeto@Sun.COM break; 2068*9585STim.Szeto@Sun.COM default: 2069*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 2070*9585STim.Szeto@Sun.COM "getDiskAllProps:ioctl error(%d) (%d) (%d)", 2071*9585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 2072*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 2073*9585STim.Szeto@Sun.COM break; 2074*9585STim.Szeto@Sun.COM } 2075*9585STim.Szeto@Sun.COM } 2076*9585STim.Szeto@Sun.COM 2077*9585STim.Szeto@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 2078*9585STim.Szeto@Sun.COM ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps); 2079*9585STim.Szeto@Sun.COM } 2080*9585STim.Szeto@Sun.COM 2081*9585STim.Szeto@Sun.COM (void) close(fd); 2082*9585STim.Szeto@Sun.COM return (ret); 2083*9585STim.Szeto@Sun.COM } 2084*9585STim.Szeto@Sun.COM 2085*9585STim.Szeto@Sun.COM /* 2086*9585STim.Szeto@Sun.COM * loadDiskPropsFromDriver 2087*9585STim.Szeto@Sun.COM * 2088*9585STim.Szeto@Sun.COM * Purpose: Retrieve all disk type properties from sbd driver 2089*9585STim.Szeto@Sun.COM * 2090*9585STim.Szeto@Sun.COM * hdl - Allocated luResourceImpl 2091*9585STim.Szeto@Sun.COM * sbdProps - sbd_lu_props_t structure returned from sbd driver 2092*9585STim.Szeto@Sun.COM * 2093*9585STim.Szeto@Sun.COM */ 2094*9585STim.Szeto@Sun.COM static int 2095*9585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps) 2096*9585STim.Szeto@Sun.COM { 2097*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 2098*9585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 2099*9585STim.Szeto@Sun.COM /* copy guid */ 2100*9585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 2101*9585STim.Szeto@Sun.COM bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid)); 2102*9585STim.Szeto@Sun.COM 2103*9585STim.Szeto@Sun.COM if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) { 2104*9585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 2105*9585STim.Szeto@Sun.COM if (strlcpy(diskLu->luMetaFileName, 2106*9585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]), 2107*9585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) >= 2108*9585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 2109*9585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 2110*9585STim.Szeto@Sun.COM } 2111*9585STim.Szeto@Sun.COM } 2112*9585STim.Szeto@Sun.COM 2113*9585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 2114*9585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 2115*9585STim.Szeto@Sun.COM if (strlcpy(diskLu->luDataFileName, 2116*9585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]), 2117*9585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) >= 2118*9585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 2119*9585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 2120*9585STim.Szeto@Sun.COM } 2121*9585STim.Szeto@Sun.COM } 2122*9585STim.Szeto@Sun.COM 2123*9585STim.Szeto@Sun.COM if (sbdProps->slp_serial_valid) { 2124*9585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 2125*9585STim.Szeto@Sun.COM bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]), 2126*9585STim.Szeto@Sun.COM diskLu->serialNum, sbdProps->slp_serial_size); 2127*9585STim.Szeto@Sun.COM } 2128*9585STim.Szeto@Sun.COM 2129*9585STim.Szeto@Sun.COM if (sbdProps->slp_alias_valid) { 2130*9585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 2131*9585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 2132*9585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]), 2133*9585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 2134*9585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 2135*9585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 2136*9585STim.Szeto@Sun.COM } 2137*9585STim.Szeto@Sun.COM } else { /* set alias to data filename if not set */ 2138*9585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 2139*9585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 2140*9585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 2141*9585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[ 2142*9585STim.Szeto@Sun.COM sbdProps->slp_data_fname_off]), 2143*9585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 2144*9585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 2145*9585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 2146*9585STim.Szeto@Sun.COM } 2147*9585STim.Szeto@Sun.COM } 2148*9585STim.Szeto@Sun.COM } 2149*9585STim.Szeto@Sun.COM 2150*9585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 2151*9585STim.Szeto@Sun.COM bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid)); 2152*9585STim.Szeto@Sun.COM 2153*9585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 2154*9585STim.Szeto@Sun.COM bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid)); 2155*9585STim.Szeto@Sun.COM 2156*9585STim.Szeto@Sun.COM diskLu->revValid = B_TRUE; 2157*9585STim.Szeto@Sun.COM bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev)); 2158*9585STim.Szeto@Sun.COM 2159*9585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 2160*9585STim.Szeto@Sun.COM if (sbdProps->slp_write_protected) { 2161*9585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 2162*9585STim.Szeto@Sun.COM } 2163*9585STim.Szeto@Sun.COM 2164*9585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 2165*9585STim.Szeto@Sun.COM if (sbdProps->slp_writeback_cache_disable_cur) { 2166*9585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 2167*9585STim.Szeto@Sun.COM } 2168*9585STim.Szeto@Sun.COM 2169*9585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 2170*9585STim.Szeto@Sun.COM diskLu->blkSize = sbdProps->slp_blksize; 2171*9585STim.Szeto@Sun.COM 2172*9585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 2173*9585STim.Szeto@Sun.COM diskLu->luSize = sbdProps->slp_lu_size; 2174*9585STim.Szeto@Sun.COM 2175*9585STim.Szeto@Sun.COM return (ret); 2176*9585STim.Szeto@Sun.COM } 2177*9585STim.Szeto@Sun.COM 2178*9585STim.Szeto@Sun.COM 2179*9585STim.Szeto@Sun.COM /* 2180*9585STim.Szeto@Sun.COM * stmfSetLuProp 2181*9585STim.Szeto@Sun.COM * 2182*9585STim.Szeto@Sun.COM * Purpose: set a property on an luResource 2183*9585STim.Szeto@Sun.COM * 2184*9585STim.Szeto@Sun.COM * hdl - allocated luResource 2185*9585STim.Szeto@Sun.COM * prop - property identifier 2186*9585STim.Szeto@Sun.COM * propVal - property value to be set 2187*9585STim.Szeto@Sun.COM */ 2188*9585STim.Szeto@Sun.COM int 2189*9585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal) 2190*9585STim.Szeto@Sun.COM { 2191*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 2192*9585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 2193*9585STim.Szeto@Sun.COM if (hdl == NULL) { 2194*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2195*9585STim.Szeto@Sun.COM } 2196*9585STim.Szeto@Sun.COM 2197*9585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 2198*9585STim.Szeto@Sun.COM ret = setDiskProp(luPropsHdl, prop, propVal); 2199*9585STim.Szeto@Sun.COM } else { 2200*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2201*9585STim.Szeto@Sun.COM } 2202*9585STim.Szeto@Sun.COM 2203*9585STim.Szeto@Sun.COM return (ret); 2204*9585STim.Szeto@Sun.COM } 2205*9585STim.Szeto@Sun.COM 2206*9585STim.Szeto@Sun.COM /* 2207*9585STim.Szeto@Sun.COM * getDiskProp 2208*9585STim.Szeto@Sun.COM * 2209*9585STim.Szeto@Sun.COM * Purpose: retrieve a given property from a logical unit resource of type disk 2210*9585STim.Szeto@Sun.COM * 2211*9585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 2212*9585STim.Szeto@Sun.COM * prop - property identifier 2213*9585STim.Szeto@Sun.COM * propVal - pointer to character to contain the retrieved property value 2214*9585STim.Szeto@Sun.COM * propLen - On input this is the length of propVal. On failure, it contains the 2215*9585STim.Szeto@Sun.COM * number of bytes required for propVal 2216*9585STim.Szeto@Sun.COM */ 2217*9585STim.Szeto@Sun.COM static int 2218*9585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen) 2219*9585STim.Szeto@Sun.COM { 2220*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 2221*9585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 2222*9585STim.Szeto@Sun.COM size_t reqLen; 2223*9585STim.Szeto@Sun.COM 2224*9585STim.Szeto@Sun.COM switch (prop) { 2225*9585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 2226*9585STim.Szeto@Sun.COM if (diskLu->blkSizeValid == B_FALSE) { 2227*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2228*9585STim.Szeto@Sun.COM } 2229*9585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, "%llu", 2230*9585STim.Szeto@Sun.COM (u_longlong_t)diskLu->blkSize); 2231*9585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 2232*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2233*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2234*9585STim.Szeto@Sun.COM } 2235*9585STim.Szeto@Sun.COM break; 2236*9585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 2237*9585STim.Szeto@Sun.COM if (diskLu->luDataFileNameValid == B_FALSE) { 2238*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2239*9585STim.Szeto@Sun.COM } 2240*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luDataFileName, 2241*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2242*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2243*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2244*9585STim.Szeto@Sun.COM } 2245*9585STim.Szeto@Sun.COM break; 2246*9585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 2247*9585STim.Szeto@Sun.COM if (diskLu->luMetaFileNameValid == B_FALSE) { 2248*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2249*9585STim.Szeto@Sun.COM } 2250*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName, 2251*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2252*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2253*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2254*9585STim.Szeto@Sun.COM } 2255*9585STim.Szeto@Sun.COM break; 2256*9585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 2257*9585STim.Szeto@Sun.COM if (diskLu->luGuidValid == B_FALSE) { 2258*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2259*9585STim.Szeto@Sun.COM } 2260*9585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, 2261*9585STim.Szeto@Sun.COM "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 2262*9585STim.Szeto@Sun.COM "%02X%02X%02X%02X", 2263*9585STim.Szeto@Sun.COM diskLu->luGuid[0], diskLu->luGuid[1], 2264*9585STim.Szeto@Sun.COM diskLu->luGuid[2], diskLu->luGuid[3], 2265*9585STim.Szeto@Sun.COM diskLu->luGuid[4], diskLu->luGuid[5], 2266*9585STim.Szeto@Sun.COM diskLu->luGuid[6], diskLu->luGuid[7], 2267*9585STim.Szeto@Sun.COM diskLu->luGuid[8], diskLu->luGuid[9], 2268*9585STim.Szeto@Sun.COM diskLu->luGuid[10], diskLu->luGuid[11], 2269*9585STim.Szeto@Sun.COM diskLu->luGuid[12], diskLu->luGuid[13], 2270*9585STim.Szeto@Sun.COM diskLu->luGuid[14], diskLu->luGuid[15]); 2271*9585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 2272*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2273*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2274*9585STim.Szeto@Sun.COM } 2275*9585STim.Szeto@Sun.COM break; 2276*9585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 2277*9585STim.Szeto@Sun.COM if (diskLu->serialNumValid == B_FALSE) { 2278*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2279*9585STim.Szeto@Sun.COM } 2280*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->serialNum, 2281*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2282*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2283*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2284*9585STim.Szeto@Sun.COM } 2285*9585STim.Szeto@Sun.COM break; 2286*9585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 2287*9585STim.Szeto@Sun.COM if (diskLu->luSizeValid == B_FALSE) { 2288*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2289*9585STim.Szeto@Sun.COM } 2290*9585STim.Szeto@Sun.COM (void) snprintf(propVal, *propLen, "%llu", 2291*9585STim.Szeto@Sun.COM (u_longlong_t)diskLu->luSize); 2292*9585STim.Szeto@Sun.COM break; 2293*9585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 2294*9585STim.Szeto@Sun.COM if (diskLu->luAliasValid == B_FALSE) { 2295*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2296*9585STim.Szeto@Sun.COM } 2297*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luAlias, 2298*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2299*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2300*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2301*9585STim.Szeto@Sun.COM } 2302*9585STim.Szeto@Sun.COM break; 2303*9585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 2304*9585STim.Szeto@Sun.COM if (diskLu->vidValid == B_FALSE) { 2305*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2306*9585STim.Szeto@Sun.COM } 2307*9585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->vid)) { 2308*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2309*9585STim.Szeto@Sun.COM } 2310*9585STim.Szeto@Sun.COM bcopy(diskLu->vid, propVal, sizeof (diskLu->vid)); 2311*9585STim.Szeto@Sun.COM propVal[sizeof (diskLu->vid)] = 0; 2312*9585STim.Szeto@Sun.COM break; 2313*9585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 2314*9585STim.Szeto@Sun.COM if (diskLu->pidValid == B_FALSE) { 2315*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2316*9585STim.Szeto@Sun.COM } 2317*9585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->pid)) { 2318*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2319*9585STim.Szeto@Sun.COM } 2320*9585STim.Szeto@Sun.COM bcopy(diskLu->pid, propVal, sizeof (diskLu->pid)); 2321*9585STim.Szeto@Sun.COM propVal[sizeof (diskLu->pid)] = 0; 2322*9585STim.Szeto@Sun.COM break; 2323*9585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 2324*9585STim.Szeto@Sun.COM if (diskLu->writeProtectEnableValid == B_FALSE) { 2325*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2326*9585STim.Szeto@Sun.COM } 2327*9585STim.Szeto@Sun.COM if (diskLu->writeProtectEnable) { 2328*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 2329*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2330*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2331*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2332*9585STim.Szeto@Sun.COM } 2333*9585STim.Szeto@Sun.COM } else { 2334*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 2335*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2336*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2337*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2338*9585STim.Szeto@Sun.COM } 2339*9585STim.Szeto@Sun.COM } 2340*9585STim.Szeto@Sun.COM break; 2341*9585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 2342*9585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisableValid == B_FALSE) { 2343*9585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 2344*9585STim.Szeto@Sun.COM } 2345*9585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisable) { 2346*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 2347*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2348*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2349*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2350*9585STim.Szeto@Sun.COM } 2351*9585STim.Szeto@Sun.COM } else { 2352*9585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 2353*9585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 2354*9585STim.Szeto@Sun.COM *propLen = reqLen + 1; 2355*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2356*9585STim.Szeto@Sun.COM } 2357*9585STim.Szeto@Sun.COM } 2358*9585STim.Szeto@Sun.COM break; 2359*9585STim.Szeto@Sun.COM default: 2360*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 2361*9585STim.Szeto@Sun.COM break; 2362*9585STim.Szeto@Sun.COM } 2363*9585STim.Szeto@Sun.COM 2364*9585STim.Szeto@Sun.COM return (ret); 2365*9585STim.Szeto@Sun.COM } 2366*9585STim.Szeto@Sun.COM 2367*9585STim.Szeto@Sun.COM /* 2368*9585STim.Szeto@Sun.COM * setDiskProp 2369*9585STim.Szeto@Sun.COM * 2370*9585STim.Szeto@Sun.COM * Purpose: set properties for resource of type disk 2371*9585STim.Szeto@Sun.COM * 2372*9585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 2373*9585STim.Szeto@Sun.COM * resourceProp - valid resource identifier 2374*9585STim.Szeto@Sun.COM * propVal - valid resource value 2375*9585STim.Szeto@Sun.COM */ 2376*9585STim.Szeto@Sun.COM static int 2377*9585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal) 2378*9585STim.Szeto@Sun.COM { 2379*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 2380*9585STim.Szeto@Sun.COM int i; 2381*9585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 2382*9585STim.Szeto@Sun.COM unsigned long long numericProp = 0; 2383*9585STim.Szeto@Sun.COM char guidProp[LU_ASCII_GUID_SIZE + 1]; 2384*9585STim.Szeto@Sun.COM char ouiProp[OUI_ASCII_SIZE + 1]; 2385*9585STim.Szeto@Sun.COM unsigned int oui[OUI_SIZE]; 2386*9585STim.Szeto@Sun.COM unsigned int guid[LU_GUID_SIZE]; 2387*9585STim.Szeto@Sun.COM int propSize; 2388*9585STim.Szeto@Sun.COM 2389*9585STim.Szeto@Sun.COM 2390*9585STim.Szeto@Sun.COM if (propVal == NULL) { 2391*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2392*9585STim.Szeto@Sun.COM } 2393*9585STim.Szeto@Sun.COM 2394*9585STim.Szeto@Sun.COM switch (resourceProp) { 2395*9585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 2396*9585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, propVal, 2397*9585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 2398*9585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 2399*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2400*9585STim.Szeto@Sun.COM } 2401*9585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 2402*9585STim.Szeto@Sun.COM break; 2403*9585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 2404*9585STim.Szeto@Sun.COM (void) sscanf(propVal, "%llu", &numericProp); 2405*9585STim.Szeto@Sun.COM if (numericProp > UINT16_MAX) { 2406*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2407*9585STim.Szeto@Sun.COM } 2408*9585STim.Szeto@Sun.COM diskLu->blkSize = numericProp; 2409*9585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 2410*9585STim.Szeto@Sun.COM break; 2411*9585STim.Szeto@Sun.COM case STMF_LU_PROP_COMPANY_ID: 2412*9585STim.Szeto@Sun.COM if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >= 2413*9585STim.Szeto@Sun.COM sizeof (ouiProp)) { 2414*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2415*9585STim.Szeto@Sun.COM } 2416*9585STim.Szeto@Sun.COM if (checkHexUpper(ouiProp) != 0) { 2417*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2418*9585STim.Szeto@Sun.COM } 2419*9585STim.Szeto@Sun.COM (void) sscanf(ouiProp, "%2X%2X%2X", 2420*9585STim.Szeto@Sun.COM &oui[0], &oui[1], &oui[2]); 2421*9585STim.Szeto@Sun.COM 2422*9585STim.Szeto@Sun.COM diskLu->companyId = 0; 2423*9585STim.Szeto@Sun.COM diskLu->companyId += oui[0] << 16; 2424*9585STim.Szeto@Sun.COM diskLu->companyId += oui[1] << 8; 2425*9585STim.Szeto@Sun.COM diskLu->companyId += oui[2]; 2426*9585STim.Szeto@Sun.COM diskLu->companyIdValid = B_TRUE; 2427*9585STim.Szeto@Sun.COM break; 2428*9585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 2429*9585STim.Szeto@Sun.COM if (strlen(propVal) != LU_ASCII_GUID_SIZE) { 2430*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2431*9585STim.Szeto@Sun.COM } 2432*9585STim.Szeto@Sun.COM 2433*9585STim.Szeto@Sun.COM if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >= 2434*9585STim.Szeto@Sun.COM sizeof (guidProp)) { 2435*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2436*9585STim.Szeto@Sun.COM } 2437*9585STim.Szeto@Sun.COM 2438*9585STim.Szeto@Sun.COM if (checkHexUpper(guidProp) != 0) { 2439*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2440*9585STim.Szeto@Sun.COM } 2441*9585STim.Szeto@Sun.COM 2442*9585STim.Szeto@Sun.COM (void) sscanf(guidProp, 2443*9585STim.Szeto@Sun.COM "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X", 2444*9585STim.Szeto@Sun.COM &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], 2445*9585STim.Szeto@Sun.COM &guid[5], &guid[6], &guid[7], &guid[8], &guid[9], 2446*9585STim.Szeto@Sun.COM &guid[10], &guid[11], &guid[12], &guid[13], 2447*9585STim.Szeto@Sun.COM &guid[14], &guid[15]); 2448*9585STim.Szeto@Sun.COM for (i = 0; i < sizeof (diskLu->luGuid); i++) { 2449*9585STim.Szeto@Sun.COM diskLu->luGuid[i] = guid[i]; 2450*9585STim.Szeto@Sun.COM } 2451*9585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 2452*9585STim.Szeto@Sun.COM break; 2453*9585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 2454*9585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luDataFileName, propVal, 2455*9585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName))) >= 2456*9585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 2457*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2458*9585STim.Szeto@Sun.COM } 2459*9585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 2460*9585STim.Szeto@Sun.COM break; 2461*9585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 2462*9585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luMetaFileName, propVal, 2463*9585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName))) >= 2464*9585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 2465*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2466*9585STim.Szeto@Sun.COM } 2467*9585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 2468*9585STim.Szeto@Sun.COM break; 2469*9585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 2470*9585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 2471*9585STim.Szeto@Sun.COM sizeof (diskLu->pid)) { 2472*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2473*9585STim.Szeto@Sun.COM } 2474*9585STim.Szeto@Sun.COM (void) strncpy(diskLu->pid, propVal, propSize); 2475*9585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 2476*9585STim.Szeto@Sun.COM break; 2477*9585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 2478*9585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 2479*9585STim.Szeto@Sun.COM (sizeof (diskLu->serialNum) - 1)) { 2480*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2481*9585STim.Szeto@Sun.COM } 2482*9585STim.Szeto@Sun.COM (void) strncpy(diskLu->serialNum, propVal, propSize); 2483*9585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 2484*9585STim.Szeto@Sun.COM break; 2485*9585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 2486*9585STim.Szeto@Sun.COM if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) { 2487*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2488*9585STim.Szeto@Sun.COM } 2489*9585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 2490*9585STim.Szeto@Sun.COM break; 2491*9585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 2492*9585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 2493*9585STim.Szeto@Sun.COM sizeof (diskLu->vid)) { 2494*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 2495*9585STim.Szeto@Sun.COM } 2496*9585STim.Szeto@Sun.COM (void) strncpy(diskLu->vid, propVal, propSize); 2497*9585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 2498*9585STim.Szeto@Sun.COM break; 2499*9585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 2500*9585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 2501*9585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 2502*9585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 2503*9585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_FALSE; 2504*9585STim.Szeto@Sun.COM } else { 2505*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2506*9585STim.Szeto@Sun.COM } 2507*9585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 2508*9585STim.Szeto@Sun.COM break; 2509*9585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 2510*9585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 2511*9585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 2512*9585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 2513*9585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_FALSE; 2514*9585STim.Szeto@Sun.COM } else { 2515*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2516*9585STim.Szeto@Sun.COM } 2517*9585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 2518*9585STim.Szeto@Sun.COM break; 2519*9585STim.Szeto@Sun.COM default: 2520*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 2521*9585STim.Szeto@Sun.COM break; 2522*9585STim.Szeto@Sun.COM } 2523*9585STim.Szeto@Sun.COM return (ret); 2524*9585STim.Szeto@Sun.COM } 2525*9585STim.Szeto@Sun.COM 2526*9585STim.Szeto@Sun.COM static int 2527*9585STim.Szeto@Sun.COM checkHexUpper(char *buf) 2528*9585STim.Szeto@Sun.COM { 2529*9585STim.Szeto@Sun.COM int i; 2530*9585STim.Szeto@Sun.COM 2531*9585STim.Szeto@Sun.COM for (i = 0; i < strlen(buf); i++) { 2532*9585STim.Szeto@Sun.COM if (isxdigit(buf[i])) { 2533*9585STim.Szeto@Sun.COM buf[i] = toupper(buf[i]); 2534*9585STim.Szeto@Sun.COM continue; 2535*9585STim.Szeto@Sun.COM } 2536*9585STim.Szeto@Sun.COM return (-1); 2537*9585STim.Szeto@Sun.COM } 2538*9585STim.Szeto@Sun.COM 2539*9585STim.Szeto@Sun.COM return (0); 2540*9585STim.Szeto@Sun.COM } 2541*9585STim.Szeto@Sun.COM 2542*9585STim.Szeto@Sun.COM /* 2543*9585STim.Szeto@Sun.COM * Given a numeric suffix, convert the value into a number of bits that the 2544*9585STim.Szeto@Sun.COM * resulting value must be shifted. 2545*9585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 2546*9585STim.Szeto@Sun.COM */ 2547*9585STim.Szeto@Sun.COM static int 2548*9585STim.Szeto@Sun.COM strToShift(const char *buf) 2549*9585STim.Szeto@Sun.COM { 2550*9585STim.Szeto@Sun.COM const char *ends = "BKMGTPE"; 2551*9585STim.Szeto@Sun.COM int i; 2552*9585STim.Szeto@Sun.COM 2553*9585STim.Szeto@Sun.COM if (buf[0] == '\0') 2554*9585STim.Szeto@Sun.COM return (0); 2555*9585STim.Szeto@Sun.COM 2556*9585STim.Szeto@Sun.COM for (i = 0; i < strlen(ends); i++) { 2557*9585STim.Szeto@Sun.COM if (toupper(buf[0]) == ends[i]) 2558*9585STim.Szeto@Sun.COM return (10*i); 2559*9585STim.Szeto@Sun.COM } 2560*9585STim.Szeto@Sun.COM 2561*9585STim.Szeto@Sun.COM return (-1); 2562*9585STim.Szeto@Sun.COM } 2563*9585STim.Szeto@Sun.COM 2564*9585STim.Szeto@Sun.COM int 2565*9585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl) 2566*9585STim.Szeto@Sun.COM { 2567*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 2568*9585STim.Szeto@Sun.COM if (hdl == NULL) { 2569*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2570*9585STim.Szeto@Sun.COM } 2571*9585STim.Szeto@Sun.COM 2572*9585STim.Szeto@Sun.COM luResourceImpl *hdlImpl = hdl; 2573*9585STim.Szeto@Sun.COM free(hdlImpl->resource); 2574*9585STim.Szeto@Sun.COM free(hdlImpl); 2575*9585STim.Szeto@Sun.COM return (ret); 2576*9585STim.Szeto@Sun.COM } 2577*9585STim.Szeto@Sun.COM 2578*9585STim.Szeto@Sun.COM /* 2579*9585STim.Szeto@Sun.COM * Convert a string of the form '100G' into a real number. Used when setting 2580*9585STim.Szeto@Sun.COM * the size of a logical unit. 2581*9585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 2582*9585STim.Szeto@Sun.COM */ 2583*9585STim.Szeto@Sun.COM static int 2584*9585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num) 2585*9585STim.Szeto@Sun.COM { 2586*9585STim.Szeto@Sun.COM char *end; 2587*9585STim.Szeto@Sun.COM int shift; 2588*9585STim.Szeto@Sun.COM 2589*9585STim.Szeto@Sun.COM *num = 0; 2590*9585STim.Szeto@Sun.COM 2591*9585STim.Szeto@Sun.COM /* Check to see if this looks like a number. */ 2592*9585STim.Szeto@Sun.COM if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 2593*9585STim.Szeto@Sun.COM return (-1); 2594*9585STim.Szeto@Sun.COM } 2595*9585STim.Szeto@Sun.COM 2596*9585STim.Szeto@Sun.COM /* Rely on stroull() to process the numeric portion. */ 2597*9585STim.Szeto@Sun.COM errno = 0; 2598*9585STim.Szeto@Sun.COM *num = strtoull(value, &end, 10); 2599*9585STim.Szeto@Sun.COM 2600*9585STim.Szeto@Sun.COM /* 2601*9585STim.Szeto@Sun.COM * Check for ERANGE, which indicates that the value is too large to fit 2602*9585STim.Szeto@Sun.COM * in a 64-bit value. 2603*9585STim.Szeto@Sun.COM */ 2604*9585STim.Szeto@Sun.COM if (errno == ERANGE) { 2605*9585STim.Szeto@Sun.COM return (-1); 2606*9585STim.Szeto@Sun.COM } 2607*9585STim.Szeto@Sun.COM 2608*9585STim.Szeto@Sun.COM /* 2609*9585STim.Szeto@Sun.COM * If we have a decimal value, then do the computation with floating 2610*9585STim.Szeto@Sun.COM * point arithmetic. Otherwise, use standard arithmetic. 2611*9585STim.Szeto@Sun.COM */ 2612*9585STim.Szeto@Sun.COM if (*end == '.') { 2613*9585STim.Szeto@Sun.COM double fval = strtod(value, &end); 2614*9585STim.Szeto@Sun.COM 2615*9585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 2616*9585STim.Szeto@Sun.COM return (-1); 2617*9585STim.Szeto@Sun.COM } 2618*9585STim.Szeto@Sun.COM 2619*9585STim.Szeto@Sun.COM fval *= pow(2, shift); 2620*9585STim.Szeto@Sun.COM 2621*9585STim.Szeto@Sun.COM if (fval > UINT64_MAX) { 2622*9585STim.Szeto@Sun.COM return (-1); 2623*9585STim.Szeto@Sun.COM } 2624*9585STim.Szeto@Sun.COM 2625*9585STim.Szeto@Sun.COM *num = (uint64_t)fval; 2626*9585STim.Szeto@Sun.COM } else { 2627*9585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 2628*9585STim.Szeto@Sun.COM return (-1); 2629*9585STim.Szeto@Sun.COM } 2630*9585STim.Szeto@Sun.COM 2631*9585STim.Szeto@Sun.COM /* Check for overflow */ 2632*9585STim.Szeto@Sun.COM if (shift >= 64 || (*num << shift) >> shift != *num) { 2633*9585STim.Szeto@Sun.COM return (-1); 2634*9585STim.Szeto@Sun.COM } 2635*9585STim.Szeto@Sun.COM 2636*9585STim.Szeto@Sun.COM *num <<= shift; 2637*9585STim.Szeto@Sun.COM } 2638*9585STim.Szeto@Sun.COM 2639*9585STim.Szeto@Sun.COM return (0); 2640*9585STim.Szeto@Sun.COM } 2641*9585STim.Szeto@Sun.COM 2642*9585STim.Szeto@Sun.COM /* 26437836SJohn.Forte@Sun.COM * stmfCreateTargetGroup 26447836SJohn.Forte@Sun.COM * 26457836SJohn.Forte@Sun.COM * Purpose: Create a local port group 26467836SJohn.Forte@Sun.COM * 26477836SJohn.Forte@Sun.COM * targetGroupName - name of local port group to create 26487836SJohn.Forte@Sun.COM */ 26497836SJohn.Forte@Sun.COM int 26507836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName) 26517836SJohn.Forte@Sun.COM { 26527836SJohn.Forte@Sun.COM int ret; 26537836SJohn.Forte@Sun.COM int fd; 26547836SJohn.Forte@Sun.COM 26557836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 26567836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 26577836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 26587836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 26597836SJohn.Forte@Sun.COM } 26607836SJohn.Forte@Sun.COM 26617836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 26627836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 26637836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 26647836SJohn.Forte@Sun.COM } 26657836SJohn.Forte@Sun.COM 26667836SJohn.Forte@Sun.COM /* call init */ 26677836SJohn.Forte@Sun.COM ret = initializeConfig(); 26687836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 26697836SJohn.Forte@Sun.COM return (ret); 26707836SJohn.Forte@Sun.COM } 26717836SJohn.Forte@Sun.COM 26727836SJohn.Forte@Sun.COM /* 26737836SJohn.Forte@Sun.COM * Open control node for stmf 26747836SJohn.Forte@Sun.COM */ 26757836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 26767836SJohn.Forte@Sun.COM return (ret); 26777836SJohn.Forte@Sun.COM 26787836SJohn.Forte@Sun.COM /* 26797836SJohn.Forte@Sun.COM * Add the group to the driver 26807836SJohn.Forte@Sun.COM */ 26817836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 26827836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 26837836SJohn.Forte@Sun.COM goto done; 26847836SJohn.Forte@Sun.COM } 26857836SJohn.Forte@Sun.COM 2686*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 2687*9585STim.Szeto@Sun.COM goto done; 2688*9585STim.Szeto@Sun.COM } 2689*9585STim.Szeto@Sun.COM 26907836SJohn.Forte@Sun.COM /* 26917836SJohn.Forte@Sun.COM * If the add to the driver was successful, add it to the persistent 26927836SJohn.Forte@Sun.COM * store. 26937836SJohn.Forte@Sun.COM */ 26947836SJohn.Forte@Sun.COM ret = psCreateTargetGroup((char *)targetGroupName); 26957836SJohn.Forte@Sun.COM switch (ret) { 26967836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 26977836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 26987836SJohn.Forte@Sun.COM break; 26997836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 27007836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 27017836SJohn.Forte@Sun.COM break; 27027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 27037836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 27047836SJohn.Forte@Sun.COM break; 27057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 27067836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 27077836SJohn.Forte@Sun.COM break; 27087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 27097836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 27107836SJohn.Forte@Sun.COM break; 27117836SJohn.Forte@Sun.COM default: 27127836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 27137836SJohn.Forte@Sun.COM "stmfCreateTargetGroup:psCreateTargetGroup" 27147836SJohn.Forte@Sun.COM ":error(%d)", ret); 27157836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 27167836SJohn.Forte@Sun.COM break; 27177836SJohn.Forte@Sun.COM } 27187836SJohn.Forte@Sun.COM 27197836SJohn.Forte@Sun.COM done: 27207836SJohn.Forte@Sun.COM (void) close(fd); 27217836SJohn.Forte@Sun.COM return (ret); 27227836SJohn.Forte@Sun.COM } 27237836SJohn.Forte@Sun.COM 27247836SJohn.Forte@Sun.COM /* 27257836SJohn.Forte@Sun.COM * stmfDeleteHostGroup 27267836SJohn.Forte@Sun.COM * 27277836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 27287836SJohn.Forte@Sun.COM * 27297836SJohn.Forte@Sun.COM * hostGroupName - group to delete 27307836SJohn.Forte@Sun.COM */ 27317836SJohn.Forte@Sun.COM int 27327836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName) 27337836SJohn.Forte@Sun.COM { 27347836SJohn.Forte@Sun.COM int ret; 27357836SJohn.Forte@Sun.COM int fd; 27367836SJohn.Forte@Sun.COM 27377836SJohn.Forte@Sun.COM if (hostGroupName == NULL) { 27387836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 27397836SJohn.Forte@Sun.COM } 27407836SJohn.Forte@Sun.COM 27417836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 27427836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 27437836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 27447836SJohn.Forte@Sun.COM } 27457836SJohn.Forte@Sun.COM 27467836SJohn.Forte@Sun.COM /* call init */ 27477836SJohn.Forte@Sun.COM ret = initializeConfig(); 27487836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 27497836SJohn.Forte@Sun.COM return (ret); 27507836SJohn.Forte@Sun.COM } 27517836SJohn.Forte@Sun.COM 27527836SJohn.Forte@Sun.COM /* 27537836SJohn.Forte@Sun.COM * Open control node for stmf 27547836SJohn.Forte@Sun.COM */ 27557836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 27567836SJohn.Forte@Sun.COM return (ret); 27577836SJohn.Forte@Sun.COM 27587836SJohn.Forte@Sun.COM /* 27597836SJohn.Forte@Sun.COM * Remove the group from the driver 27607836SJohn.Forte@Sun.COM */ 27617836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP, 27627836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 27637836SJohn.Forte@Sun.COM goto done; 27647836SJohn.Forte@Sun.COM } 27657836SJohn.Forte@Sun.COM 2766*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 2767*9585STim.Szeto@Sun.COM goto done; 2768*9585STim.Szeto@Sun.COM } 2769*9585STim.Szeto@Sun.COM 27707836SJohn.Forte@Sun.COM /* 27717836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 27727836SJohn.Forte@Sun.COM * persistent store. 27737836SJohn.Forte@Sun.COM */ 27747836SJohn.Forte@Sun.COM ret = psDeleteHostGroup((char *)hostGroupName); 27757836SJohn.Forte@Sun.COM switch (ret) { 27767836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 27777836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 27787836SJohn.Forte@Sun.COM break; 27797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 27807836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 27817836SJohn.Forte@Sun.COM break; 27827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 27837836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 27847836SJohn.Forte@Sun.COM break; 27857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 27867836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 27877836SJohn.Forte@Sun.COM break; 27887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 27897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 27907836SJohn.Forte@Sun.COM break; 27917836SJohn.Forte@Sun.COM default: 27927836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 27937836SJohn.Forte@Sun.COM "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)", 27947836SJohn.Forte@Sun.COM ret); 27957836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 27967836SJohn.Forte@Sun.COM break; 27977836SJohn.Forte@Sun.COM } 27987836SJohn.Forte@Sun.COM 27997836SJohn.Forte@Sun.COM done: 28007836SJohn.Forte@Sun.COM (void) close(fd); 28017836SJohn.Forte@Sun.COM return (ret); 28027836SJohn.Forte@Sun.COM } 28037836SJohn.Forte@Sun.COM 28047836SJohn.Forte@Sun.COM /* 28057836SJohn.Forte@Sun.COM * stmfDeleteTargetGroup 28067836SJohn.Forte@Sun.COM * 28077836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 28087836SJohn.Forte@Sun.COM * 28097836SJohn.Forte@Sun.COM * targetGroupName - group to delete 28107836SJohn.Forte@Sun.COM */ 28117836SJohn.Forte@Sun.COM int 28127836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName) 28137836SJohn.Forte@Sun.COM { 28147836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 28157836SJohn.Forte@Sun.COM int fd; 28167836SJohn.Forte@Sun.COM 28177836SJohn.Forte@Sun.COM if (targetGroupName == NULL) { 28187836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 28197836SJohn.Forte@Sun.COM } 28207836SJohn.Forte@Sun.COM 28217836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 28227836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 28237836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 28247836SJohn.Forte@Sun.COM } 28257836SJohn.Forte@Sun.COM 28267836SJohn.Forte@Sun.COM /* call init */ 28277836SJohn.Forte@Sun.COM ret = initializeConfig(); 28287836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 28297836SJohn.Forte@Sun.COM return (ret); 28307836SJohn.Forte@Sun.COM } 28317836SJohn.Forte@Sun.COM 28327836SJohn.Forte@Sun.COM /* 28337836SJohn.Forte@Sun.COM * Open control node for stmf 28347836SJohn.Forte@Sun.COM */ 28357836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 28367836SJohn.Forte@Sun.COM return (ret); 28377836SJohn.Forte@Sun.COM 28387836SJohn.Forte@Sun.COM /* 28397836SJohn.Forte@Sun.COM * Remove the group from the driver 28407836SJohn.Forte@Sun.COM */ 28417836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP, 28427836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 28437836SJohn.Forte@Sun.COM goto done; 28447836SJohn.Forte@Sun.COM } 28457836SJohn.Forte@Sun.COM 2846*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 2847*9585STim.Szeto@Sun.COM goto done; 2848*9585STim.Szeto@Sun.COM } 2849*9585STim.Szeto@Sun.COM 28507836SJohn.Forte@Sun.COM /* 28517836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 28527836SJohn.Forte@Sun.COM * persistent store. 28537836SJohn.Forte@Sun.COM */ 28547836SJohn.Forte@Sun.COM ret = psDeleteTargetGroup((char *)targetGroupName); 28557836SJohn.Forte@Sun.COM switch (ret) { 28567836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 28577836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 28587836SJohn.Forte@Sun.COM break; 28597836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 28607836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 28617836SJohn.Forte@Sun.COM break; 28627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 28637836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 28647836SJohn.Forte@Sun.COM break; 28657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 28667836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 28677836SJohn.Forte@Sun.COM break; 28687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 28697836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 28707836SJohn.Forte@Sun.COM break; 28717836SJohn.Forte@Sun.COM default: 28727836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 28737836SJohn.Forte@Sun.COM "stmfDeleteTargetGroup:psDeleteTargetGroup" 28747836SJohn.Forte@Sun.COM ":error(%d)", ret); 28757836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 28767836SJohn.Forte@Sun.COM break; 28777836SJohn.Forte@Sun.COM } 28787836SJohn.Forte@Sun.COM 28797836SJohn.Forte@Sun.COM done: 28807836SJohn.Forte@Sun.COM (void) close(fd); 28817836SJohn.Forte@Sun.COM return (ret); 28827836SJohn.Forte@Sun.COM } 28837836SJohn.Forte@Sun.COM 28847836SJohn.Forte@Sun.COM /* 28857836SJohn.Forte@Sun.COM * stmfDevidFromIscsiName 28867836SJohn.Forte@Sun.COM * 28877836SJohn.Forte@Sun.COM * Purpose: convert an iSCSI name to an stmf devid 28887836SJohn.Forte@Sun.COM * 28897836SJohn.Forte@Sun.COM * iscsiName - unicode nul terminated utf-8 encoded iSCSI name 28907836SJohn.Forte@Sun.COM * devid - on success, contains the converted iscsi name 28917836SJohn.Forte@Sun.COM */ 28927836SJohn.Forte@Sun.COM int 28937836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid) 28947836SJohn.Forte@Sun.COM { 28957836SJohn.Forte@Sun.COM if (devid == NULL || iscsiName == NULL) 28967836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 28977836SJohn.Forte@Sun.COM 28987836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 28997836SJohn.Forte@Sun.COM 29007836SJohn.Forte@Sun.COM /* Validate size of target */ 29017836SJohn.Forte@Sun.COM if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME || 29027836SJohn.Forte@Sun.COM devid->identLength < strlen(EUI) || 29037836SJohn.Forte@Sun.COM devid->identLength < strlen(IQN)) { 29047836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29057836SJohn.Forte@Sun.COM } 29067836SJohn.Forte@Sun.COM 29077836SJohn.Forte@Sun.COM if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) && 29087836SJohn.Forte@Sun.COM strncmp(iscsiName, IQN, strlen(IQN)) != 0) { 29097836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29107836SJohn.Forte@Sun.COM } 29117836SJohn.Forte@Sun.COM 29127836SJohn.Forte@Sun.COM /* copy UTF-8 bytes to ident */ 29137836SJohn.Forte@Sun.COM bcopy(iscsiName, devid->ident, devid->identLength); 29147836SJohn.Forte@Sun.COM 29157836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 29167836SJohn.Forte@Sun.COM } 29177836SJohn.Forte@Sun.COM 29187836SJohn.Forte@Sun.COM /* 29197836SJohn.Forte@Sun.COM * stmfDevidFromWwn 29207836SJohn.Forte@Sun.COM * 29217836SJohn.Forte@Sun.COM * Purpose: convert a WWN to an stmf devid 29227836SJohn.Forte@Sun.COM * 29237836SJohn.Forte@Sun.COM * wwn - 8-byte wwn identifier 29247836SJohn.Forte@Sun.COM * devid - on success, contains the converted wwn 29257836SJohn.Forte@Sun.COM */ 29267836SJohn.Forte@Sun.COM int 29277836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid) 29287836SJohn.Forte@Sun.COM { 29297836SJohn.Forte@Sun.COM if (wwn == NULL || devid == NULL) 29307836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29317836SJohn.Forte@Sun.COM 29327836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 29337836SJohn.Forte@Sun.COM 29347836SJohn.Forte@Sun.COM /* Copy eui prefix */ 29357836SJohn.Forte@Sun.COM (void) bcopy(WWN, devid->ident, strlen(WWN)); 29367836SJohn.Forte@Sun.COM 29377836SJohn.Forte@Sun.COM /* Convert to ASCII uppercase hexadecimal string */ 29387836SJohn.Forte@Sun.COM (void) snprintf((char *)&devid->ident[strlen(WWN)], 29397836SJohn.Forte@Sun.COM sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X", 29407836SJohn.Forte@Sun.COM wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 29417836SJohn.Forte@Sun.COM 29427836SJohn.Forte@Sun.COM devid->identLength = strlen((char *)devid->ident); 29437836SJohn.Forte@Sun.COM 29447836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 29457836SJohn.Forte@Sun.COM } 29467836SJohn.Forte@Sun.COM 29477836SJohn.Forte@Sun.COM /* 29487836SJohn.Forte@Sun.COM * stmfFreeMemory 29497836SJohn.Forte@Sun.COM * 29507836SJohn.Forte@Sun.COM * Purpose: Free memory allocated by this library 29517836SJohn.Forte@Sun.COM * 29527836SJohn.Forte@Sun.COM * memory - previously allocated pointer of memory managed by library 29537836SJohn.Forte@Sun.COM */ 29547836SJohn.Forte@Sun.COM void 29557836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory) 29567836SJohn.Forte@Sun.COM { 29577836SJohn.Forte@Sun.COM free(memory); 29587836SJohn.Forte@Sun.COM } 29597836SJohn.Forte@Sun.COM 29607836SJohn.Forte@Sun.COM /* 2961*9585STim.Szeto@Sun.COM * get host group, target group list from stmf 29627836SJohn.Forte@Sun.COM * 2963*9585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 29647836SJohn.Forte@Sun.COM */ 2965*9585STim.Szeto@Sun.COM static int 2966*9585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType) 2967*9585STim.Szeto@Sun.COM { 2968*9585STim.Szeto@Sun.COM int ret; 2969*9585STim.Szeto@Sun.COM int fd; 2970*9585STim.Szeto@Sun.COM int ioctlRet; 2971*9585STim.Szeto@Sun.COM int i; 2972*9585STim.Szeto@Sun.COM int cmd; 2973*9585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 2974*9585STim.Szeto@Sun.COM /* framework group list */ 2975*9585STim.Szeto@Sun.COM stmf_group_name_t *iGroupList = NULL; 2976*9585STim.Szeto@Sun.COM uint32_t groupListSize; 2977*9585STim.Szeto@Sun.COM 2978*9585STim.Szeto@Sun.COM if (groupList == NULL) { 2979*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2980*9585STim.Szeto@Sun.COM } 2981*9585STim.Szeto@Sun.COM 2982*9585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 2983*9585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_LIST; 2984*9585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 2985*9585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_LIST; 2986*9585STim.Szeto@Sun.COM } else { 2987*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 2988*9585STim.Szeto@Sun.COM } 2989*9585STim.Szeto@Sun.COM 2990*9585STim.Szeto@Sun.COM /* call init */ 2991*9585STim.Szeto@Sun.COM ret = initializeConfig(); 2992*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2993*9585STim.Szeto@Sun.COM return (ret); 2994*9585STim.Szeto@Sun.COM } 2995*9585STim.Szeto@Sun.COM 2996*9585STim.Szeto@Sun.COM /* 2997*9585STim.Szeto@Sun.COM * Open control node for stmf 2998*9585STim.Szeto@Sun.COM */ 2999*9585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 3000*9585STim.Szeto@Sun.COM return (ret); 3001*9585STim.Szeto@Sun.COM 3002*9585STim.Szeto@Sun.COM /* 3003*9585STim.Szeto@Sun.COM * Allocate ioctl input buffer 3004*9585STim.Szeto@Sun.COM */ 3005*9585STim.Szeto@Sun.COM groupListSize = ALLOC_GROUP; 3006*9585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_group_name_t)); 3007*9585STim.Szeto@Sun.COM iGroupList = (stmf_group_name_t *)calloc(1, groupListSize); 3008*9585STim.Szeto@Sun.COM if (iGroupList == NULL) { 3009*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3010*9585STim.Szeto@Sun.COM goto done; 3011*9585STim.Szeto@Sun.COM } 3012*9585STim.Szeto@Sun.COM 3013*9585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3014*9585STim.Szeto@Sun.COM /* 3015*9585STim.Szeto@Sun.COM * Issue ioctl to get the group list 3016*9585STim.Szeto@Sun.COM */ 3017*9585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3018*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 3019*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 3020*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3021*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 3022*9585STim.Szeto@Sun.COM switch (errno) { 3023*9585STim.Szeto@Sun.COM case EBUSY: 3024*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3025*9585STim.Szeto@Sun.COM break; 3026*9585STim.Szeto@Sun.COM case EPERM: 3027*9585STim.Szeto@Sun.COM case EACCES: 3028*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 3029*9585STim.Szeto@Sun.COM break; 3030*9585STim.Szeto@Sun.COM default: 3031*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 3032*9585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 3033*9585STim.Szeto@Sun.COM errno); 3034*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 3035*9585STim.Szeto@Sun.COM break; 3036*9585STim.Szeto@Sun.COM } 3037*9585STim.Szeto@Sun.COM goto done; 3038*9585STim.Szeto@Sun.COM } 3039*9585STim.Szeto@Sun.COM /* 3040*9585STim.Szeto@Sun.COM * Check whether input buffer was large enough 3041*9585STim.Szeto@Sun.COM */ 3042*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) { 3043*9585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 3044*9585STim.Szeto@Sun.COM sizeof (stmf_group_name_t); 3045*9585STim.Szeto@Sun.COM iGroupList = realloc(iGroupList, groupListSize); 3046*9585STim.Szeto@Sun.COM if (iGroupList == NULL) { 3047*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3048*9585STim.Szeto@Sun.COM goto done; 3049*9585STim.Szeto@Sun.COM } 3050*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 3051*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 3052*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3053*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 3054*9585STim.Szeto@Sun.COM switch (errno) { 3055*9585STim.Szeto@Sun.COM case EBUSY: 3056*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3057*9585STim.Szeto@Sun.COM break; 3058*9585STim.Szeto@Sun.COM case EPERM: 3059*9585STim.Szeto@Sun.COM case EACCES: 3060*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 3061*9585STim.Szeto@Sun.COM break; 3062*9585STim.Szeto@Sun.COM default: 3063*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 3064*9585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 3065*9585STim.Szeto@Sun.COM errno); 3066*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 3067*9585STim.Szeto@Sun.COM break; 3068*9585STim.Szeto@Sun.COM } 3069*9585STim.Szeto@Sun.COM goto done; 3070*9585STim.Szeto@Sun.COM } 3071*9585STim.Szeto@Sun.COM } 3072*9585STim.Szeto@Sun.COM 3073*9585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 3074*9585STim.Szeto@Sun.COM *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) * 3075*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_nentries); 3076*9585STim.Szeto@Sun.COM if (*groupList == NULL) { 3077*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3078*9585STim.Szeto@Sun.COM goto done; 3079*9585STim.Szeto@Sun.COM } 3080*9585STim.Szeto@Sun.COM (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries; 3081*9585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 3082*9585STim.Szeto@Sun.COM bcopy(iGroupList->name, (*groupList)->name[i], 3083*9585STim.Szeto@Sun.COM sizeof (stmfGroupName)); 3084*9585STim.Szeto@Sun.COM iGroupList++; 3085*9585STim.Szeto@Sun.COM } 3086*9585STim.Szeto@Sun.COM 3087*9585STim.Szeto@Sun.COM done: 3088*9585STim.Szeto@Sun.COM free(iGroupList); 3089*9585STim.Szeto@Sun.COM (void) close(fd); 3090*9585STim.Szeto@Sun.COM return (ret); 3091*9585STim.Szeto@Sun.COM } 3092*9585STim.Szeto@Sun.COM 3093*9585STim.Szeto@Sun.COM /* 3094*9585STim.Szeto@Sun.COM * get host group members, target group members from stmf 3095*9585STim.Szeto@Sun.COM * 3096*9585STim.Szeto@Sun.COM * groupProps - allocated on success 3097*9585STim.Szeto@Sun.COM * 3098*9585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 3099*9585STim.Szeto@Sun.COM */ 3100*9585STim.Szeto@Sun.COM static int 3101*9585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps, 3102*9585STim.Szeto@Sun.COM int groupType) 31037836SJohn.Forte@Sun.COM { 31047836SJohn.Forte@Sun.COM int ret; 3105*9585STim.Szeto@Sun.COM int fd; 3106*9585STim.Szeto@Sun.COM int ioctlRet; 3107*9585STim.Szeto@Sun.COM int i; 3108*9585STim.Szeto@Sun.COM int cmd; 3109*9585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 3110*9585STim.Szeto@Sun.COM /* framework group list */ 3111*9585STim.Szeto@Sun.COM stmf_group_name_t iGroupName; 3112*9585STim.Szeto@Sun.COM stmf_ge_ident_t *iGroupMembers; 3113*9585STim.Szeto@Sun.COM uint32_t groupListSize; 3114*9585STim.Szeto@Sun.COM 3115*9585STim.Szeto@Sun.COM if (groupName == NULL) { 3116*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 3117*9585STim.Szeto@Sun.COM } 3118*9585STim.Szeto@Sun.COM 3119*9585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 3120*9585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_ENTRIES; 3121*9585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 3122*9585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_ENTRIES; 3123*9585STim.Szeto@Sun.COM } else { 31247836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31257836SJohn.Forte@Sun.COM } 31267836SJohn.Forte@Sun.COM 3127*9585STim.Szeto@Sun.COM /* call init */ 3128*9585STim.Szeto@Sun.COM ret = initializeConfig(); 3129*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 3130*9585STim.Szeto@Sun.COM return (ret); 3131*9585STim.Szeto@Sun.COM } 3132*9585STim.Szeto@Sun.COM 3133*9585STim.Szeto@Sun.COM /* 3134*9585STim.Szeto@Sun.COM * Open control node for stmf 3135*9585STim.Szeto@Sun.COM */ 3136*9585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 3137*9585STim.Szeto@Sun.COM return (ret); 3138*9585STim.Szeto@Sun.COM 3139*9585STim.Szeto@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 3140*9585STim.Szeto@Sun.COM 3141*9585STim.Szeto@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 3142*9585STim.Szeto@Sun.COM 3143*9585STim.Szeto@Sun.COM iGroupName.name_size = strlen((char *)groupName); 3144*9585STim.Szeto@Sun.COM 3145*9585STim.Szeto@Sun.COM /* 3146*9585STim.Szeto@Sun.COM * Allocate ioctl input buffer 3147*9585STim.Szeto@Sun.COM */ 3148*9585STim.Szeto@Sun.COM groupListSize = ALLOC_GRP_MEMBER; 3149*9585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_ge_ident_t)); 3150*9585STim.Szeto@Sun.COM iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize); 3151*9585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 3152*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3153*9585STim.Szeto@Sun.COM goto done; 3154*9585STim.Szeto@Sun.COM } 3155*9585STim.Szeto@Sun.COM 3156*9585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3157*9585STim.Szeto@Sun.COM /* 3158*9585STim.Szeto@Sun.COM * Issue ioctl to get the group list 3159*9585STim.Szeto@Sun.COM */ 3160*9585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3161*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 3162*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 3163*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 3164*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 3165*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3166*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 3167*9585STim.Szeto@Sun.COM switch (errno) { 3168*9585STim.Szeto@Sun.COM case EBUSY: 3169*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3170*9585STim.Szeto@Sun.COM break; 3171*9585STim.Szeto@Sun.COM case EPERM: 3172*9585STim.Szeto@Sun.COM case EACCES: 3173*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 3174*9585STim.Szeto@Sun.COM break; 3175*9585STim.Szeto@Sun.COM default: 3176*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 3177*9585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 3178*9585STim.Szeto@Sun.COM errno); 3179*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 3180*9585STim.Szeto@Sun.COM break; 3181*9585STim.Szeto@Sun.COM } 3182*9585STim.Szeto@Sun.COM goto done; 3183*9585STim.Szeto@Sun.COM } 3184*9585STim.Szeto@Sun.COM /* 3185*9585STim.Szeto@Sun.COM * Check whether input buffer was large enough 3186*9585STim.Szeto@Sun.COM */ 3187*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) { 3188*9585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 3189*9585STim.Szeto@Sun.COM sizeof (stmf_ge_ident_t); 3190*9585STim.Szeto@Sun.COM iGroupMembers = realloc(iGroupMembers, groupListSize); 3191*9585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 3192*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3193*9585STim.Szeto@Sun.COM goto done; 3194*9585STim.Szeto@Sun.COM } 3195*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 3196*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 3197*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 3198*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 3199*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3200*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 3201*9585STim.Szeto@Sun.COM switch (errno) { 3202*9585STim.Szeto@Sun.COM case EBUSY: 3203*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3204*9585STim.Szeto@Sun.COM break; 3205*9585STim.Szeto@Sun.COM case EPERM: 3206*9585STim.Szeto@Sun.COM case EACCES: 3207*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 3208*9585STim.Szeto@Sun.COM break; 3209*9585STim.Szeto@Sun.COM default: 3210*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 3211*9585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 3212*9585STim.Szeto@Sun.COM errno); 3213*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 3214*9585STim.Szeto@Sun.COM break; 3215*9585STim.Szeto@Sun.COM } 3216*9585STim.Szeto@Sun.COM goto done; 3217*9585STim.Szeto@Sun.COM } 3218*9585STim.Szeto@Sun.COM } 3219*9585STim.Szeto@Sun.COM 3220*9585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 3221*9585STim.Szeto@Sun.COM *groupProps = (stmfGroupProperties *)calloc(1, 3222*9585STim.Szeto@Sun.COM sizeof (stmfGroupProperties) * stmfIoctl.stmf_obuf_nentries); 3223*9585STim.Szeto@Sun.COM if (*groupProps == NULL) { 3224*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3225*9585STim.Szeto@Sun.COM goto done; 3226*9585STim.Szeto@Sun.COM } 3227*9585STim.Szeto@Sun.COM (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries; 3228*9585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 3229*9585STim.Szeto@Sun.COM (*groupProps)->name[i].identLength = 3230*9585STim.Szeto@Sun.COM iGroupMembers->ident_size; 3231*9585STim.Szeto@Sun.COM bcopy(iGroupMembers->ident, (*groupProps)->name[i].ident, 3232*9585STim.Szeto@Sun.COM iGroupMembers->ident_size); 3233*9585STim.Szeto@Sun.COM iGroupMembers++; 3234*9585STim.Szeto@Sun.COM } 3235*9585STim.Szeto@Sun.COM 3236*9585STim.Szeto@Sun.COM done: 3237*9585STim.Szeto@Sun.COM free(iGroupMembers); 3238*9585STim.Szeto@Sun.COM (void) close(fd); 3239*9585STim.Szeto@Sun.COM return (ret); 3240*9585STim.Szeto@Sun.COM } 3241*9585STim.Szeto@Sun.COM 3242*9585STim.Szeto@Sun.COM /* 3243*9585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 3244*9585STim.Szeto@Sun.COM */ 3245*9585STim.Szeto@Sun.COM static int 3246*9585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type) 3247*9585STim.Szeto@Sun.COM { 3248*9585STim.Szeto@Sun.COM int ret; 3249*9585STim.Szeto@Sun.COM 3250*9585STim.Szeto@Sun.COM if (groupList == NULL) { 3251*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 3252*9585STim.Szeto@Sun.COM } 3253*9585STim.Szeto@Sun.COM 3254*9585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 3255*9585STim.Szeto@Sun.COM ret = psGetHostGroupList(groupList); 3256*9585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 3257*9585STim.Szeto@Sun.COM ret = psGetTargetGroupList(groupList); 3258*9585STim.Szeto@Sun.COM } else { 3259*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 3260*9585STim.Szeto@Sun.COM } 32617836SJohn.Forte@Sun.COM switch (ret) { 32627836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 32637836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 32647836SJohn.Forte@Sun.COM break; 32657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 32667836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 32677836SJohn.Forte@Sun.COM break; 32687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 32697836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 32707836SJohn.Forte@Sun.COM break; 32717836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 32727836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 32737836SJohn.Forte@Sun.COM break; 32747836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 32757836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 32767836SJohn.Forte@Sun.COM break; 32777836SJohn.Forte@Sun.COM default: 32787836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 32797836SJohn.Forte@Sun.COM "stmfGetHostGroupList:psGetHostGroupList:error(%d)", 32807836SJohn.Forte@Sun.COM ret); 32817836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 32827836SJohn.Forte@Sun.COM break; 32837836SJohn.Forte@Sun.COM } 32847836SJohn.Forte@Sun.COM 32857836SJohn.Forte@Sun.COM return (ret); 32867836SJohn.Forte@Sun.COM } 32877836SJohn.Forte@Sun.COM 32887836SJohn.Forte@Sun.COM /* 3289*9585STim.Szeto@Sun.COM * stmfGetHostGroupList 32907836SJohn.Forte@Sun.COM * 3291*9585STim.Szeto@Sun.COM * Purpose: Retrieves the list of initiator group oids 3292*9585STim.Szeto@Sun.COM * 3293*9585STim.Szeto@Sun.COM * hostGroupList - pointer to pointer to hostGroupList structure 3294*9585STim.Szeto@Sun.COM * on success, this contains the host group list. 32957836SJohn.Forte@Sun.COM */ 32967836SJohn.Forte@Sun.COM int 3297*9585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList) 3298*9585STim.Szeto@Sun.COM { 3299*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 3300*9585STim.Szeto@Sun.COM 3301*9585STim.Szeto@Sun.COM if (hostGroupList == NULL) { 3302*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 3303*9585STim.Szeto@Sun.COM } 3304*9585STim.Szeto@Sun.COM 3305*9585STim.Szeto@Sun.COM ret = groupListIoctl(hostGroupList, HOST_GROUP); 3306*9585STim.Szeto@Sun.COM return (ret); 3307*9585STim.Szeto@Sun.COM } 3308*9585STim.Szeto@Sun.COM 3309*9585STim.Szeto@Sun.COM 3310*9585STim.Szeto@Sun.COM /* 3311*9585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 3312*9585STim.Szeto@Sun.COM */ 3313*9585STim.Szeto@Sun.COM static int 3314*9585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName, 3315*9585STim.Szeto@Sun.COM stmfGroupProperties **groupProp, int type) 33167836SJohn.Forte@Sun.COM { 33177836SJohn.Forte@Sun.COM int ret; 33187836SJohn.Forte@Sun.COM 3319*9585STim.Szeto@Sun.COM if (groupName == NULL) { 33207836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 33217836SJohn.Forte@Sun.COM } 33227836SJohn.Forte@Sun.COM 3323*9585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 3324*9585STim.Szeto@Sun.COM ret = psGetHostGroupMemberList((char *)groupName, groupProp); 3325*9585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 3326*9585STim.Szeto@Sun.COM ret = psGetTargetGroupMemberList((char *)groupName, groupProp); 3327*9585STim.Szeto@Sun.COM } else { 3328*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 3329*9585STim.Szeto@Sun.COM } 33307836SJohn.Forte@Sun.COM switch (ret) { 33317836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 33327836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 33337836SJohn.Forte@Sun.COM break; 33347836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 33357836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 33367836SJohn.Forte@Sun.COM break; 33377836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 33387836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 33397836SJohn.Forte@Sun.COM break; 33407836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33417836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33427836SJohn.Forte@Sun.COM break; 33437836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33447836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33457836SJohn.Forte@Sun.COM break; 33467836SJohn.Forte@Sun.COM default: 33477836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 3348*9585STim.Szeto@Sun.COM "iLoadGroupMembersFromPs:psGetHostGroupList:" 3349*9585STim.Szeto@Sun.COM "error(%d)", ret); 33507836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33517836SJohn.Forte@Sun.COM break; 33527836SJohn.Forte@Sun.COM } 33537836SJohn.Forte@Sun.COM 33547836SJohn.Forte@Sun.COM return (ret); 33557836SJohn.Forte@Sun.COM } 33567836SJohn.Forte@Sun.COM 33577836SJohn.Forte@Sun.COM /* 3358*9585STim.Szeto@Sun.COM * stmfGetHostGroupMembers 3359*9585STim.Szeto@Sun.COM * 3360*9585STim.Szeto@Sun.COM * Purpose: Retrieves the group properties for a host group 3361*9585STim.Szeto@Sun.COM * 3362*9585STim.Szeto@Sun.COM * groupName - name of group for which to retrieve host group members. 3363*9585STim.Szeto@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 3364*9585STim.Szeto@Sun.COM * on success, this contains the list of group members. 3365*9585STim.Szeto@Sun.COM */ 3366*9585STim.Szeto@Sun.COM int 3367*9585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName, 3368*9585STim.Szeto@Sun.COM stmfGroupProperties **groupProp) 3369*9585STim.Szeto@Sun.COM { 3370*9585STim.Szeto@Sun.COM int ret; 3371*9585STim.Szeto@Sun.COM 3372*9585STim.Szeto@Sun.COM if (groupName == NULL || groupProp == NULL) { 3373*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 3374*9585STim.Szeto@Sun.COM } 3375*9585STim.Szeto@Sun.COM 3376*9585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP); 3377*9585STim.Szeto@Sun.COM 3378*9585STim.Szeto@Sun.COM return (ret); 3379*9585STim.Szeto@Sun.COM } 3380*9585STim.Szeto@Sun.COM 3381*9585STim.Szeto@Sun.COM /* 33827836SJohn.Forte@Sun.COM * stmfGetProviderData 33837836SJohn.Forte@Sun.COM * 33847836SJohn.Forte@Sun.COM * Purpose: Get provider data list 33857836SJohn.Forte@Sun.COM * 33867836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 33877836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 33887836SJohn.Forte@Sun.COM * retrieved. 33897836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 33907836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 33917836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 33927836SJohn.Forte@Sun.COM */ 33937836SJohn.Forte@Sun.COM int 33947836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType) 33957836SJohn.Forte@Sun.COM { 33967836SJohn.Forte@Sun.COM return (stmfGetProviderDataProt(providerName, nvl, providerType, 33977836SJohn.Forte@Sun.COM NULL)); 33987836SJohn.Forte@Sun.COM } 33997836SJohn.Forte@Sun.COM 34007836SJohn.Forte@Sun.COM /* 34017836SJohn.Forte@Sun.COM * stmfGetProviderDataProt 34027836SJohn.Forte@Sun.COM * 34037836SJohn.Forte@Sun.COM * Purpose: Get provider data list with token 34047836SJohn.Forte@Sun.COM * 34057836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 34067836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 34077836SJohn.Forte@Sun.COM * retrieved. 34087836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 34097836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 34107836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 34117836SJohn.Forte@Sun.COM * setToken - Returns the stale data token 34127836SJohn.Forte@Sun.COM */ 34137836SJohn.Forte@Sun.COM int 34147836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType, 34157836SJohn.Forte@Sun.COM uint64_t *setToken) 34167836SJohn.Forte@Sun.COM { 34177836SJohn.Forte@Sun.COM int ret; 34187836SJohn.Forte@Sun.COM 34197836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 34207836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34217836SJohn.Forte@Sun.COM } 34227836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 34237836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 34247836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34257836SJohn.Forte@Sun.COM } 34267836SJohn.Forte@Sun.COM /* call init */ 34277836SJohn.Forte@Sun.COM ret = initializeConfig(); 34287836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 34297836SJohn.Forte@Sun.COM return (ret); 34307836SJohn.Forte@Sun.COM } 3431*9585STim.Szeto@Sun.COM return (getProviderData(providerName, nvl, providerType, setToken)); 34327836SJohn.Forte@Sun.COM } 34337836SJohn.Forte@Sun.COM 34347836SJohn.Forte@Sun.COM /* 34357836SJohn.Forte@Sun.COM * stmfGetProviderDataList 34367836SJohn.Forte@Sun.COM * 34377836SJohn.Forte@Sun.COM * Purpose: Get the list of providers currently persisting data 34387836SJohn.Forte@Sun.COM * 34397836SJohn.Forte@Sun.COM * providerList - pointer to pointer to an stmfProviderList structure allocated 34407836SJohn.Forte@Sun.COM * by the caller. Will contain the list of providers on success. 34417836SJohn.Forte@Sun.COM */ 34427836SJohn.Forte@Sun.COM int 34437836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList) 34447836SJohn.Forte@Sun.COM { 34457836SJohn.Forte@Sun.COM int ret; 34467836SJohn.Forte@Sun.COM 34477836SJohn.Forte@Sun.COM ret = psGetProviderDataList(providerList); 34487836SJohn.Forte@Sun.COM switch (ret) { 34497836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 34507836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 34517836SJohn.Forte@Sun.COM break; 34527836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 34537836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 34547836SJohn.Forte@Sun.COM break; 34557836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 34567836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 34577836SJohn.Forte@Sun.COM break; 34587836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 34597836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 34607836SJohn.Forte@Sun.COM break; 34617836SJohn.Forte@Sun.COM default: 34627836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 34637836SJohn.Forte@Sun.COM "stmfGetProviderDataList:psGetProviderDataList" 34647836SJohn.Forte@Sun.COM ":error(%d)", ret); 34657836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 34667836SJohn.Forte@Sun.COM break; 34677836SJohn.Forte@Sun.COM } 34687836SJohn.Forte@Sun.COM 34697836SJohn.Forte@Sun.COM return (ret); 34707836SJohn.Forte@Sun.COM } 34717836SJohn.Forte@Sun.COM 34727836SJohn.Forte@Sun.COM 34737836SJohn.Forte@Sun.COM /* 34747836SJohn.Forte@Sun.COM * stmfGetSessionList 34757836SJohn.Forte@Sun.COM * 34767836SJohn.Forte@Sun.COM * Purpose: Retrieves the session list for a target (devid) 34777836SJohn.Forte@Sun.COM * 34787836SJohn.Forte@Sun.COM * devid - devid of target for which to retrieve session information. 34797836SJohn.Forte@Sun.COM * sessionList - pointer to pointer to stmfSessionList structure 34807836SJohn.Forte@Sun.COM * on success, this contains the list of initiator sessions. 34817836SJohn.Forte@Sun.COM */ 34827836SJohn.Forte@Sun.COM int 34837836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList) 34847836SJohn.Forte@Sun.COM { 34857836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 34867836SJohn.Forte@Sun.COM int fd; 34877836SJohn.Forte@Sun.COM int ioctlRet; 34887836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_SESSION_LIST; 34897836SJohn.Forte@Sun.COM int i; 34907836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 34917836SJohn.Forte@Sun.COM slist_scsi_session_t *fSessionList; 34927836SJohn.Forte@Sun.COM uint8_t ident[260]; 34937836SJohn.Forte@Sun.COM uint32_t fSessionListSize; 34947836SJohn.Forte@Sun.COM 34957836SJohn.Forte@Sun.COM if (sessionList == NULL || devid == NULL) { 34967836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 34977836SJohn.Forte@Sun.COM } 34987836SJohn.Forte@Sun.COM 34997836SJohn.Forte@Sun.COM /* call init */ 35007836SJohn.Forte@Sun.COM ret = initializeConfig(); 35017836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 35027836SJohn.Forte@Sun.COM return (ret); 35037836SJohn.Forte@Sun.COM } 35047836SJohn.Forte@Sun.COM 35057836SJohn.Forte@Sun.COM /* 35067836SJohn.Forte@Sun.COM * Open control node for stmf 35077836SJohn.Forte@Sun.COM */ 35087836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 35097836SJohn.Forte@Sun.COM return (ret); 35107836SJohn.Forte@Sun.COM 35117836SJohn.Forte@Sun.COM /* 35127836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 35137836SJohn.Forte@Sun.COM */ 3514*9585STim.Szeto@Sun.COM fSessionListSize = ALLOC_SESSION; 35157836SJohn.Forte@Sun.COM fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t)); 35167836SJohn.Forte@Sun.COM fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize); 35177836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 35187836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 35197836SJohn.Forte@Sun.COM } 35207836SJohn.Forte@Sun.COM 35217836SJohn.Forte@Sun.COM ident[IDENT_LENGTH_BYTE] = devid->identLength; 35227836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1], 35237836SJohn.Forte@Sun.COM devid->identLength); 35247836SJohn.Forte@Sun.COM 35257836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 35267836SJohn.Forte@Sun.COM /* 35277836SJohn.Forte@Sun.COM * Issue ioctl to get the session list 35287836SJohn.Forte@Sun.COM */ 35297836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 35307836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident; 35317836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ident); 35327836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 35337836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 35347836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35357836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 35367836SJohn.Forte@Sun.COM switch (errno) { 35377836SJohn.Forte@Sun.COM case EBUSY: 35387836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35397836SJohn.Forte@Sun.COM break; 3540*9585STim.Szeto@Sun.COM case EPERM: 35417836SJohn.Forte@Sun.COM case EACCES: 35427836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 35437836SJohn.Forte@Sun.COM break; 35447836SJohn.Forte@Sun.COM default: 35457836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 35467836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl errno(%d)", 35477836SJohn.Forte@Sun.COM errno); 35487836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 35497836SJohn.Forte@Sun.COM break; 35507836SJohn.Forte@Sun.COM } 35517836SJohn.Forte@Sun.COM goto done; 35527836SJohn.Forte@Sun.COM } 35537836SJohn.Forte@Sun.COM /* 35547836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 35557836SJohn.Forte@Sun.COM */ 3556*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) { 35577836SJohn.Forte@Sun.COM fSessionListSize = stmfIoctl.stmf_obuf_max_nentries * 35587836SJohn.Forte@Sun.COM sizeof (slist_scsi_session_t); 35597836SJohn.Forte@Sun.COM fSessionList = realloc(fSessionList, fSessionListSize); 35607836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 35617836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 35627836SJohn.Forte@Sun.COM } 35637836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 35647836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 35657836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35667836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 35677836SJohn.Forte@Sun.COM switch (errno) { 35687836SJohn.Forte@Sun.COM case EBUSY: 35697836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35707836SJohn.Forte@Sun.COM break; 3571*9585STim.Szeto@Sun.COM case EPERM: 35727836SJohn.Forte@Sun.COM case EACCES: 35737836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 35747836SJohn.Forte@Sun.COM break; 35757836SJohn.Forte@Sun.COM default: 35767836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 35777836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl " 35787836SJohn.Forte@Sun.COM "errno(%d)", errno); 35797836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 35807836SJohn.Forte@Sun.COM break; 35817836SJohn.Forte@Sun.COM } 35827836SJohn.Forte@Sun.COM goto done; 35837836SJohn.Forte@Sun.COM } 35847836SJohn.Forte@Sun.COM } 35857836SJohn.Forte@Sun.COM 35867836SJohn.Forte@Sun.COM /* 35877836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 35887836SJohn.Forte@Sun.COM */ 35897836SJohn.Forte@Sun.COM *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) + 35907836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession)); 35917836SJohn.Forte@Sun.COM if (*sessionList == NULL) { 35927836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 35937836SJohn.Forte@Sun.COM free(sessionList); 35947836SJohn.Forte@Sun.COM goto done; 35957836SJohn.Forte@Sun.COM } 35967836SJohn.Forte@Sun.COM 35977836SJohn.Forte@Sun.COM (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 35987836SJohn.Forte@Sun.COM 35997836SJohn.Forte@Sun.COM /* 36007836SJohn.Forte@Sun.COM * copy session info to caller's buffer 36017836SJohn.Forte@Sun.COM */ 36027836SJohn.Forte@Sun.COM for (i = 0; i < (*sessionList)->cnt; i++) { 36037836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.identLength = 36047836SJohn.Forte@Sun.COM fSessionList->initiator[IDENT_LENGTH_BYTE]; 36057836SJohn.Forte@Sun.COM bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]), 36067836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.ident, 36077836SJohn.Forte@Sun.COM STMF_IDENT_LENGTH); 36087836SJohn.Forte@Sun.COM bcopy(&(fSessionList->alias), 36097836SJohn.Forte@Sun.COM &((*sessionList)->session[i].alias), 36107836SJohn.Forte@Sun.COM sizeof ((*sessionList)->session[i].alias)); 36117836SJohn.Forte@Sun.COM bcopy(&(fSessionList++->creation_time), 36127836SJohn.Forte@Sun.COM &((*sessionList)->session[i].creationTime), 36137836SJohn.Forte@Sun.COM sizeof (time_t)); 36147836SJohn.Forte@Sun.COM } 36157836SJohn.Forte@Sun.COM done: 36167836SJohn.Forte@Sun.COM (void) close(fd); 36177836SJohn.Forte@Sun.COM return (ret); 36187836SJohn.Forte@Sun.COM } 36197836SJohn.Forte@Sun.COM 36207836SJohn.Forte@Sun.COM /* 36217836SJohn.Forte@Sun.COM * stmfGetTargetGroupList 36227836SJohn.Forte@Sun.COM * 36237836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target groups 36247836SJohn.Forte@Sun.COM * 36257836SJohn.Forte@Sun.COM * targetGroupList - pointer to a pointer to an stmfGroupList structure. On 36267836SJohn.Forte@Sun.COM * success, it contains the list of target groups. 36277836SJohn.Forte@Sun.COM */ 36287836SJohn.Forte@Sun.COM int 36297836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList) 36307836SJohn.Forte@Sun.COM { 36317836SJohn.Forte@Sun.COM int ret; 36327836SJohn.Forte@Sun.COM 36337836SJohn.Forte@Sun.COM if (targetGroupList == NULL) { 36347836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36357836SJohn.Forte@Sun.COM } 36367836SJohn.Forte@Sun.COM 3637*9585STim.Szeto@Sun.COM ret = groupListIoctl(targetGroupList, TARGET_GROUP); 36387836SJohn.Forte@Sun.COM return (ret); 36397836SJohn.Forte@Sun.COM } 36407836SJohn.Forte@Sun.COM 36417836SJohn.Forte@Sun.COM /* 36427836SJohn.Forte@Sun.COM * stmfGetTargetGroupMembers 36437836SJohn.Forte@Sun.COM * 36447836SJohn.Forte@Sun.COM * Purpose: Retrieves the group members for a target group 36457836SJohn.Forte@Sun.COM * 36467836SJohn.Forte@Sun.COM * groupName - name of target group for which to retrieve members. 36477836SJohn.Forte@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 36487836SJohn.Forte@Sun.COM * on success, this contains the list of group members. 36497836SJohn.Forte@Sun.COM */ 36507836SJohn.Forte@Sun.COM int 36517836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName, 36527836SJohn.Forte@Sun.COM stmfGroupProperties **groupProp) 36537836SJohn.Forte@Sun.COM { 36547836SJohn.Forte@Sun.COM int ret; 36557836SJohn.Forte@Sun.COM 36567836SJohn.Forte@Sun.COM if (groupName == NULL || groupProp == NULL) { 36577836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36587836SJohn.Forte@Sun.COM } 36597836SJohn.Forte@Sun.COM 3660*9585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP); 36617836SJohn.Forte@Sun.COM 36627836SJohn.Forte@Sun.COM return (ret); 36637836SJohn.Forte@Sun.COM } 36647836SJohn.Forte@Sun.COM 36657836SJohn.Forte@Sun.COM /* 36667836SJohn.Forte@Sun.COM * stmfGetTargetList 36677836SJohn.Forte@Sun.COM * 36687836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target ports 36697836SJohn.Forte@Sun.COM * 36707836SJohn.Forte@Sun.COM * targetList - pointer to a pointer to an stmfDevidList structure. 36717836SJohn.Forte@Sun.COM * On success, it contains the list of local ports (target). 36727836SJohn.Forte@Sun.COM */ 36737836SJohn.Forte@Sun.COM int 36747836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList) 36757836SJohn.Forte@Sun.COM { 36767836SJohn.Forte@Sun.COM int ret; 36777836SJohn.Forte@Sun.COM int fd; 36787836SJohn.Forte@Sun.COM int ioctlRet; 36797836SJohn.Forte@Sun.COM int i; 36807836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 36817836SJohn.Forte@Sun.COM /* framework target port list */ 3682*9585STim.Szeto@Sun.COM slist_target_port_t *fTargetList, *fTargetListP = NULL; 36837836SJohn.Forte@Sun.COM uint32_t fTargetListSize; 36847836SJohn.Forte@Sun.COM 36857836SJohn.Forte@Sun.COM if (targetList == NULL) { 36867836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36877836SJohn.Forte@Sun.COM } 36887836SJohn.Forte@Sun.COM 36897836SJohn.Forte@Sun.COM /* call init */ 36907836SJohn.Forte@Sun.COM ret = initializeConfig(); 36917836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 36927836SJohn.Forte@Sun.COM return (ret); 36937836SJohn.Forte@Sun.COM } 36947836SJohn.Forte@Sun.COM 36957836SJohn.Forte@Sun.COM /* 36967836SJohn.Forte@Sun.COM * Open control node for stmf 36977836SJohn.Forte@Sun.COM */ 36987836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 36997836SJohn.Forte@Sun.COM return (ret); 37007836SJohn.Forte@Sun.COM 37017836SJohn.Forte@Sun.COM /* 37027836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 37037836SJohn.Forte@Sun.COM */ 3704*9585STim.Szeto@Sun.COM fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t); 37058252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 37068252SJohn.Forte@Sun.COM (slist_target_port_t *)calloc(1, fTargetListSize); 37077836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 3708*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37097836SJohn.Forte@Sun.COM goto done; 37107836SJohn.Forte@Sun.COM } 37117836SJohn.Forte@Sun.COM 37127836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 37137836SJohn.Forte@Sun.COM /* 37148252SJohn.Forte@Sun.COM * Issue ioctl to retrieve target list 37157836SJohn.Forte@Sun.COM */ 37167836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 37177836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 37187836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 37197836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl); 37207836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37217836SJohn.Forte@Sun.COM switch (errno) { 37227836SJohn.Forte@Sun.COM case EBUSY: 37237836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37247836SJohn.Forte@Sun.COM break; 3725*9585STim.Szeto@Sun.COM case EPERM: 37267836SJohn.Forte@Sun.COM case EACCES: 37277836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37287836SJohn.Forte@Sun.COM break; 37297836SJohn.Forte@Sun.COM default: 37307836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37317836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", errno); 37327836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37337836SJohn.Forte@Sun.COM break; 37347836SJohn.Forte@Sun.COM } 37357836SJohn.Forte@Sun.COM goto done; 37367836SJohn.Forte@Sun.COM } 37377836SJohn.Forte@Sun.COM /* 37387836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 37397836SJohn.Forte@Sun.COM */ 3740*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) { 37417836SJohn.Forte@Sun.COM fTargetListSize = stmfIoctl.stmf_obuf_max_nentries * 37428116SJohn.Forte@Sun.COM sizeof (slist_target_port_t); 37438252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 37448252SJohn.Forte@Sun.COM realloc(fTargetList, fTargetListSize); 37457836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 3746*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3747*9585STim.Szeto@Sun.COM goto done; 37487836SJohn.Forte@Sun.COM } 37497836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 37507836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 37517836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, 37527836SJohn.Forte@Sun.COM &stmfIoctl); 37537836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37547836SJohn.Forte@Sun.COM switch (errno) { 37557836SJohn.Forte@Sun.COM case EBUSY: 37567836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37577836SJohn.Forte@Sun.COM break; 3758*9585STim.Szeto@Sun.COM case EPERM: 37597836SJohn.Forte@Sun.COM case EACCES: 37607836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37617836SJohn.Forte@Sun.COM break; 37627836SJohn.Forte@Sun.COM default: 37637836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37647836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", 37657836SJohn.Forte@Sun.COM errno); 37667836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37677836SJohn.Forte@Sun.COM break; 37687836SJohn.Forte@Sun.COM } 37697836SJohn.Forte@Sun.COM goto done; 37707836SJohn.Forte@Sun.COM } 37717836SJohn.Forte@Sun.COM } 37727836SJohn.Forte@Sun.COM 37737836SJohn.Forte@Sun.COM *targetList = (stmfDevidList *)calloc(1, 37747836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) + 37757836SJohn.Forte@Sun.COM sizeof (stmfDevidList)); 3776*9585STim.Szeto@Sun.COM if (*targetList == NULL) { 3777*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3778*9585STim.Szeto@Sun.COM goto done; 3779*9585STim.Szeto@Sun.COM } 37807836SJohn.Forte@Sun.COM 37817836SJohn.Forte@Sun.COM (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 37827836SJohn.Forte@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) { 37837836SJohn.Forte@Sun.COM (*targetList)->devid[i].identLength = 37847836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]; 37857836SJohn.Forte@Sun.COM bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1], 37867836SJohn.Forte@Sun.COM &(*targetList)->devid[i].ident, 37877836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]); 37887836SJohn.Forte@Sun.COM } 37897836SJohn.Forte@Sun.COM 37907836SJohn.Forte@Sun.COM done: 37917836SJohn.Forte@Sun.COM (void) close(fd); 37928252SJohn.Forte@Sun.COM free(fTargetListP); 37937836SJohn.Forte@Sun.COM return (ret); 37947836SJohn.Forte@Sun.COM } 37957836SJohn.Forte@Sun.COM 37967836SJohn.Forte@Sun.COM /* 37977836SJohn.Forte@Sun.COM * stmfGetTargetProperties 37987836SJohn.Forte@Sun.COM * 37997836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 38007836SJohn.Forte@Sun.COM * 38017836SJohn.Forte@Sun.COM * devid - devid of the target for which to retrieve properties 38027836SJohn.Forte@Sun.COM * targetProps - pointer to an stmfTargetProperties structure. 38037836SJohn.Forte@Sun.COM * On success, it contains the target properties for 38047836SJohn.Forte@Sun.COM * the specified devid. 38057836SJohn.Forte@Sun.COM */ 38067836SJohn.Forte@Sun.COM int 38077836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps) 38087836SJohn.Forte@Sun.COM { 38097836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 38107836SJohn.Forte@Sun.COM int fd; 38117836SJohn.Forte@Sun.COM int ioctlRet; 38127836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 38137836SJohn.Forte@Sun.COM sioc_target_port_props_t targetProperties; 38147836SJohn.Forte@Sun.COM 38157836SJohn.Forte@Sun.COM if (devid == NULL || targetProps == NULL) { 38167836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38177836SJohn.Forte@Sun.COM } 38187836SJohn.Forte@Sun.COM 38197836SJohn.Forte@Sun.COM /* call init */ 38207836SJohn.Forte@Sun.COM ret = initializeConfig(); 38217836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 38227836SJohn.Forte@Sun.COM return (ret); 38237836SJohn.Forte@Sun.COM } 38247836SJohn.Forte@Sun.COM 38257836SJohn.Forte@Sun.COM /* 38267836SJohn.Forte@Sun.COM * Open control node for stmf 38277836SJohn.Forte@Sun.COM */ 38287836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 38297836SJohn.Forte@Sun.COM return (ret); 38307836SJohn.Forte@Sun.COM 38317836SJohn.Forte@Sun.COM targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength; 38327836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1], 38337836SJohn.Forte@Sun.COM devid->identLength); 38347836SJohn.Forte@Sun.COM 38357836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 38367836SJohn.Forte@Sun.COM /* 38377836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 38387836SJohn.Forte@Sun.COM */ 38397836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 38407836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id); 38417836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id; 38427836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties; 38437836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (targetProperties); 38447836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES, 38457836SJohn.Forte@Sun.COM &stmfIoctl); 38467836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 38477836SJohn.Forte@Sun.COM switch (errno) { 38487836SJohn.Forte@Sun.COM case EBUSY: 38497836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 38507836SJohn.Forte@Sun.COM break; 3851*9585STim.Szeto@Sun.COM case EPERM: 38527836SJohn.Forte@Sun.COM case EACCES: 38537836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 38547836SJohn.Forte@Sun.COM break; 38557836SJohn.Forte@Sun.COM case ENOENT: 38567836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 38577836SJohn.Forte@Sun.COM break; 38587836SJohn.Forte@Sun.COM default: 38597836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 38607836SJohn.Forte@Sun.COM "stmfGetTargetProperties:ioctl errno(%d)", 38617836SJohn.Forte@Sun.COM errno); 38627836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 38637836SJohn.Forte@Sun.COM break; 38647836SJohn.Forte@Sun.COM } 38657836SJohn.Forte@Sun.COM goto done; 38667836SJohn.Forte@Sun.COM } 38677836SJohn.Forte@Sun.COM 38687836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_provider_name, targetProps->providerName, 38697836SJohn.Forte@Sun.COM sizeof (targetProperties.tgt_provider_name)); 38707836SJohn.Forte@Sun.COM if (targetProperties.tgt_state == STMF_STATE_ONLINE) { 38717836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINE; 38727836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) { 38737836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINE; 38747836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) { 38757836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINING; 38767836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) { 38777836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINING; 38787836SJohn.Forte@Sun.COM } 38797836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_alias, targetProps->alias, 38807836SJohn.Forte@Sun.COM sizeof (targetProps->alias)); 38817836SJohn.Forte@Sun.COM done: 38827836SJohn.Forte@Sun.COM (void) close(fd); 38837836SJohn.Forte@Sun.COM return (ret); 38847836SJohn.Forte@Sun.COM } 38857836SJohn.Forte@Sun.COM 38867836SJohn.Forte@Sun.COM /* 38877836SJohn.Forte@Sun.COM * stmfGetLogicalUnitList 38887836SJohn.Forte@Sun.COM * 38897836SJohn.Forte@Sun.COM * Purpose: Retrieves list of logical unit Object IDs 38907836SJohn.Forte@Sun.COM * 38917836SJohn.Forte@Sun.COM * luList - pointer to a pointer to a stmfGuidList structure. On success, 38927836SJohn.Forte@Sun.COM * it contains the list of logical unit guids. 38937836SJohn.Forte@Sun.COM * 38947836SJohn.Forte@Sun.COM */ 38957836SJohn.Forte@Sun.COM int 38967836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList) 38977836SJohn.Forte@Sun.COM { 38987836SJohn.Forte@Sun.COM int ret; 38997836SJohn.Forte@Sun.COM int fd; 39007836SJohn.Forte@Sun.COM int ioctlRet; 39017836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_LU_LIST; 3902*9585STim.Szeto@Sun.COM int i; 39037836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 39047836SJohn.Forte@Sun.COM slist_lu_t *fLuList; 39057836SJohn.Forte@Sun.COM uint32_t fLuListSize; 3906*9585STim.Szeto@Sun.COM uint32_t listCnt; 39077836SJohn.Forte@Sun.COM 39087836SJohn.Forte@Sun.COM if (luList == NULL) { 39097836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39107836SJohn.Forte@Sun.COM } 39117836SJohn.Forte@Sun.COM 39127836SJohn.Forte@Sun.COM /* call init */ 39137836SJohn.Forte@Sun.COM ret = initializeConfig(); 39147836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39157836SJohn.Forte@Sun.COM return (ret); 39167836SJohn.Forte@Sun.COM } 39177836SJohn.Forte@Sun.COM 39187836SJohn.Forte@Sun.COM /* 39197836SJohn.Forte@Sun.COM * Open control node for stmf 39207836SJohn.Forte@Sun.COM */ 39217836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 39227836SJohn.Forte@Sun.COM return (ret); 39237836SJohn.Forte@Sun.COM 39247836SJohn.Forte@Sun.COM /* 39257836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 39267836SJohn.Forte@Sun.COM */ 3927*9585STim.Szeto@Sun.COM fLuListSize = ALLOC_LU; 39287836SJohn.Forte@Sun.COM fLuListSize = fLuListSize * (sizeof (slist_lu_t)); 39297836SJohn.Forte@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 39307836SJohn.Forte@Sun.COM if (fLuList == NULL) { 3931*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3932*9585STim.Szeto@Sun.COM goto done; 39337836SJohn.Forte@Sun.COM } 39347836SJohn.Forte@Sun.COM 39357836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 39367836SJohn.Forte@Sun.COM /* 39377836SJohn.Forte@Sun.COM * Issue ioctl to get the LU list 39387836SJohn.Forte@Sun.COM */ 39397836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 39407836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 39417836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 39427836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 39437836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39447836SJohn.Forte@Sun.COM switch (errno) { 39457836SJohn.Forte@Sun.COM case EBUSY: 39467836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39477836SJohn.Forte@Sun.COM break; 3948*9585STim.Szeto@Sun.COM case EPERM: 39497836SJohn.Forte@Sun.COM case EACCES: 39507836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39517836SJohn.Forte@Sun.COM break; 39527836SJohn.Forte@Sun.COM default: 39537836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39547836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:ioctl errno(%d)", 39557836SJohn.Forte@Sun.COM errno); 39567836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39577836SJohn.Forte@Sun.COM break; 39587836SJohn.Forte@Sun.COM } 39597836SJohn.Forte@Sun.COM goto done; 39607836SJohn.Forte@Sun.COM } 39617836SJohn.Forte@Sun.COM /* 39627836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 39637836SJohn.Forte@Sun.COM */ 3964*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) { 39657836SJohn.Forte@Sun.COM fLuListSize = stmfIoctl.stmf_obuf_max_nentries * 39667836SJohn.Forte@Sun.COM sizeof (slist_lu_t); 3967*9585STim.Szeto@Sun.COM free(fLuList); 3968*9585STim.Szeto@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 39697836SJohn.Forte@Sun.COM if (fLuList == NULL) { 3970*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 3971*9585STim.Szeto@Sun.COM goto done; 39727836SJohn.Forte@Sun.COM } 39737836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 39747836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 39757836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 39767836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39777836SJohn.Forte@Sun.COM switch (errno) { 39787836SJohn.Forte@Sun.COM case EBUSY: 39797836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39807836SJohn.Forte@Sun.COM break; 3981*9585STim.Szeto@Sun.COM case EPERM: 39827836SJohn.Forte@Sun.COM case EACCES: 39837836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39847836SJohn.Forte@Sun.COM break; 39857836SJohn.Forte@Sun.COM default: 39867836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39877836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:" 39887836SJohn.Forte@Sun.COM "ioctl errno(%d)", errno); 39897836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39907836SJohn.Forte@Sun.COM break; 39917836SJohn.Forte@Sun.COM } 39927836SJohn.Forte@Sun.COM goto done; 39937836SJohn.Forte@Sun.COM } 39947836SJohn.Forte@Sun.COM } 39957836SJohn.Forte@Sun.COM 39967836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39977836SJohn.Forte@Sun.COM goto done; 39987836SJohn.Forte@Sun.COM } 39997836SJohn.Forte@Sun.COM 4000*9585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 40017836SJohn.Forte@Sun.COM 40027836SJohn.Forte@Sun.COM /* 40037836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 40047836SJohn.Forte@Sun.COM */ 40057836SJohn.Forte@Sun.COM *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) + 4006*9585STim.Szeto@Sun.COM listCnt * sizeof (stmfGuid)); 40077836SJohn.Forte@Sun.COM if (*luList == NULL) { 40087836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 40097836SJohn.Forte@Sun.COM goto done; 40107836SJohn.Forte@Sun.COM } 40117836SJohn.Forte@Sun.COM 4012*9585STim.Szeto@Sun.COM (*luList)->cnt = listCnt; 4013*9585STim.Szeto@Sun.COM 4014*9585STim.Szeto@Sun.COM /* copy to caller's buffer */ 4015*9585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 4016*9585STim.Szeto@Sun.COM bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid, 4017*9585STim.Szeto@Sun.COM sizeof (stmfGuid)); 4018*9585STim.Szeto@Sun.COM } 4019*9585STim.Szeto@Sun.COM 40207836SJohn.Forte@Sun.COM /* 4021*9585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 40227836SJohn.Forte@Sun.COM */ 4023*9585STim.Szeto@Sun.COM qsort((void *)&((*luList)->guid[0]), (*luList)->cnt, 4024*9585STim.Szeto@Sun.COM sizeof (stmfGuid), guidCompare); 40257836SJohn.Forte@Sun.COM 40267836SJohn.Forte@Sun.COM done: 40277836SJohn.Forte@Sun.COM (void) close(fd); 40287836SJohn.Forte@Sun.COM /* 40297836SJohn.Forte@Sun.COM * free internal buffers 40307836SJohn.Forte@Sun.COM */ 40317836SJohn.Forte@Sun.COM free(fLuList); 40327836SJohn.Forte@Sun.COM return (ret); 40337836SJohn.Forte@Sun.COM } 40347836SJohn.Forte@Sun.COM 40357836SJohn.Forte@Sun.COM /* 40367836SJohn.Forte@Sun.COM * stmfGetLogicalUnitProperties 40377836SJohn.Forte@Sun.COM * 40387836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 40397836SJohn.Forte@Sun.COM * 40407836SJohn.Forte@Sun.COM * lu - guid of the logical unit for which to retrieve properties 40417836SJohn.Forte@Sun.COM * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success, 40427836SJohn.Forte@Sun.COM * it contains the logical unit properties for the specified guid. 40437836SJohn.Forte@Sun.COM */ 40447836SJohn.Forte@Sun.COM int 40457836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps) 40467836SJohn.Forte@Sun.COM { 40477836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 40487836SJohn.Forte@Sun.COM int stmfRet; 40497836SJohn.Forte@Sun.COM int fd; 40507836SJohn.Forte@Sun.COM int ioctlRet; 40517836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_GET_LU_PROPERTIES; 40527836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 40537836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 40547836SJohn.Forte@Sun.COM sioc_lu_props_t fLuProps; 40557836SJohn.Forte@Sun.COM 4056*9585STim.Szeto@Sun.COM if (lu == NULL || luProps == NULL) { 4057*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 40587836SJohn.Forte@Sun.COM } 40597836SJohn.Forte@Sun.COM 40607836SJohn.Forte@Sun.COM bzero(luProps, sizeof (stmfLogicalUnitProperties)); 40617836SJohn.Forte@Sun.COM 40627836SJohn.Forte@Sun.COM /* call init */ 40637836SJohn.Forte@Sun.COM ret = initializeConfig(); 40647836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 40657836SJohn.Forte@Sun.COM return (ret); 40667836SJohn.Forte@Sun.COM } 40677836SJohn.Forte@Sun.COM 40687836SJohn.Forte@Sun.COM /* 40697836SJohn.Forte@Sun.COM * Open control node for stmf 40707836SJohn.Forte@Sun.COM */ 40717836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 40727836SJohn.Forte@Sun.COM return (ret); 40737836SJohn.Forte@Sun.COM 40747836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 40757836SJohn.Forte@Sun.COM /* 40767836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 40777836SJohn.Forte@Sun.COM */ 40787836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 40797836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 40807836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 40817836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps; 40827836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (fLuProps); 40837836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40847836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40857836SJohn.Forte@Sun.COM switch (errno) { 40867836SJohn.Forte@Sun.COM case EBUSY: 40877836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40887836SJohn.Forte@Sun.COM break; 4089*9585STim.Szeto@Sun.COM case EPERM: 40907836SJohn.Forte@Sun.COM case EACCES: 40917836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40927836SJohn.Forte@Sun.COM break; 40937836SJohn.Forte@Sun.COM case ENOENT: 40947836SJohn.Forte@Sun.COM stmfRet = stmfGetViewEntryList(lu, 40957836SJohn.Forte@Sun.COM &viewEntryList); 40967836SJohn.Forte@Sun.COM if (stmfRet == STMF_STATUS_SUCCESS) { 40977836SJohn.Forte@Sun.COM luProps->status = 40987836SJohn.Forte@Sun.COM STMF_LOGICAL_UNIT_UNREGISTERED; 40997836SJohn.Forte@Sun.COM if (viewEntryList->cnt > 0) { 41007836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 41017836SJohn.Forte@Sun.COM } else { 41027836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 41037836SJohn.Forte@Sun.COM } 41047836SJohn.Forte@Sun.COM } else { 41057836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 41067836SJohn.Forte@Sun.COM } 41077836SJohn.Forte@Sun.COM stmfFreeMemory(viewEntryList); 41087836SJohn.Forte@Sun.COM break; 41097836SJohn.Forte@Sun.COM default: 41107836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 41117836SJohn.Forte@Sun.COM "stmfGetLogicalUnit:ioctl errno(%d)", 41127836SJohn.Forte@Sun.COM errno); 41137836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 41147836SJohn.Forte@Sun.COM break; 41157836SJohn.Forte@Sun.COM } 41167836SJohn.Forte@Sun.COM goto done; 41177836SJohn.Forte@Sun.COM } 41187836SJohn.Forte@Sun.COM 41197836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_provider_name, luProps->providerName, 41207836SJohn.Forte@Sun.COM sizeof (fLuProps.lu_provider_name)); 41217836SJohn.Forte@Sun.COM if (fLuProps.lu_state == STMF_STATE_ONLINE) { 41227836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINE; 41237836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) { 41247836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINE; 41257836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_ONLINING) { 41267836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINING; 41277836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) { 41287836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINING; 41297836SJohn.Forte@Sun.COM } 41307836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias)); 41317836SJohn.Forte@Sun.COM done: 41327836SJohn.Forte@Sun.COM (void) close(fd); 41337836SJohn.Forte@Sun.COM return (ret); 41347836SJohn.Forte@Sun.COM } 41357836SJohn.Forte@Sun.COM 41367836SJohn.Forte@Sun.COM /* 41377836SJohn.Forte@Sun.COM * stmfGetState 41387836SJohn.Forte@Sun.COM * 41397836SJohn.Forte@Sun.COM * Purpose: retrieve the current state of the stmf module 41407836SJohn.Forte@Sun.COM * 41417836SJohn.Forte@Sun.COM * state - pointer to stmfState structure allocated by the caller 41427836SJohn.Forte@Sun.COM * On success, contains the state of stmf 41437836SJohn.Forte@Sun.COM */ 41447836SJohn.Forte@Sun.COM int 41457836SJohn.Forte@Sun.COM stmfGetState(stmfState *state) 41467836SJohn.Forte@Sun.COM { 41477836SJohn.Forte@Sun.COM int ret; 41487836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 41497836SJohn.Forte@Sun.COM 41507836SJohn.Forte@Sun.COM if (state == NULL) { 41517836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41527836SJohn.Forte@Sun.COM } 41537836SJohn.Forte@Sun.COM 41547836SJohn.Forte@Sun.COM ret = getStmfState(&iState); 41557836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 41567836SJohn.Forte@Sun.COM return (ret); 41577836SJohn.Forte@Sun.COM } 41587836SJohn.Forte@Sun.COM switch (iState.state) { 41597836SJohn.Forte@Sun.COM case STMF_STATE_ONLINE: 41607836SJohn.Forte@Sun.COM state->operationalState = 41617836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINE; 41627836SJohn.Forte@Sun.COM break; 41637836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINE: 41647836SJohn.Forte@Sun.COM state->operationalState = 41657836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINE; 41667836SJohn.Forte@Sun.COM break; 41677836SJohn.Forte@Sun.COM case STMF_STATE_ONLINING: 41687836SJohn.Forte@Sun.COM state->operationalState = 41697836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINING; 41707836SJohn.Forte@Sun.COM break; 41717836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINING: 41727836SJohn.Forte@Sun.COM state->operationalState = 41737836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINING; 41747836SJohn.Forte@Sun.COM break; 41757836SJohn.Forte@Sun.COM default: 41767836SJohn.Forte@Sun.COM state->operationalState = 41777836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_UNKNOWN; 41787836SJohn.Forte@Sun.COM break; 41797836SJohn.Forte@Sun.COM } 41807836SJohn.Forte@Sun.COM switch (iState.config_state) { 41817836SJohn.Forte@Sun.COM case STMF_CONFIG_NONE: 41827836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_NONE; 41837836SJohn.Forte@Sun.COM break; 41847836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT: 41857836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_INIT; 41867836SJohn.Forte@Sun.COM break; 41877836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT_DONE: 41887836SJohn.Forte@Sun.COM state->configState = 41897836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_INIT_DONE; 41907836SJohn.Forte@Sun.COM break; 41917836SJohn.Forte@Sun.COM default: 41927836SJohn.Forte@Sun.COM state->configState = 41937836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_UNKNOWN; 41947836SJohn.Forte@Sun.COM break; 41957836SJohn.Forte@Sun.COM } 41967836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 41977836SJohn.Forte@Sun.COM } 41987836SJohn.Forte@Sun.COM 41997836SJohn.Forte@Sun.COM /* 42007836SJohn.Forte@Sun.COM * stmfGetViewEntryList 42017836SJohn.Forte@Sun.COM * 42027836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of view entries for the specified 42037836SJohn.Forte@Sun.COM * logical unit. 42047836SJohn.Forte@Sun.COM * 42057836SJohn.Forte@Sun.COM * lu - the guid of the logical unit for which to retrieve the view entry list 42067836SJohn.Forte@Sun.COM * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On 42077836SJohn.Forte@Sun.COM * success, contains the list of view entries. 42087836SJohn.Forte@Sun.COM */ 42097836SJohn.Forte@Sun.COM int 42107836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList) 42117836SJohn.Forte@Sun.COM { 42127836SJohn.Forte@Sun.COM int ret; 4213*9585STim.Szeto@Sun.COM int fd; 4214*9585STim.Szeto@Sun.COM int ioctlRet; 4215*9585STim.Szeto@Sun.COM int cmd = STMF_IOCTL_LU_VE_LIST; 4216*9585STim.Szeto@Sun.COM int i; 4217*9585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 4218*9585STim.Szeto@Sun.COM stmf_view_op_entry_t *fVeList; 4219*9585STim.Szeto@Sun.COM uint32_t fVeListSize; 4220*9585STim.Szeto@Sun.COM uint32_t listCnt; 42217836SJohn.Forte@Sun.COM 42227836SJohn.Forte@Sun.COM if (lu == NULL || viewEntryList == NULL) { 42237836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 42247836SJohn.Forte@Sun.COM } 42257836SJohn.Forte@Sun.COM 4226*9585STim.Szeto@Sun.COM /* call init */ 4227*9585STim.Szeto@Sun.COM ret = initializeConfig(); 4228*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4229*9585STim.Szeto@Sun.COM return (ret); 4230*9585STim.Szeto@Sun.COM } 4231*9585STim.Szeto@Sun.COM 4232*9585STim.Szeto@Sun.COM /* 4233*9585STim.Szeto@Sun.COM * Open control node for stmf 4234*9585STim.Szeto@Sun.COM */ 4235*9585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4236*9585STim.Szeto@Sun.COM return (ret); 4237*9585STim.Szeto@Sun.COM 4238*9585STim.Szeto@Sun.COM /* 4239*9585STim.Szeto@Sun.COM * Allocate ioctl input buffer 4240*9585STim.Szeto@Sun.COM */ 4241*9585STim.Szeto@Sun.COM fVeListSize = ALLOC_VE; 4242*9585STim.Szeto@Sun.COM fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t)); 4243*9585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 4244*9585STim.Szeto@Sun.COM if (fVeList == NULL) { 4245*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 4246*9585STim.Szeto@Sun.COM goto done; 4247*9585STim.Szeto@Sun.COM } 4248*9585STim.Szeto@Sun.COM 4249*9585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 4250*9585STim.Szeto@Sun.COM /* 4251*9585STim.Szeto@Sun.COM * Issue ioctl to get the LU list 4252*9585STim.Szeto@Sun.COM */ 4253*9585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 4254*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 4255*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 4256*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 4257*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 4258*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 4259*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 4260*9585STim.Szeto@Sun.COM switch (errno) { 4261*9585STim.Szeto@Sun.COM case EBUSY: 4262*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 4263*9585STim.Szeto@Sun.COM break; 4264*9585STim.Szeto@Sun.COM case EPERM: 4265*9585STim.Szeto@Sun.COM case EACCES: 4266*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 4267*9585STim.Szeto@Sun.COM break; 4268*9585STim.Szeto@Sun.COM default: 4269*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 4270*9585STim.Szeto@Sun.COM "stmfGetViewEntryList:ioctl errno(%d)", 4271*9585STim.Szeto@Sun.COM errno); 4272*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 4273*9585STim.Szeto@Sun.COM break; 4274*9585STim.Szeto@Sun.COM } 4275*9585STim.Szeto@Sun.COM goto done; 4276*9585STim.Szeto@Sun.COM } 4277*9585STim.Szeto@Sun.COM /* 4278*9585STim.Szeto@Sun.COM * Check whether input buffer was large enough 4279*9585STim.Szeto@Sun.COM */ 4280*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) { 4281*9585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 4282*9585STim.Szeto@Sun.COM fVeListSize = stmfIoctl.stmf_obuf_max_nentries * 4283*9585STim.Szeto@Sun.COM sizeof (stmf_view_op_entry_t); 4284*9585STim.Szeto@Sun.COM free(fVeList); 4285*9585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 4286*9585STim.Szeto@Sun.COM if (fVeList == NULL) { 4287*9585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 4288*9585STim.Szeto@Sun.COM } 4289*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 4290*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 4291*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 4292*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 4293*9585STim.Szeto@Sun.COM switch (errno) { 4294*9585STim.Szeto@Sun.COM case EBUSY: 4295*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 4296*9585STim.Szeto@Sun.COM break; 4297*9585STim.Szeto@Sun.COM case EPERM: 4298*9585STim.Szeto@Sun.COM case EACCES: 4299*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 4300*9585STim.Szeto@Sun.COM break; 4301*9585STim.Szeto@Sun.COM default: 4302*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 4303*9585STim.Szeto@Sun.COM "stmfGetLogicalUnitList:" 4304*9585STim.Szeto@Sun.COM "ioctl errno(%d)", errno); 4305*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 4306*9585STim.Szeto@Sun.COM break; 4307*9585STim.Szeto@Sun.COM } 4308*9585STim.Szeto@Sun.COM goto done; 4309*9585STim.Szeto@Sun.COM } 4310*9585STim.Szeto@Sun.COM } 4311*9585STim.Szeto@Sun.COM 4312*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4313*9585STim.Szeto@Sun.COM goto done; 4314*9585STim.Szeto@Sun.COM } 4315*9585STim.Szeto@Sun.COM 4316*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_nentries == 0) { 4317*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 4318*9585STim.Szeto@Sun.COM goto done; 4319*9585STim.Szeto@Sun.COM } 4320*9585STim.Szeto@Sun.COM 4321*9585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 4322*9585STim.Szeto@Sun.COM 4323*9585STim.Szeto@Sun.COM /* 4324*9585STim.Szeto@Sun.COM * allocate caller's buffer with the final size 4325*9585STim.Szeto@Sun.COM */ 4326*9585STim.Szeto@Sun.COM *viewEntryList = (stmfViewEntryList *)calloc(1, 4327*9585STim.Szeto@Sun.COM sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry)); 4328*9585STim.Szeto@Sun.COM if (*viewEntryList == NULL) { 4329*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 4330*9585STim.Szeto@Sun.COM goto done; 4331*9585STim.Szeto@Sun.COM } 4332*9585STim.Szeto@Sun.COM 4333*9585STim.Szeto@Sun.COM (*viewEntryList)->cnt = listCnt; 4334*9585STim.Szeto@Sun.COM 4335*9585STim.Szeto@Sun.COM /* copy to caller's buffer */ 4336*9585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 4337*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndexValid = B_TRUE; 4338*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx; 4339*9585STim.Szeto@Sun.COM if (fVeList[i].ve_all_hosts == 1) { 4340*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allHosts = B_TRUE; 4341*9585STim.Szeto@Sun.COM } else { 4342*9585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_host_group.name, 4343*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].hostGroup, 4344*9585STim.Szeto@Sun.COM fVeList[i].ve_host_group.name_size); 4345*9585STim.Szeto@Sun.COM } 4346*9585STim.Szeto@Sun.COM if (fVeList[i].ve_all_targets == 1) { 4347*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allTargets = B_TRUE; 4348*9585STim.Szeto@Sun.COM } else { 4349*9585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_target_group.name, 4350*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].targetGroup, 4351*9585STim.Szeto@Sun.COM fVeList[i].ve_target_group.name_size); 4352*9585STim.Szeto@Sun.COM } 4353*9585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr, 4354*9585STim.Szeto@Sun.COM sizeof ((*viewEntryList)->ve[i].luNbr)); 4355*9585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].luNbrValid = B_TRUE; 4356*9585STim.Szeto@Sun.COM } 4357*9585STim.Szeto@Sun.COM 4358*9585STim.Szeto@Sun.COM /* 4359*9585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 4360*9585STim.Szeto@Sun.COM */ 4361*9585STim.Szeto@Sun.COM qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt, 4362*9585STim.Szeto@Sun.COM sizeof (stmfViewEntry), viewEntryCompare); 4363*9585STim.Szeto@Sun.COM 4364*9585STim.Szeto@Sun.COM done: 4365*9585STim.Szeto@Sun.COM (void) close(fd); 4366*9585STim.Szeto@Sun.COM /* 4367*9585STim.Szeto@Sun.COM * free internal buffers 4368*9585STim.Szeto@Sun.COM */ 4369*9585STim.Szeto@Sun.COM free(fVeList); 43707836SJohn.Forte@Sun.COM return (ret); 43717836SJohn.Forte@Sun.COM } 43727836SJohn.Forte@Sun.COM 4373*9585STim.Szeto@Sun.COM 43747836SJohn.Forte@Sun.COM /* 43757836SJohn.Forte@Sun.COM * loadHostGroups 43767836SJohn.Forte@Sun.COM * 43777836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the host groups into stmf 43787836SJohn.Forte@Sun.COM * 43797836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 43807836SJohn.Forte@Sun.COM * groupList - populated host group list 43817836SJohn.Forte@Sun.COM */ 43827836SJohn.Forte@Sun.COM static int 43837836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList) 43847836SJohn.Forte@Sun.COM { 43857836SJohn.Forte@Sun.COM int i, j; 43867836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 43877836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 43887836SJohn.Forte@Sun.COM 43897836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 43907836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 43917836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 43927836SJohn.Forte@Sun.COM goto out; 43937836SJohn.Forte@Sun.COM } 4394*9585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 4395*9585STim.Szeto@Sun.COM &groupProps, HOST_GROUP); 43967836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 43977836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, 43987836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 43997836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 44007836SJohn.Forte@Sun.COM goto out; 44017836SJohn.Forte@Sun.COM } 44027836SJohn.Forte@Sun.COM } 44037836SJohn.Forte@Sun.COM } 44047836SJohn.Forte@Sun.COM 44057836SJohn.Forte@Sun.COM 44067836SJohn.Forte@Sun.COM out: 44077836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 44087836SJohn.Forte@Sun.COM return (ret); 44097836SJohn.Forte@Sun.COM } 44107836SJohn.Forte@Sun.COM 44117836SJohn.Forte@Sun.COM /* 44127836SJohn.Forte@Sun.COM * loadTargetGroups 44137836SJohn.Forte@Sun.COM * 44147836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the target groups into stmf 44157836SJohn.Forte@Sun.COM * 44167836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 44177836SJohn.Forte@Sun.COM * groupList - populated target group list. 44187836SJohn.Forte@Sun.COM */ 44197836SJohn.Forte@Sun.COM static int 44207836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList) 44217836SJohn.Forte@Sun.COM { 44227836SJohn.Forte@Sun.COM int i, j; 44237836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 44247836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 44257836SJohn.Forte@Sun.COM 44267836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 44277836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 44287836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 44297836SJohn.Forte@Sun.COM goto out; 44307836SJohn.Forte@Sun.COM } 4431*9585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 4432*9585STim.Szeto@Sun.COM &groupProps, TARGET_GROUP); 44337836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 44347836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 44357836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 44367836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 44377836SJohn.Forte@Sun.COM goto out; 44387836SJohn.Forte@Sun.COM } 44397836SJohn.Forte@Sun.COM } 44407836SJohn.Forte@Sun.COM } 44417836SJohn.Forte@Sun.COM 44427836SJohn.Forte@Sun.COM 44437836SJohn.Forte@Sun.COM out: 44447836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 44457836SJohn.Forte@Sun.COM return (ret); 44467836SJohn.Forte@Sun.COM } 44477836SJohn.Forte@Sun.COM 44487836SJohn.Forte@Sun.COM 44497836SJohn.Forte@Sun.COM /* 44507836SJohn.Forte@Sun.COM * loadStore 44517836SJohn.Forte@Sun.COM * 44527836SJohn.Forte@Sun.COM * Purpose: Load the configuration data from the store 44537836SJohn.Forte@Sun.COM * 44547836SJohn.Forte@Sun.COM * First load the host groups and target groups, then the view entries 44557836SJohn.Forte@Sun.COM * and finally the provider data 44567836SJohn.Forte@Sun.COM * 44577836SJohn.Forte@Sun.COM * fd - file descriptor of control node for stmf. 44587836SJohn.Forte@Sun.COM */ 44597836SJohn.Forte@Sun.COM static int 44607836SJohn.Forte@Sun.COM loadStore(int fd) 44617836SJohn.Forte@Sun.COM { 44627836SJohn.Forte@Sun.COM int ret; 44637836SJohn.Forte@Sun.COM int i, j; 44647836SJohn.Forte@Sun.COM stmfGroupList *groupList = NULL; 44657836SJohn.Forte@Sun.COM stmfGuidList *guidList = NULL; 44667836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 44677836SJohn.Forte@Sun.COM stmfProviderList *providerList = NULL; 44687836SJohn.Forte@Sun.COM int providerType; 44697836SJohn.Forte@Sun.COM nvlist_t *nvl = NULL; 44707836SJohn.Forte@Sun.COM 44717836SJohn.Forte@Sun.COM 44727836SJohn.Forte@Sun.COM 44737836SJohn.Forte@Sun.COM /* load host groups */ 4474*9585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, HOST_GROUP); 44757836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44767836SJohn.Forte@Sun.COM return (ret); 44777836SJohn.Forte@Sun.COM } 44787836SJohn.Forte@Sun.COM ret = loadHostGroups(fd, groupList); 44797836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44807836SJohn.Forte@Sun.COM goto out; 44817836SJohn.Forte@Sun.COM } 44827836SJohn.Forte@Sun.COM 44837836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 44847836SJohn.Forte@Sun.COM groupList = NULL; 44857836SJohn.Forte@Sun.COM 44867836SJohn.Forte@Sun.COM /* load target groups */ 4487*9585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, TARGET_GROUP); 44887836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44897836SJohn.Forte@Sun.COM goto out; 44907836SJohn.Forte@Sun.COM } 44917836SJohn.Forte@Sun.COM ret = loadTargetGroups(fd, groupList); 44927836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44937836SJohn.Forte@Sun.COM goto out; 44947836SJohn.Forte@Sun.COM } 44957836SJohn.Forte@Sun.COM 44967836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 44977836SJohn.Forte@Sun.COM groupList = NULL; 44987836SJohn.Forte@Sun.COM 44997836SJohn.Forte@Sun.COM /* Get the guid list */ 45007836SJohn.Forte@Sun.COM ret = psGetLogicalUnitList(&guidList); 45017836SJohn.Forte@Sun.COM switch (ret) { 45027836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45037836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45047836SJohn.Forte@Sun.COM break; 45057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45067836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45077836SJohn.Forte@Sun.COM break; 45087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45097836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45107836SJohn.Forte@Sun.COM break; 45117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45127836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45137836SJohn.Forte@Sun.COM break; 45147836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45157836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45167836SJohn.Forte@Sun.COM break; 45177836SJohn.Forte@Sun.COM default: 45187836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45197836SJohn.Forte@Sun.COM break; 45207836SJohn.Forte@Sun.COM } 45217836SJohn.Forte@Sun.COM 45227836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45237836SJohn.Forte@Sun.COM goto out; 45247836SJohn.Forte@Sun.COM } 45257836SJohn.Forte@Sun.COM 45267836SJohn.Forte@Sun.COM /* 45277836SJohn.Forte@Sun.COM * We have the guid list, now get the corresponding 45287836SJohn.Forte@Sun.COM * view entries for each guid 45297836SJohn.Forte@Sun.COM */ 45307836SJohn.Forte@Sun.COM for (i = 0; i < guidList->cnt; i++) { 45317836SJohn.Forte@Sun.COM ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList); 45327836SJohn.Forte@Sun.COM switch (ret) { 45337836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45347836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45357836SJohn.Forte@Sun.COM break; 45367836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45377836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45387836SJohn.Forte@Sun.COM break; 45397836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45407836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45417836SJohn.Forte@Sun.COM break; 45427836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45437836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45447836SJohn.Forte@Sun.COM break; 45457836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45467836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45477836SJohn.Forte@Sun.COM break; 45487836SJohn.Forte@Sun.COM default: 45497836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45507836SJohn.Forte@Sun.COM break; 45517836SJohn.Forte@Sun.COM } 45527836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45537836SJohn.Forte@Sun.COM goto out; 45547836SJohn.Forte@Sun.COM } 45557836SJohn.Forte@Sun.COM for (j = 0; j < viewEntryList->cnt; j++) { 45567836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, &guidList->guid[i], 45577836SJohn.Forte@Sun.COM &viewEntryList->ve[j]); 45587836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45597836SJohn.Forte@Sun.COM goto out; 45607836SJohn.Forte@Sun.COM } 45617836SJohn.Forte@Sun.COM } 45627836SJohn.Forte@Sun.COM } 45637836SJohn.Forte@Sun.COM 45647836SJohn.Forte@Sun.COM /* get the list of providers that have data */ 45657836SJohn.Forte@Sun.COM ret = psGetProviderDataList(&providerList); 45667836SJohn.Forte@Sun.COM switch (ret) { 45677836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45687836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45697836SJohn.Forte@Sun.COM break; 45707836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45717836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45727836SJohn.Forte@Sun.COM break; 45737836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45747836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45757836SJohn.Forte@Sun.COM break; 45767836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45777836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45787836SJohn.Forte@Sun.COM break; 45797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45807836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45817836SJohn.Forte@Sun.COM break; 45827836SJohn.Forte@Sun.COM default: 45837836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45847836SJohn.Forte@Sun.COM break; 45857836SJohn.Forte@Sun.COM } 45867836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45877836SJohn.Forte@Sun.COM goto out; 45887836SJohn.Forte@Sun.COM } 45897836SJohn.Forte@Sun.COM 45907836SJohn.Forte@Sun.COM for (i = 0; i < providerList->cnt; i++) { 45917836SJohn.Forte@Sun.COM providerType = providerList->provider[i].providerType; 45927836SJohn.Forte@Sun.COM ret = psGetProviderData(providerList->provider[i].name, 45937836SJohn.Forte@Sun.COM &nvl, providerType, NULL); 45947836SJohn.Forte@Sun.COM switch (ret) { 45957836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45967836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45977836SJohn.Forte@Sun.COM break; 45987836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45997836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46007836SJohn.Forte@Sun.COM break; 46017836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 46027836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46037836SJohn.Forte@Sun.COM break; 46047836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46057836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46067836SJohn.Forte@Sun.COM break; 46077836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46087836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46097836SJohn.Forte@Sun.COM break; 46107836SJohn.Forte@Sun.COM default: 46117836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46127836SJohn.Forte@Sun.COM break; 46137836SJohn.Forte@Sun.COM } 46147836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46157836SJohn.Forte@Sun.COM goto out; 46167836SJohn.Forte@Sun.COM } 46177836SJohn.Forte@Sun.COM 46187836SJohn.Forte@Sun.COM /* call setProviderData */ 46197836SJohn.Forte@Sun.COM ret = setProviderData(fd, providerList->provider[i].name, nvl, 4620*9585STim.Szeto@Sun.COM providerType, NULL); 46217836SJohn.Forte@Sun.COM switch (ret) { 46227836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 46237836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46247836SJohn.Forte@Sun.COM break; 46257836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 46267836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46277836SJohn.Forte@Sun.COM break; 46287836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 46297836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46307836SJohn.Forte@Sun.COM break; 46317836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46327836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46337836SJohn.Forte@Sun.COM break; 46347836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46357836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46367836SJohn.Forte@Sun.COM break; 46377836SJohn.Forte@Sun.COM default: 46387836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46397836SJohn.Forte@Sun.COM break; 46407836SJohn.Forte@Sun.COM } 46417836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46427836SJohn.Forte@Sun.COM goto out; 46437836SJohn.Forte@Sun.COM } 46447836SJohn.Forte@Sun.COM 46457836SJohn.Forte@Sun.COM nvlist_free(nvl); 46467836SJohn.Forte@Sun.COM nvl = NULL; 46477836SJohn.Forte@Sun.COM } 46487836SJohn.Forte@Sun.COM out: 46497836SJohn.Forte@Sun.COM if (groupList != NULL) { 46507836SJohn.Forte@Sun.COM free(groupList); 46517836SJohn.Forte@Sun.COM } 46527836SJohn.Forte@Sun.COM if (guidList != NULL) { 46537836SJohn.Forte@Sun.COM free(guidList); 46547836SJohn.Forte@Sun.COM } 46557836SJohn.Forte@Sun.COM if (viewEntryList != NULL) { 46567836SJohn.Forte@Sun.COM free(viewEntryList); 46577836SJohn.Forte@Sun.COM } 46587836SJohn.Forte@Sun.COM if (nvl != NULL) { 46597836SJohn.Forte@Sun.COM nvlist_free(nvl); 46607836SJohn.Forte@Sun.COM } 46617836SJohn.Forte@Sun.COM return (ret); 46627836SJohn.Forte@Sun.COM } 46637836SJohn.Forte@Sun.COM 46647836SJohn.Forte@Sun.COM /* 46657836SJohn.Forte@Sun.COM * stmfLoadConfig 46667836SJohn.Forte@Sun.COM * 46677836SJohn.Forte@Sun.COM * Purpose - load the configuration data from smf into stmf 46687836SJohn.Forte@Sun.COM * 46697836SJohn.Forte@Sun.COM */ 46707836SJohn.Forte@Sun.COM int 46717836SJohn.Forte@Sun.COM stmfLoadConfig(void) 46727836SJohn.Forte@Sun.COM { 4673*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 46747836SJohn.Forte@Sun.COM int fd; 46757836SJohn.Forte@Sun.COM stmf_state_desc_t stmfStateSet; 46767836SJohn.Forte@Sun.COM stmfState state; 46777836SJohn.Forte@Sun.COM 4678*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 4679*9585STim.Szeto@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 4680*9585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 4681*9585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) 4682*9585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 4683*9585STim.Szeto@Sun.COM return (ret); 4684*9585STim.Szeto@Sun.COM } 4685*9585STim.Szeto@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 4686*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4687*9585STim.Szeto@Sun.COM goto done; 4688*9585STim.Szeto@Sun.COM } 4689*9585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 4690*9585STim.Szeto@Sun.COM goto done; 4691*9585STim.Szeto@Sun.COM } 46927836SJohn.Forte@Sun.COM 46937836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 46947836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 46957836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 46967836SJohn.Forte@Sun.COM } 46977836SJohn.Forte@Sun.COM 46987836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 46997836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 47007836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 47017836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 47027836SJohn.Forte@Sun.COM } 47037836SJohn.Forte@Sun.COM } else { 47047836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 47057836SJohn.Forte@Sun.COM } 47067836SJohn.Forte@Sun.COM 47077836SJohn.Forte@Sun.COM 47087836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 47097836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 47107836SJohn.Forte@Sun.COM 47117836SJohn.Forte@Sun.COM /* 47127836SJohn.Forte@Sun.COM * Open control node for stmf 47137836SJohn.Forte@Sun.COM */ 47147836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 47157836SJohn.Forte@Sun.COM return (ret); 47167836SJohn.Forte@Sun.COM 47177836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 47187836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47197836SJohn.Forte@Sun.COM goto done; 47207836SJohn.Forte@Sun.COM } 47217836SJohn.Forte@Sun.COM 47227836SJohn.Forte@Sun.COM /* Load the persistent configuration data */ 47237836SJohn.Forte@Sun.COM ret = loadStore(fd); 47247836SJohn.Forte@Sun.COM if (ret != 0) { 47257836SJohn.Forte@Sun.COM goto done; 47267836SJohn.Forte@Sun.COM } 47277836SJohn.Forte@Sun.COM 47287836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 47297836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 47307836SJohn.Forte@Sun.COM 47317836SJohn.Forte@Sun.COM done: 47327836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 47337836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 47347836SJohn.Forte@Sun.COM } 47357836SJohn.Forte@Sun.COM (void) close(fd); 47367836SJohn.Forte@Sun.COM return (ret); 47377836SJohn.Forte@Sun.COM } 47387836SJohn.Forte@Sun.COM 4739*9585STim.Szeto@Sun.COM 47407836SJohn.Forte@Sun.COM /* 47417836SJohn.Forte@Sun.COM * getStmfState 47427836SJohn.Forte@Sun.COM * 47437836SJohn.Forte@Sun.COM * stmfState - pointer to stmf_state_desc_t structure. Will contain the state 47447836SJohn.Forte@Sun.COM * information of the stmf service on success. 47457836SJohn.Forte@Sun.COM */ 47467836SJohn.Forte@Sun.COM static int 47477836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState) 47487836SJohn.Forte@Sun.COM { 47497836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 47507836SJohn.Forte@Sun.COM int fd; 47517836SJohn.Forte@Sun.COM int ioctlRet; 47527836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 47537836SJohn.Forte@Sun.COM 47547836SJohn.Forte@Sun.COM /* 47557836SJohn.Forte@Sun.COM * Open control node for stmf 47567836SJohn.Forte@Sun.COM */ 47577836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 47587836SJohn.Forte@Sun.COM return (ret); 47597836SJohn.Forte@Sun.COM 47607836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 47617836SJohn.Forte@Sun.COM /* 47627836SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 47637836SJohn.Forte@Sun.COM */ 47647836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 47657836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 47667836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 47677836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t); 47687836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState; 47697836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl); 47707836SJohn.Forte@Sun.COM 47717836SJohn.Forte@Sun.COM (void) close(fd); 47727836SJohn.Forte@Sun.COM 47737836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 47747836SJohn.Forte@Sun.COM switch (errno) { 47757836SJohn.Forte@Sun.COM case EBUSY: 47767836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 47777836SJohn.Forte@Sun.COM break; 47787836SJohn.Forte@Sun.COM case EPERM: 47797836SJohn.Forte@Sun.COM case EACCES: 47807836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 47817836SJohn.Forte@Sun.COM break; 47827836SJohn.Forte@Sun.COM default: 47837836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 47847836SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 47857836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 47867836SJohn.Forte@Sun.COM break; 47877836SJohn.Forte@Sun.COM } 47887836SJohn.Forte@Sun.COM } 47897836SJohn.Forte@Sun.COM return (ret); 47907836SJohn.Forte@Sun.COM } 47917836SJohn.Forte@Sun.COM 47927836SJohn.Forte@Sun.COM 47937836SJohn.Forte@Sun.COM /* 47947836SJohn.Forte@Sun.COM * setStmfState 47957836SJohn.Forte@Sun.COM * 47967836SJohn.Forte@Sun.COM * stmfState - pointer to caller set state structure 47977836SJohn.Forte@Sun.COM * objectType - one of: 47987836SJohn.Forte@Sun.COM * LOGICAL_UNIT_TYPE 47997836SJohn.Forte@Sun.COM * TARGET_TYPE 48007836SJohn.Forte@Sun.COM * STMF_SERVICE_TYPE 48017836SJohn.Forte@Sun.COM */ 48027836SJohn.Forte@Sun.COM static int 48037836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType) 48047836SJohn.Forte@Sun.COM { 48057836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 48067836SJohn.Forte@Sun.COM int ioctlRet; 48077836SJohn.Forte@Sun.COM int cmd; 48087836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 48097836SJohn.Forte@Sun.COM 48107836SJohn.Forte@Sun.COM switch (objectType) { 48117836SJohn.Forte@Sun.COM case LOGICAL_UNIT_TYPE: 48127836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_LU_STATE; 48137836SJohn.Forte@Sun.COM break; 48147836SJohn.Forte@Sun.COM case TARGET_TYPE: 48157836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_TARGET_PORT_STATE; 48167836SJohn.Forte@Sun.COM break; 48177836SJohn.Forte@Sun.COM case STMF_SERVICE_TYPE: 48187836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_STMF_STATE; 48197836SJohn.Forte@Sun.COM break; 48207836SJohn.Forte@Sun.COM default: 48217836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48227836SJohn.Forte@Sun.COM goto done; 48237836SJohn.Forte@Sun.COM } 48247836SJohn.Forte@Sun.COM 48257836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 48267836SJohn.Forte@Sun.COM /* 48277836SJohn.Forte@Sun.COM * Issue ioctl to set the stmf state 48287836SJohn.Forte@Sun.COM */ 48297836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 48307836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 48317836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 48327836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 48337836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 48347836SJohn.Forte@Sun.COM switch (errno) { 48357836SJohn.Forte@Sun.COM case EBUSY: 48367836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48377836SJohn.Forte@Sun.COM break; 4838*9585STim.Szeto@Sun.COM case EPERM: 48397836SJohn.Forte@Sun.COM case EACCES: 48407836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 48417836SJohn.Forte@Sun.COM break; 48427836SJohn.Forte@Sun.COM case ENOENT: 48437836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 48447836SJohn.Forte@Sun.COM break; 48457836SJohn.Forte@Sun.COM default: 48467836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 48477836SJohn.Forte@Sun.COM "setStmfState:ioctl errno(%d)", errno); 48487836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48497836SJohn.Forte@Sun.COM break; 48507836SJohn.Forte@Sun.COM } 48517836SJohn.Forte@Sun.COM } 48527836SJohn.Forte@Sun.COM done: 48537836SJohn.Forte@Sun.COM return (ret); 48547836SJohn.Forte@Sun.COM } 48557836SJohn.Forte@Sun.COM 48567836SJohn.Forte@Sun.COM /* 48577836SJohn.Forte@Sun.COM * stmfOnline 48587836SJohn.Forte@Sun.COM * 48597836SJohn.Forte@Sun.COM * Purpose: Online stmf service 48607836SJohn.Forte@Sun.COM * 48617836SJohn.Forte@Sun.COM */ 48627836SJohn.Forte@Sun.COM int 48637836SJohn.Forte@Sun.COM stmfOnline(void) 48647836SJohn.Forte@Sun.COM { 48657836SJohn.Forte@Sun.COM int ret; 48667836SJohn.Forte@Sun.COM int fd; 48677836SJohn.Forte@Sun.COM stmfState state; 48687836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 48697836SJohn.Forte@Sun.COM 48707836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 48717836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 48727836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 48737836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 48747836SJohn.Forte@Sun.COM } 48757836SJohn.Forte@Sun.COM } else { 48767836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 48777836SJohn.Forte@Sun.COM } 48787836SJohn.Forte@Sun.COM iState.state = STMF_STATE_ONLINE; 48797836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 48807836SJohn.Forte@Sun.COM /* 48817836SJohn.Forte@Sun.COM * Open control node for stmf 48827836SJohn.Forte@Sun.COM * to make call to setStmfState() 48837836SJohn.Forte@Sun.COM */ 48847836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 48857836SJohn.Forte@Sun.COM return (ret); 48867836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 48877836SJohn.Forte@Sun.COM (void) close(fd); 48887836SJohn.Forte@Sun.COM return (ret); 48897836SJohn.Forte@Sun.COM } 48907836SJohn.Forte@Sun.COM 48917836SJohn.Forte@Sun.COM /* 48927836SJohn.Forte@Sun.COM * stmfOffline 48937836SJohn.Forte@Sun.COM * 48947836SJohn.Forte@Sun.COM * Purpose: Offline stmf service 48957836SJohn.Forte@Sun.COM * 48967836SJohn.Forte@Sun.COM */ 48977836SJohn.Forte@Sun.COM int 48987836SJohn.Forte@Sun.COM stmfOffline(void) 48997836SJohn.Forte@Sun.COM { 49007836SJohn.Forte@Sun.COM int ret; 49017836SJohn.Forte@Sun.COM int fd; 49027836SJohn.Forte@Sun.COM stmfState state; 49037836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 49047836SJohn.Forte@Sun.COM 49057836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 49067836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 49077836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 49087836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_OFFLINE); 49097836SJohn.Forte@Sun.COM } 49107836SJohn.Forte@Sun.COM } else { 49117836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 49127836SJohn.Forte@Sun.COM } 49137836SJohn.Forte@Sun.COM iState.state = STMF_STATE_OFFLINE; 49147836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 49157836SJohn.Forte@Sun.COM 49167836SJohn.Forte@Sun.COM /* 49177836SJohn.Forte@Sun.COM * Open control node for stmf 49187836SJohn.Forte@Sun.COM * to make call to setStmfState() 49197836SJohn.Forte@Sun.COM */ 49207836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49217836SJohn.Forte@Sun.COM return (ret); 49227836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 49237836SJohn.Forte@Sun.COM (void) close(fd); 49247836SJohn.Forte@Sun.COM return (ret); 49257836SJohn.Forte@Sun.COM } 49267836SJohn.Forte@Sun.COM 49277836SJohn.Forte@Sun.COM 49287836SJohn.Forte@Sun.COM /* 49297836SJohn.Forte@Sun.COM * stmfOfflineTarget 49307836SJohn.Forte@Sun.COM * 49317836SJohn.Forte@Sun.COM * Purpose: Change state of target to offline 49327836SJohn.Forte@Sun.COM * 49337836SJohn.Forte@Sun.COM * devid - devid of the target to offline 49347836SJohn.Forte@Sun.COM */ 49357836SJohn.Forte@Sun.COM int 49367836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid) 49377836SJohn.Forte@Sun.COM { 49387836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 49397836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49407836SJohn.Forte@Sun.COM int fd; 49417836SJohn.Forte@Sun.COM 49427836SJohn.Forte@Sun.COM if (devid == NULL) { 49437836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 49447836SJohn.Forte@Sun.COM } 49457836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 49467836SJohn.Forte@Sun.COM 49477836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_OFFLINE; 49487836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 49497836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 49507836SJohn.Forte@Sun.COM devid->identLength); 49517836SJohn.Forte@Sun.COM /* 49527836SJohn.Forte@Sun.COM * Open control node for stmf 49537836SJohn.Forte@Sun.COM * to make call to setStmfState() 49547836SJohn.Forte@Sun.COM */ 49557836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49567836SJohn.Forte@Sun.COM return (ret); 49577836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 49587836SJohn.Forte@Sun.COM (void) close(fd); 49597836SJohn.Forte@Sun.COM return (ret); 49607836SJohn.Forte@Sun.COM } 49617836SJohn.Forte@Sun.COM 49627836SJohn.Forte@Sun.COM /* 49637836SJohn.Forte@Sun.COM * stmfOfflineLogicalUnit 49647836SJohn.Forte@Sun.COM * 49657836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to offline 49667836SJohn.Forte@Sun.COM * 49677836SJohn.Forte@Sun.COM * lu - guid of the logical unit to offline 49687836SJohn.Forte@Sun.COM */ 49697836SJohn.Forte@Sun.COM int 49707836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu) 49717836SJohn.Forte@Sun.COM { 49727836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 49737836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49747836SJohn.Forte@Sun.COM int fd; 49757836SJohn.Forte@Sun.COM 49767836SJohn.Forte@Sun.COM if (lu == NULL) { 49777836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 49787836SJohn.Forte@Sun.COM } 49797836SJohn.Forte@Sun.COM 49807836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 49817836SJohn.Forte@Sun.COM 49827836SJohn.Forte@Sun.COM luState.state = STMF_STATE_OFFLINE; 49837836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 49847836SJohn.Forte@Sun.COM /* 49857836SJohn.Forte@Sun.COM * Open control node for stmf 49867836SJohn.Forte@Sun.COM * to make call to setStmfState() 49877836SJohn.Forte@Sun.COM */ 49887836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49897836SJohn.Forte@Sun.COM return (ret); 49907836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 49917836SJohn.Forte@Sun.COM (void) close(fd); 49927836SJohn.Forte@Sun.COM return (ret); 49937836SJohn.Forte@Sun.COM } 49947836SJohn.Forte@Sun.COM 49957836SJohn.Forte@Sun.COM /* 49967836SJohn.Forte@Sun.COM * stmfOnlineTarget 49977836SJohn.Forte@Sun.COM * 49987836SJohn.Forte@Sun.COM * Purpose: Change state of target to online 49997836SJohn.Forte@Sun.COM * 50007836SJohn.Forte@Sun.COM * devid - devid of the target to online 50017836SJohn.Forte@Sun.COM */ 50027836SJohn.Forte@Sun.COM int 50037836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid) 50047836SJohn.Forte@Sun.COM { 50057836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 50067836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50077836SJohn.Forte@Sun.COM int fd; 50087836SJohn.Forte@Sun.COM 50097836SJohn.Forte@Sun.COM if (devid == NULL) { 50107836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50117836SJohn.Forte@Sun.COM } 50127836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 50137836SJohn.Forte@Sun.COM 50147836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_ONLINE; 50157836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 50167836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 50177836SJohn.Forte@Sun.COM devid->identLength); 50187836SJohn.Forte@Sun.COM /* 50197836SJohn.Forte@Sun.COM * Open control node for stmf 50207836SJohn.Forte@Sun.COM * to make call to setStmfState() 50217836SJohn.Forte@Sun.COM */ 50227836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50237836SJohn.Forte@Sun.COM return (ret); 50247836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 50257836SJohn.Forte@Sun.COM (void) close(fd); 50267836SJohn.Forte@Sun.COM return (ret); 50277836SJohn.Forte@Sun.COM } 50287836SJohn.Forte@Sun.COM 50297836SJohn.Forte@Sun.COM /* 50307836SJohn.Forte@Sun.COM * stmfOnlineLogicalUnit 50317836SJohn.Forte@Sun.COM * 50327836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to online 50337836SJohn.Forte@Sun.COM * 50347836SJohn.Forte@Sun.COM * lu - guid of the logical unit to online 50357836SJohn.Forte@Sun.COM */ 50367836SJohn.Forte@Sun.COM int 50377836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu) 50387836SJohn.Forte@Sun.COM { 50397836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 50407836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50417836SJohn.Forte@Sun.COM int fd; 50427836SJohn.Forte@Sun.COM 50437836SJohn.Forte@Sun.COM if (lu == NULL) { 50447836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50457836SJohn.Forte@Sun.COM } 50467836SJohn.Forte@Sun.COM 50477836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 50487836SJohn.Forte@Sun.COM 50497836SJohn.Forte@Sun.COM luState.state = STMF_STATE_ONLINE; 50507836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 50517836SJohn.Forte@Sun.COM /* 50527836SJohn.Forte@Sun.COM * Open control node for stmf 50537836SJohn.Forte@Sun.COM * to make call to setStmfState() 50547836SJohn.Forte@Sun.COM */ 50557836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50567836SJohn.Forte@Sun.COM return (ret); 50577836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 50587836SJohn.Forte@Sun.COM (void) close(fd); 50597836SJohn.Forte@Sun.COM return (ret); 50607836SJohn.Forte@Sun.COM } 50617836SJohn.Forte@Sun.COM 50627836SJohn.Forte@Sun.COM /* 50637836SJohn.Forte@Sun.COM * stmfRemoveFromHostGroup 50647836SJohn.Forte@Sun.COM * 50657836SJohn.Forte@Sun.COM * Purpose: Removes an initiator from an initiator group 50667836SJohn.Forte@Sun.COM * 50677836SJohn.Forte@Sun.COM * hostGroupName - name of an initiator group 50687836SJohn.Forte@Sun.COM * hostName - name of host group member to remove 50697836SJohn.Forte@Sun.COM */ 50707836SJohn.Forte@Sun.COM int 50717836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 50727836SJohn.Forte@Sun.COM { 50737836SJohn.Forte@Sun.COM int ret; 50747836SJohn.Forte@Sun.COM int fd; 50757836SJohn.Forte@Sun.COM 50767836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 50777836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 50787836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 50797836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50807836SJohn.Forte@Sun.COM } 50817836SJohn.Forte@Sun.COM 50827836SJohn.Forte@Sun.COM /* call init */ 50837836SJohn.Forte@Sun.COM ret = initializeConfig(); 50847836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50857836SJohn.Forte@Sun.COM return (ret); 50867836SJohn.Forte@Sun.COM } 50877836SJohn.Forte@Sun.COM 50887836SJohn.Forte@Sun.COM /* 50897836SJohn.Forte@Sun.COM * Open control node for stmf 50907836SJohn.Forte@Sun.COM */ 50917836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 50927836SJohn.Forte@Sun.COM return (ret); 50937836SJohn.Forte@Sun.COM 50947836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY, 50957836SJohn.Forte@Sun.COM hostGroupName, hostName)) != STMF_STATUS_SUCCESS) { 50967836SJohn.Forte@Sun.COM goto done; 50977836SJohn.Forte@Sun.COM } 50987836SJohn.Forte@Sun.COM 5099*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5100*9585STim.Szeto@Sun.COM goto done; 5101*9585STim.Szeto@Sun.COM } 5102*9585STim.Szeto@Sun.COM 51037836SJohn.Forte@Sun.COM ret = psRemoveHostGroupMember((char *)hostGroupName, 51047836SJohn.Forte@Sun.COM (char *)hostName->ident); 51057836SJohn.Forte@Sun.COM switch (ret) { 51067836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51077836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51087836SJohn.Forte@Sun.COM break; 51097836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 51107836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 51117836SJohn.Forte@Sun.COM break; 51127836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 51137836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 51147836SJohn.Forte@Sun.COM break; 51157836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51167836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51177836SJohn.Forte@Sun.COM break; 51187836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51197836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51207836SJohn.Forte@Sun.COM break; 51217836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51227836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51237836SJohn.Forte@Sun.COM break; 51247836SJohn.Forte@Sun.COM default: 51257836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 51267836SJohn.Forte@Sun.COM "stmfRemoveFromHostGroup" 51277836SJohn.Forte@Sun.COM "psRemoveHostGroupMember:error(%d)", ret); 51287836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51297836SJohn.Forte@Sun.COM break; 51307836SJohn.Forte@Sun.COM } 51317836SJohn.Forte@Sun.COM 51327836SJohn.Forte@Sun.COM done: 51337836SJohn.Forte@Sun.COM (void) close(fd); 51347836SJohn.Forte@Sun.COM return (ret); 51357836SJohn.Forte@Sun.COM } 51367836SJohn.Forte@Sun.COM 51377836SJohn.Forte@Sun.COM /* 51387836SJohn.Forte@Sun.COM * stmfRemoveFromTargetGroup 51397836SJohn.Forte@Sun.COM * 51407836SJohn.Forte@Sun.COM * Purpose: Removes a local port from a local port group 51417836SJohn.Forte@Sun.COM * 51427836SJohn.Forte@Sun.COM * targetGroupName - name of a target group 51437836SJohn.Forte@Sun.COM * targetName - name of target to remove 51447836SJohn.Forte@Sun.COM */ 51457836SJohn.Forte@Sun.COM int 51467836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 51477836SJohn.Forte@Sun.COM { 51487836SJohn.Forte@Sun.COM int ret; 51497836SJohn.Forte@Sun.COM int fd; 51507836SJohn.Forte@Sun.COM 51517836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 51527836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 51537836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 51547836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 51557836SJohn.Forte@Sun.COM } 51567836SJohn.Forte@Sun.COM 51577836SJohn.Forte@Sun.COM /* call init */ 51587836SJohn.Forte@Sun.COM ret = initializeConfig(); 51597836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51607836SJohn.Forte@Sun.COM return (ret); 51617836SJohn.Forte@Sun.COM } 51627836SJohn.Forte@Sun.COM 51637836SJohn.Forte@Sun.COM /* 51647836SJohn.Forte@Sun.COM * Open control node for stmf 51657836SJohn.Forte@Sun.COM */ 51667836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 51677836SJohn.Forte@Sun.COM return (ret); 51687836SJohn.Forte@Sun.COM 51697836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY, 51707836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 51717836SJohn.Forte@Sun.COM goto done; 51727836SJohn.Forte@Sun.COM } 51737836SJohn.Forte@Sun.COM 5174*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5175*9585STim.Szeto@Sun.COM goto done; 5176*9585STim.Szeto@Sun.COM } 5177*9585STim.Szeto@Sun.COM 51787836SJohn.Forte@Sun.COM ret = psRemoveTargetGroupMember((char *)targetGroupName, 51797836SJohn.Forte@Sun.COM (char *)targetName->ident); 51807836SJohn.Forte@Sun.COM switch (ret) { 51817836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51827836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51837836SJohn.Forte@Sun.COM break; 51847836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 51857836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 51867836SJohn.Forte@Sun.COM break; 51877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 51887836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 51897836SJohn.Forte@Sun.COM break; 51907836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51917836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51927836SJohn.Forte@Sun.COM break; 51937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51947836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51957836SJohn.Forte@Sun.COM break; 51967836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51977836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51987836SJohn.Forte@Sun.COM break; 51997836SJohn.Forte@Sun.COM default: 52007836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 52017836SJohn.Forte@Sun.COM "stmfRemoveFromTargetGroup" 52027836SJohn.Forte@Sun.COM "psRemoveTargetGroupMember:error(%d)", ret); 52037836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52047836SJohn.Forte@Sun.COM break; 52057836SJohn.Forte@Sun.COM } 52067836SJohn.Forte@Sun.COM 52077836SJohn.Forte@Sun.COM done: 52087836SJohn.Forte@Sun.COM (void) close(fd); 52097836SJohn.Forte@Sun.COM return (ret); 52107836SJohn.Forte@Sun.COM } 52117836SJohn.Forte@Sun.COM 52127836SJohn.Forte@Sun.COM /* 52137836SJohn.Forte@Sun.COM * stmfRemoveViewEntry 52147836SJohn.Forte@Sun.COM * 52157836SJohn.Forte@Sun.COM * Purpose: Removes a view entry from a logical unit 52167836SJohn.Forte@Sun.COM * 52177836SJohn.Forte@Sun.COM * lu - guid of lu for which view entry is being removed 52187836SJohn.Forte@Sun.COM * viewEntryIndex - index of view entry to remove 52197836SJohn.Forte@Sun.COM * 52207836SJohn.Forte@Sun.COM */ 52217836SJohn.Forte@Sun.COM int 52227836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex) 52237836SJohn.Forte@Sun.COM { 52247836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 52257836SJohn.Forte@Sun.COM int fd; 52267836SJohn.Forte@Sun.COM int ioctlRet; 52277836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 52287836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 52297836SJohn.Forte@Sun.COM 52307836SJohn.Forte@Sun.COM if (lu == NULL) { 52317836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 52327836SJohn.Forte@Sun.COM } 52337836SJohn.Forte@Sun.COM 52347836SJohn.Forte@Sun.COM /* call init */ 52357836SJohn.Forte@Sun.COM ret = initializeConfig(); 52367836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 52377836SJohn.Forte@Sun.COM return (ret); 52387836SJohn.Forte@Sun.COM } 52397836SJohn.Forte@Sun.COM 52407836SJohn.Forte@Sun.COM /* 52417836SJohn.Forte@Sun.COM * Open control node for stmf 52427836SJohn.Forte@Sun.COM */ 52437836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 52447836SJohn.Forte@Sun.COM return (ret); 52457836SJohn.Forte@Sun.COM 52467836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 52477836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx_valid = B_TRUE; 52487836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx = viewEntryIndex; 52497836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 52507836SJohn.Forte@Sun.COM 52517836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 52527836SJohn.Forte@Sun.COM /* 52537836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 52547836SJohn.Forte@Sun.COM */ 52557836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 52567836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 52577836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 52587836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl); 52597836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 52607836SJohn.Forte@Sun.COM switch (errno) { 52617836SJohn.Forte@Sun.COM case EBUSY: 52627836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 52637836SJohn.Forte@Sun.COM break; 5264*9585STim.Szeto@Sun.COM case EPERM: 5265*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 5266*9585STim.Szeto@Sun.COM break; 52677836SJohn.Forte@Sun.COM case EACCES: 52687836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 52697836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 52707836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 52717836SJohn.Forte@Sun.COM break; 52727836SJohn.Forte@Sun.COM default: 52737836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 52747836SJohn.Forte@Sun.COM break; 52757836SJohn.Forte@Sun.COM } 52767836SJohn.Forte@Sun.COM break; 52777836SJohn.Forte@Sun.COM case ENODEV: 52787836SJohn.Forte@Sun.COM case ENOENT: 52797836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 52807836SJohn.Forte@Sun.COM break; 52817836SJohn.Forte@Sun.COM default: 52827836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 52837836SJohn.Forte@Sun.COM "stmfRemoveViewEntry:ioctl errno(%d)", 52847836SJohn.Forte@Sun.COM errno); 52857836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52867836SJohn.Forte@Sun.COM break; 52877836SJohn.Forte@Sun.COM } 52887836SJohn.Forte@Sun.COM goto done; 52897836SJohn.Forte@Sun.COM } 52907836SJohn.Forte@Sun.COM 5291*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5292*9585STim.Szeto@Sun.COM goto done; 5293*9585STim.Szeto@Sun.COM } 5294*9585STim.Szeto@Sun.COM 52957836SJohn.Forte@Sun.COM ret = psRemoveViewEntry(lu, viewEntryIndex); 52967836SJohn.Forte@Sun.COM switch (ret) { 52977836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 52987836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 52997836SJohn.Forte@Sun.COM break; 53007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 53017836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 53027836SJohn.Forte@Sun.COM break; 53037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 53047836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 53057836SJohn.Forte@Sun.COM break; 53067836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 53077836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 53087836SJohn.Forte@Sun.COM break; 53097836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 53107836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 53117836SJohn.Forte@Sun.COM break; 53127836SJohn.Forte@Sun.COM default: 53137836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 53147836SJohn.Forte@Sun.COM "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)", 53157836SJohn.Forte@Sun.COM ret); 53167836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 53177836SJohn.Forte@Sun.COM break; 53187836SJohn.Forte@Sun.COM } 53197836SJohn.Forte@Sun.COM 53207836SJohn.Forte@Sun.COM done: 53217836SJohn.Forte@Sun.COM (void) close(fd); 53227836SJohn.Forte@Sun.COM return (ret); 53237836SJohn.Forte@Sun.COM } 53247836SJohn.Forte@Sun.COM 53257836SJohn.Forte@Sun.COM /* 53267836SJohn.Forte@Sun.COM * stmfSetProviderData 53277836SJohn.Forte@Sun.COM * 53287836SJohn.Forte@Sun.COM * Purpose: set the provider data 53297836SJohn.Forte@Sun.COM * 53307836SJohn.Forte@Sun.COM * providerName - unique name of provider 53317836SJohn.Forte@Sun.COM * nvl - nvlist to set 53327836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 53337836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 53347836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 53357836SJohn.Forte@Sun.COM */ 53367836SJohn.Forte@Sun.COM int 53377836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType) 53387836SJohn.Forte@Sun.COM { 53397836SJohn.Forte@Sun.COM return (stmfSetProviderDataProt(providerName, nvl, providerType, 53407836SJohn.Forte@Sun.COM NULL)); 53417836SJohn.Forte@Sun.COM } 53427836SJohn.Forte@Sun.COM 53437836SJohn.Forte@Sun.COM /* 53447836SJohn.Forte@Sun.COM * stmfSetProviderDataProt 53457836SJohn.Forte@Sun.COM * 53467836SJohn.Forte@Sun.COM * Purpose: set the provider data 53477836SJohn.Forte@Sun.COM * 53487836SJohn.Forte@Sun.COM * providerName - unique name of provider 53497836SJohn.Forte@Sun.COM * nvl - nvlist to set 53507836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 53517836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 53527836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 53537836SJohn.Forte@Sun.COM * setToken - Stale data token returned in the stmfGetProviderDataProt() 53547836SJohn.Forte@Sun.COM * call or NULL. 53557836SJohn.Forte@Sun.COM */ 53567836SJohn.Forte@Sun.COM int 53577836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, 53587836SJohn.Forte@Sun.COM uint64_t *setToken) 53597836SJohn.Forte@Sun.COM { 53607836SJohn.Forte@Sun.COM int ret; 53617836SJohn.Forte@Sun.COM int fd; 53627836SJohn.Forte@Sun.COM 53637836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 53647836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 53657836SJohn.Forte@Sun.COM } 53667836SJohn.Forte@Sun.COM 53677836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 53687836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 53697836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 53707836SJohn.Forte@Sun.COM } 53717836SJohn.Forte@Sun.COM 53727836SJohn.Forte@Sun.COM /* call init */ 53737836SJohn.Forte@Sun.COM ret = initializeConfig(); 53747836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 53757836SJohn.Forte@Sun.COM return (ret); 53767836SJohn.Forte@Sun.COM } 53777836SJohn.Forte@Sun.COM 53787836SJohn.Forte@Sun.COM /* 53797836SJohn.Forte@Sun.COM * Open control node for stmf 53807836SJohn.Forte@Sun.COM */ 53817836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 53827836SJohn.Forte@Sun.COM return (ret); 53837836SJohn.Forte@Sun.COM 5384*9585STim.Szeto@Sun.COM ret = setProviderData(fd, providerName, nvl, providerType, setToken); 53857836SJohn.Forte@Sun.COM 53867836SJohn.Forte@Sun.COM (void) close(fd); 53877836SJohn.Forte@Sun.COM 53887836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 53897836SJohn.Forte@Sun.COM goto done; 53907836SJohn.Forte@Sun.COM } 53917836SJohn.Forte@Sun.COM 5392*9585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5393*9585STim.Szeto@Sun.COM goto done; 5394*9585STim.Szeto@Sun.COM } 5395*9585STim.Szeto@Sun.COM 53967836SJohn.Forte@Sun.COM /* setting driver provider data successful. Now persist it */ 5397*9585STim.Szeto@Sun.COM ret = psSetProviderData(providerName, nvl, providerType, NULL); 53987836SJohn.Forte@Sun.COM switch (ret) { 53997836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 54007836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 54017836SJohn.Forte@Sun.COM break; 54027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 54037836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 54047836SJohn.Forte@Sun.COM break; 54057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 54067836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 54077836SJohn.Forte@Sun.COM break; 54087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 54097836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 54107836SJohn.Forte@Sun.COM break; 54117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 54127836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 54137836SJohn.Forte@Sun.COM break; 54147836SJohn.Forte@Sun.COM case STMF_PS_ERROR_PROV_DATA_STALE: 54157836SJohn.Forte@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 54167836SJohn.Forte@Sun.COM break; 54177836SJohn.Forte@Sun.COM default: 54187836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 54197836SJohn.Forte@Sun.COM "stmfSetProviderData" 54207836SJohn.Forte@Sun.COM "psSetProviderData:error(%d)", ret); 54217836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 54227836SJohn.Forte@Sun.COM break; 54237836SJohn.Forte@Sun.COM } 54247836SJohn.Forte@Sun.COM 54257836SJohn.Forte@Sun.COM done: 54267836SJohn.Forte@Sun.COM return (ret); 54277836SJohn.Forte@Sun.COM } 54287836SJohn.Forte@Sun.COM 54297836SJohn.Forte@Sun.COM /* 5430*9585STim.Szeto@Sun.COM * getProviderData 5431*9585STim.Szeto@Sun.COM * 5432*9585STim.Szeto@Sun.COM * Purpose: set the provider data from stmf 5433*9585STim.Szeto@Sun.COM * 5434*9585STim.Szeto@Sun.COM * providerName - unique name of provider 5435*9585STim.Szeto@Sun.COM * nvl - nvlist to load/retrieve 5436*9585STim.Szeto@Sun.COM * providerType - logical unit or port provider 5437*9585STim.Szeto@Sun.COM * setToken - returned stale data token 5438*9585STim.Szeto@Sun.COM */ 5439*9585STim.Szeto@Sun.COM int 5440*9585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType, 5441*9585STim.Szeto@Sun.COM uint64_t *setToken) 5442*9585STim.Szeto@Sun.COM { 5443*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 5444*9585STim.Szeto@Sun.COM int fd; 5445*9585STim.Szeto@Sun.COM int ioctlRet; 5446*9585STim.Szeto@Sun.COM size_t nvlistSize = ALLOC_PP_DATA_SIZE; 5447*9585STim.Szeto@Sun.COM int retryCnt = 0; 5448*9585STim.Szeto@Sun.COM int retryCntMax = MAX_PROVIDER_RETRY; 5449*9585STim.Szeto@Sun.COM stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL; 5450*9585STim.Szeto@Sun.COM boolean_t retry = B_TRUE; 5451*9585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 5452*9585STim.Szeto@Sun.COM 5453*9585STim.Szeto@Sun.COM if (providerName == NULL) { 5454*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 5455*9585STim.Szeto@Sun.COM } 5456*9585STim.Szeto@Sun.COM 5457*9585STim.Szeto@Sun.COM /* 5458*9585STim.Szeto@Sun.COM * Open control node for stmf 5459*9585STim.Szeto@Sun.COM */ 5460*9585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 5461*9585STim.Szeto@Sun.COM return (ret); 5462*9585STim.Szeto@Sun.COM 5463*9585STim.Szeto@Sun.COM /* set provider name and provider type */ 5464*9585STim.Szeto@Sun.COM if (strlcpy(ppi.ppi_name, providerName, 5465*9585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) >= 5466*9585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) { 5467*9585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 5468*9585STim.Szeto@Sun.COM goto done; 5469*9585STim.Szeto@Sun.COM } 5470*9585STim.Szeto@Sun.COM switch (providerType) { 5471*9585STim.Szeto@Sun.COM case STMF_LU_PROVIDER_TYPE: 5472*9585STim.Szeto@Sun.COM ppi.ppi_lu_provider = 1; 5473*9585STim.Szeto@Sun.COM break; 5474*9585STim.Szeto@Sun.COM case STMF_PORT_PROVIDER_TYPE: 5475*9585STim.Szeto@Sun.COM ppi.ppi_port_provider = 1; 5476*9585STim.Szeto@Sun.COM break; 5477*9585STim.Szeto@Sun.COM default: 5478*9585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 5479*9585STim.Szeto@Sun.COM goto done; 5480*9585STim.Szeto@Sun.COM } 5481*9585STim.Szeto@Sun.COM 5482*9585STim.Szeto@Sun.COM do { 5483*9585STim.Szeto@Sun.COM /* allocate memory for ioctl */ 5484*9585STim.Szeto@Sun.COM ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize + 5485*9585STim.Szeto@Sun.COM sizeof (stmf_ppioctl_data_t)); 5486*9585STim.Szeto@Sun.COM if (ppi_out == NULL) { 5487*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 5488*9585STim.Szeto@Sun.COM goto done; 5489*9585STim.Szeto@Sun.COM 5490*9585STim.Szeto@Sun.COM } 5491*9585STim.Szeto@Sun.COM 5492*9585STim.Szeto@Sun.COM /* set the size of the ioctl data to allocated buffer */ 5493*9585STim.Szeto@Sun.COM ppi.ppi_data_size = nvlistSize; 5494*9585STim.Szeto@Sun.COM 5495*9585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 5496*9585STim.Szeto@Sun.COM 5497*9585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 5498*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 5499*9585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 5500*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) + 5501*9585STim.Szeto@Sun.COM nvlistSize; 5502*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out; 5503*9585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl); 5504*9585STim.Szeto@Sun.COM if (ioctlRet != 0) { 5505*9585STim.Szeto@Sun.COM switch (errno) { 5506*9585STim.Szeto@Sun.COM case EBUSY: 5507*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 5508*9585STim.Szeto@Sun.COM break; 5509*9585STim.Szeto@Sun.COM case EPERM: 5510*9585STim.Szeto@Sun.COM case EACCES: 5511*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 5512*9585STim.Szeto@Sun.COM break; 5513*9585STim.Szeto@Sun.COM case EINVAL: 5514*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 5515*9585STim.Szeto@Sun.COM STMF_IOCERR_INSUFFICIENT_BUF) { 5516*9585STim.Szeto@Sun.COM nvlistSize = 5517*9585STim.Szeto@Sun.COM ppi_out->ppi_data_size; 5518*9585STim.Szeto@Sun.COM free(ppi_out); 5519*9585STim.Szeto@Sun.COM ppi_out = NULL; 5520*9585STim.Szeto@Sun.COM if (retryCnt++ > retryCntMax) { 5521*9585STim.Szeto@Sun.COM retry = B_FALSE; 5522*9585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 5523*9585STim.Szeto@Sun.COM } else { 5524*9585STim.Szeto@Sun.COM ret = 5525*9585STim.Szeto@Sun.COM STMF_STATUS_SUCCESS; 5526*9585STim.Szeto@Sun.COM } 5527*9585STim.Szeto@Sun.COM } else { 5528*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 5529*9585STim.Szeto@Sun.COM "getProviderData:ioctl" 5530*9585STim.Szeto@Sun.COM "unable to retrieve " 5531*9585STim.Szeto@Sun.COM "nvlist"); 5532*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 5533*9585STim.Szeto@Sun.COM } 5534*9585STim.Szeto@Sun.COM break; 5535*9585STim.Szeto@Sun.COM case ENOENT: 5536*9585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 5537*9585STim.Szeto@Sun.COM break; 5538*9585STim.Szeto@Sun.COM default: 5539*9585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 5540*9585STim.Szeto@Sun.COM "getProviderData:ioctl errno(%d)", 5541*9585STim.Szeto@Sun.COM errno); 5542*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 5543*9585STim.Szeto@Sun.COM break; 5544*9585STim.Szeto@Sun.COM } 5545*9585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) 5546*9585STim.Szeto@Sun.COM goto done; 5547*9585STim.Szeto@Sun.COM } 5548*9585STim.Szeto@Sun.COM } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF); 5549*9585STim.Szeto@Sun.COM 5550*9585STim.Szeto@Sun.COM if ((ret = nvlist_unpack((char *)ppi_out->ppi_data, 5551*9585STim.Szeto@Sun.COM ppi_out->ppi_data_size, nvl, 0)) != 0) { 5552*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 5553*9585STim.Szeto@Sun.COM goto done; 5554*9585STim.Szeto@Sun.COM } 5555*9585STim.Szeto@Sun.COM 5556*9585STim.Szeto@Sun.COM /* caller has asked for new token */ 5557*9585STim.Szeto@Sun.COM if (setToken) { 5558*9585STim.Szeto@Sun.COM *setToken = ppi_out->ppi_token; 5559*9585STim.Szeto@Sun.COM } 5560*9585STim.Szeto@Sun.COM done: 5561*9585STim.Szeto@Sun.COM free(ppi_out); 5562*9585STim.Szeto@Sun.COM (void) close(fd); 5563*9585STim.Szeto@Sun.COM return (ret); 5564*9585STim.Szeto@Sun.COM } 5565*9585STim.Szeto@Sun.COM 5566*9585STim.Szeto@Sun.COM /* 55677836SJohn.Forte@Sun.COM * setProviderData 55687836SJohn.Forte@Sun.COM * 5569*9585STim.Szeto@Sun.COM * Purpose: set the provider data in stmf 55707836SJohn.Forte@Sun.COM * 55717836SJohn.Forte@Sun.COM * providerName - unique name of provider 55727836SJohn.Forte@Sun.COM * nvl - nvlist to set 55737836SJohn.Forte@Sun.COM * providerType - logical unit or port provider 5574*9585STim.Szeto@Sun.COM * setToken - stale data token to check if not NULL 55757836SJohn.Forte@Sun.COM */ 55767836SJohn.Forte@Sun.COM static int 5577*9585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType, 5578*9585STim.Szeto@Sun.COM uint64_t *setToken) 55797836SJohn.Forte@Sun.COM { 55807836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 55817836SJohn.Forte@Sun.COM int ioctlRet; 55827836SJohn.Forte@Sun.COM size_t nvlistEncodedSize; 55837836SJohn.Forte@Sun.COM stmf_ppioctl_data_t *ppi = NULL; 5584*9585STim.Szeto@Sun.COM uint64_t outToken; 55857836SJohn.Forte@Sun.COM char *allocatedNvBuffer; 55867836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 55877836SJohn.Forte@Sun.COM 55887836SJohn.Forte@Sun.COM if (providerName == NULL) { 55897836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 55907836SJohn.Forte@Sun.COM } 55917836SJohn.Forte@Sun.COM 55927836SJohn.Forte@Sun.COM /* get size of encoded nvlist */ 55937836SJohn.Forte@Sun.COM if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) { 55947836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 55957836SJohn.Forte@Sun.COM } 55967836SJohn.Forte@Sun.COM 55977836SJohn.Forte@Sun.COM /* allocate memory for ioctl */ 55987836SJohn.Forte@Sun.COM ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize + 55997836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t)); 56007836SJohn.Forte@Sun.COM if (ppi == NULL) { 56017836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 56027836SJohn.Forte@Sun.COM } 56037836SJohn.Forte@Sun.COM 5604*9585STim.Szeto@Sun.COM if (setToken) { 5605*9585STim.Szeto@Sun.COM ppi->ppi_token_valid = 1; 5606*9585STim.Szeto@Sun.COM ppi->ppi_token = *setToken; 5607*9585STim.Szeto@Sun.COM } 5608*9585STim.Szeto@Sun.COM 56097836SJohn.Forte@Sun.COM allocatedNvBuffer = (char *)&ppi->ppi_data; 56107836SJohn.Forte@Sun.COM if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize, 56117836SJohn.Forte@Sun.COM NV_ENCODE_XDR, 0) != 0) { 56127836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 56137836SJohn.Forte@Sun.COM } 56147836SJohn.Forte@Sun.COM 56157836SJohn.Forte@Sun.COM /* set provider name and provider type */ 56167836SJohn.Forte@Sun.COM (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name)); 56177836SJohn.Forte@Sun.COM switch (providerType) { 56187836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 56197836SJohn.Forte@Sun.COM ppi->ppi_lu_provider = 1; 56207836SJohn.Forte@Sun.COM break; 56217836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 56227836SJohn.Forte@Sun.COM ppi->ppi_port_provider = 1; 56237836SJohn.Forte@Sun.COM break; 56247836SJohn.Forte@Sun.COM default: 56257836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56267836SJohn.Forte@Sun.COM } 56277836SJohn.Forte@Sun.COM 56287836SJohn.Forte@Sun.COM /* set the size of the ioctl data to packed data size */ 56297836SJohn.Forte@Sun.COM ppi->ppi_data_size = nvlistEncodedSize; 56307836SJohn.Forte@Sun.COM 56317836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 56327836SJohn.Forte@Sun.COM 56337836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 56347836SJohn.Forte@Sun.COM /* 56357836SJohn.Forte@Sun.COM * Subtracting 8 from the size as that is the size of the last member 56367836SJohn.Forte@Sun.COM * of the structure where the packed data resides 56377836SJohn.Forte@Sun.COM */ 56387836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = nvlistEncodedSize + 56397836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t) - 8; 56407836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi; 5641*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (uint64_t); 5642*9585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken; 56437836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl); 56447836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 56457836SJohn.Forte@Sun.COM switch (errno) { 56467836SJohn.Forte@Sun.COM case EBUSY: 56477836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 56487836SJohn.Forte@Sun.COM break; 5649*9585STim.Szeto@Sun.COM case EPERM: 56507836SJohn.Forte@Sun.COM case EACCES: 56517836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 56527836SJohn.Forte@Sun.COM break; 5653*9585STim.Szeto@Sun.COM case EINVAL: 5654*9585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 5655*9585STim.Szeto@Sun.COM STMF_IOCERR_PPD_UPDATED) { 5656*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 5657*9585STim.Szeto@Sun.COM } else { 5658*9585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 5659*9585STim.Szeto@Sun.COM } 5660*9585STim.Szeto@Sun.COM break; 56617836SJohn.Forte@Sun.COM default: 56627836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 56637836SJohn.Forte@Sun.COM "setProviderData:ioctl errno(%d)", errno); 56647836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 56657836SJohn.Forte@Sun.COM break; 56667836SJohn.Forte@Sun.COM } 56677836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) 56687836SJohn.Forte@Sun.COM goto done; 56697836SJohn.Forte@Sun.COM } 56707836SJohn.Forte@Sun.COM 5671*9585STim.Szeto@Sun.COM /* caller has asked for new token */ 5672*9585STim.Szeto@Sun.COM if (setToken) { 5673*9585STim.Szeto@Sun.COM *setToken = outToken; 5674*9585STim.Szeto@Sun.COM } 56757836SJohn.Forte@Sun.COM done: 56767836SJohn.Forte@Sun.COM free(ppi); 56777836SJohn.Forte@Sun.COM return (ret); 56787836SJohn.Forte@Sun.COM } 5679*9585STim.Szeto@Sun.COM 5680*9585STim.Szeto@Sun.COM /* 5681*9585STim.Szeto@Sun.COM * set the persistence method in the library only or library and service 5682*9585STim.Szeto@Sun.COM */ 5683*9585STim.Szeto@Sun.COM int 5684*9585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet) 5685*9585STim.Szeto@Sun.COM { 5686*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 5687*9585STim.Szeto@Sun.COM int oldPersist; 5688*9585STim.Szeto@Sun.COM 5689*9585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 5690*9585STim.Szeto@Sun.COM oldPersist = iPersistType; 5691*9585STim.Szeto@Sun.COM if (persistType == STMF_PERSIST_NONE || 5692*9585STim.Szeto@Sun.COM persistType == STMF_PERSIST_SMF) { 5693*9585STim.Szeto@Sun.COM iLibSetPersist = B_TRUE; 5694*9585STim.Szeto@Sun.COM iPersistType = persistType; 5695*9585STim.Szeto@Sun.COM } else { 5696*9585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 5697*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 5698*9585STim.Szeto@Sun.COM } 5699*9585STim.Szeto@Sun.COM /* Is this for this library open or in SMF */ 5700*9585STim.Szeto@Sun.COM if (serviceSet == B_TRUE) { 5701*9585STim.Szeto@Sun.COM ret = psSetServicePersist(persistType); 5702*9585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 5703*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 5704*9585STim.Szeto@Sun.COM /* Set to old value */ 5705*9585STim.Szeto@Sun.COM iPersistType = oldPersist; 5706*9585STim.Szeto@Sun.COM } 5707*9585STim.Szeto@Sun.COM } 5708*9585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 5709*9585STim.Szeto@Sun.COM 5710*9585STim.Szeto@Sun.COM return (ret); 5711*9585STim.Szeto@Sun.COM } 5712*9585STim.Szeto@Sun.COM 5713*9585STim.Szeto@Sun.COM /* 5714*9585STim.Szeto@Sun.COM * Only returns internal state for persist. If unset, goes to ps. If that 5715*9585STim.Szeto@Sun.COM * fails, returns default setting 5716*9585STim.Szeto@Sun.COM */ 5717*9585STim.Szeto@Sun.COM static uint8_t 5718*9585STim.Szeto@Sun.COM iGetPersistMethod() 5719*9585STim.Szeto@Sun.COM { 5720*9585STim.Szeto@Sun.COM 5721*9585STim.Szeto@Sun.COM uint8_t persistType = 0; 5722*9585STim.Szeto@Sun.COM 5723*9585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 5724*9585STim.Szeto@Sun.COM if (iLibSetPersist) { 5725*9585STim.Szeto@Sun.COM persistType = iPersistType; 5726*9585STim.Szeto@Sun.COM } else { 5727*9585STim.Szeto@Sun.COM int ret; 5728*9585STim.Szeto@Sun.COM ret = psGetServicePersist(&persistType); 5729*9585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 5730*9585STim.Szeto@Sun.COM /* set to default */ 5731*9585STim.Szeto@Sun.COM persistType = STMF_DEFAULT_PERSIST; 5732*9585STim.Szeto@Sun.COM } 5733*9585STim.Szeto@Sun.COM } 5734*9585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 5735*9585STim.Szeto@Sun.COM return (persistType); 5736*9585STim.Szeto@Sun.COM } 5737*9585STim.Szeto@Sun.COM 5738*9585STim.Szeto@Sun.COM /* 5739*9585STim.Szeto@Sun.COM * Returns either library state or persistent config state depending on 5740*9585STim.Szeto@Sun.COM * serviceState 5741*9585STim.Szeto@Sun.COM */ 5742*9585STim.Szeto@Sun.COM int 5743*9585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState) 5744*9585STim.Szeto@Sun.COM { 5745*9585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 5746*9585STim.Szeto@Sun.COM 5747*9585STim.Szeto@Sun.COM if (persistType == NULL) { 5748*9585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 5749*9585STim.Szeto@Sun.COM } 5750*9585STim.Szeto@Sun.COM if (serviceState) { 5751*9585STim.Szeto@Sun.COM ret = psGetServicePersist(persistType); 5752*9585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 5753*9585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 5754*9585STim.Szeto@Sun.COM } 5755*9585STim.Szeto@Sun.COM } else { 5756*9585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 5757*9585STim.Szeto@Sun.COM if (iLibSetPersist) { 5758*9585STim.Szeto@Sun.COM *persistType = iPersistType; 5759*9585STim.Szeto@Sun.COM } else { 5760*9585STim.Szeto@Sun.COM *persistType = STMF_DEFAULT_PERSIST; 5761*9585STim.Szeto@Sun.COM } 5762*9585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 5763*9585STim.Szeto@Sun.COM } 5764*9585STim.Szeto@Sun.COM 5765*9585STim.Szeto@Sun.COM return (ret); 5766*9585STim.Szeto@Sun.COM } 5767