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 /* 2211691SSrivijitha.Dugganapalli@Sun.COM * Copyright 2010 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> 469585STim.Szeto@Sun.COM #include <math.h> 479585STim.Szeto@Sun.COM #include <libstmf_impl.h> 487836SJohn.Forte@Sun.COM #include <sys/stmf_ioctl.h> 499585STim.Szeto@Sun.COM #include <sys/stmf_sbd_ioctl.h> 5010725SJohn.Forte@Sun.COM #include <sys/pppt_ioctl.h> 5111103SJohn.Forte@Sun.COM #include <macros.h> 527836SJohn.Forte@Sun.COM 537836SJohn.Forte@Sun.COM #define STMF_PATH "/devices/pseudo/stmf@0:admin" 549585STim.Szeto@Sun.COM #define SBD_PATH "/devices/pseudo/stmf_sbd@0:admin" 5510725SJohn.Forte@Sun.COM #define PPPT_PATH "/devices/pseudo/pppt@0:pppt" 567836SJohn.Forte@Sun.COM 577836SJohn.Forte@Sun.COM #define EUI "eui." 587836SJohn.Forte@Sun.COM #define WWN "wwn." 597836SJohn.Forte@Sun.COM #define IQN "iqn." 609585STim.Szeto@Sun.COM #define LU_ASCII_GUID_SIZE 32 619585STim.Szeto@Sun.COM #define LU_GUID_SIZE 16 629585STim.Szeto@Sun.COM #define OUI_ASCII_SIZE 6 6310765SJohn.Forte@Sun.COM #define HOST_ID_ASCII_SIZE 8 649585STim.Szeto@Sun.COM #define OUI_SIZE 3 6510765SJohn.Forte@Sun.COM #define HOST_ID_SIZE 4 667836SJohn.Forte@Sun.COM #define IDENT_LENGTH_BYTE 3 677836SJohn.Forte@Sun.COM 689585STim.Szeto@Sun.COM /* various initial allocation values */ 699585STim.Szeto@Sun.COM #define ALLOC_LU 8192 709585STim.Szeto@Sun.COM #define ALLOC_TARGET_PORT 2048 719585STim.Szeto@Sun.COM #define ALLOC_PROVIDER 64 729585STim.Szeto@Sun.COM #define ALLOC_GROUP 2048 739585STim.Szeto@Sun.COM #define ALLOC_SESSION 2048 749585STim.Szeto@Sun.COM #define ALLOC_VE 256 759585STim.Szeto@Sun.COM #define ALLOC_PP_DATA_SIZE 128*1024 769585STim.Szeto@Sun.COM #define ALLOC_GRP_MEMBER 256 779585STim.Szeto@Sun.COM 787836SJohn.Forte@Sun.COM #define MAX_ISCSI_NAME 223 799585STim.Szeto@Sun.COM #define MAX_SERIAL_SIZE 252 + 1 809585STim.Szeto@Sun.COM #define MAX_LU_ALIAS_SIZE 256 819585STim.Szeto@Sun.COM #define MAX_SBD_PROPS MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE 827836SJohn.Forte@Sun.COM 837836SJohn.Forte@Sun.COM #define OPEN_STMF 0 847836SJohn.Forte@Sun.COM #define OPEN_EXCL_STMF O_EXCL 857836SJohn.Forte@Sun.COM 869585STim.Szeto@Sun.COM #define OPEN_SBD 0 879585STim.Szeto@Sun.COM #define OPEN_EXCL_SBD O_EXCL 889585STim.Szeto@Sun.COM 8910725SJohn.Forte@Sun.COM #define OPEN_PPPT 0 9010725SJohn.Forte@Sun.COM #define OPEN_EXCL_PPPT O_EXCL 9110725SJohn.Forte@Sun.COM 927836SJohn.Forte@Sun.COM #define LOGICAL_UNIT_TYPE 0 937836SJohn.Forte@Sun.COM #define TARGET_TYPE 1 947836SJohn.Forte@Sun.COM #define STMF_SERVICE_TYPE 2 957836SJohn.Forte@Sun.COM 969585STim.Szeto@Sun.COM #define HOST_GROUP 1 979585STim.Szeto@Sun.COM #define TARGET_GROUP 2 989585STim.Szeto@Sun.COM 999585STim.Szeto@Sun.COM /* set default persistence here */ 1009585STim.Szeto@Sun.COM #define STMF_DEFAULT_PERSIST STMF_PERSIST_SMF 1019585STim.Szeto@Sun.COM 1029585STim.Szeto@Sun.COM #define MAX_PROVIDER_RETRY 30 1039585STim.Szeto@Sun.COM 1047836SJohn.Forte@Sun.COM static int openStmf(int, int *fd); 1059585STim.Szeto@Sun.COM static int openSbd(int, int *fd); 10610725SJohn.Forte@Sun.COM static int openPppt(int, int *fd); 1077836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *); 1087836SJohn.Forte@Sun.COM static int loadStore(int fd); 1097836SJohn.Forte@Sun.COM static int initializeConfig(); 1107836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *); 1117836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *); 1127836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *); 1137836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *); 1147836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *); 1157836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *); 1167836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int); 1179585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *); 1189585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *); 1199585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *); 1209585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid); 1219585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *); 1229585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl); 1239585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *); 1249585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *); 1259585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *); 1269585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t); 1279585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *); 12811103SJohn.Forte@Sun.COM static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen); 1299585STim.Szeto@Sun.COM static int checkHexUpper(char *); 1309585STim.Szeto@Sun.COM static int strToShift(const char *); 1319585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *); 1329585STim.Szeto@Sun.COM static void diskError(uint32_t, int *); 1339585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *); 1349585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *); 1359585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *); 1369585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t); 1379585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod(); 1389585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int); 1399585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int); 1409585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int); 1419585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *); 14210725SJohn.Forte@Sun.COM static int setDiskStandby(stmfGuid *luGuid); 14311103SJohn.Forte@Sun.COM static int setDiskGlobalProp(uint32_t, const char *); 1449585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *); 14510725SJohn.Forte@Sun.COM static void deleteNonActiveLus(); 1469585STim.Szeto@Sun.COM 1479585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER; 1489585STim.Szeto@Sun.COM static int iPersistType = 0; 1499585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */ 1509585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE; 1517836SJohn.Forte@Sun.COM 1527836SJohn.Forte@Sun.COM /* 1537836SJohn.Forte@Sun.COM * Open for stmf module 1547836SJohn.Forte@Sun.COM * 1557836SJohn.Forte@Sun.COM * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF) 1567836SJohn.Forte@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1577836SJohn.Forte@Sun.COM */ 1587836SJohn.Forte@Sun.COM static int 1597836SJohn.Forte@Sun.COM openStmf(int flag, int *fd) 1607836SJohn.Forte@Sun.COM { 1617836SJohn.Forte@Sun.COM int ret = STMF_STATUS_ERROR; 1627836SJohn.Forte@Sun.COM 1637836SJohn.Forte@Sun.COM if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1647836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 1657836SJohn.Forte@Sun.COM } else { 1667836SJohn.Forte@Sun.COM if (errno == EBUSY) { 1677836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 1689585STim.Szeto@Sun.COM } else if (errno == EACCES) { 1699585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1707836SJohn.Forte@Sun.COM } else { 1717836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 1727836SJohn.Forte@Sun.COM } 1737836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)", 1747836SJohn.Forte@Sun.COM STMF_PATH, errno); 1757836SJohn.Forte@Sun.COM } 1767836SJohn.Forte@Sun.COM 1777836SJohn.Forte@Sun.COM return (ret); 1787836SJohn.Forte@Sun.COM } 1797836SJohn.Forte@Sun.COM 1807836SJohn.Forte@Sun.COM /* 1819585STim.Szeto@Sun.COM * Open for sbd module 1829585STim.Szeto@Sun.COM * 18310725SJohn.Forte@Sun.COM * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD) 1849585STim.Szeto@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1859585STim.Szeto@Sun.COM */ 1869585STim.Szeto@Sun.COM static int 1879585STim.Szeto@Sun.COM openSbd(int flag, int *fd) 1889585STim.Szeto@Sun.COM { 1899585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 1909585STim.Szeto@Sun.COM 1919585STim.Szeto@Sun.COM if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1929585STim.Szeto@Sun.COM ret = STMF_STATUS_SUCCESS; 1939585STim.Szeto@Sun.COM } else { 1949585STim.Szeto@Sun.COM if (errno == EBUSY) { 1959585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1969585STim.Szeto@Sun.COM } else if (errno == EACCES) { 1979585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1989585STim.Szeto@Sun.COM } else { 1999585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 2009585STim.Szeto@Sun.COM } 2019585STim.Szeto@Sun.COM syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)", 2029585STim.Szeto@Sun.COM SBD_PATH, errno); 2039585STim.Szeto@Sun.COM } 2049585STim.Szeto@Sun.COM 2059585STim.Szeto@Sun.COM return (ret); 2069585STim.Szeto@Sun.COM } 2079585STim.Szeto@Sun.COM 2089585STim.Szeto@Sun.COM /* 20910725SJohn.Forte@Sun.COM * Open for pppt module 21010725SJohn.Forte@Sun.COM * 21110725SJohn.Forte@Sun.COM * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT) 21210725SJohn.Forte@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 21310725SJohn.Forte@Sun.COM */ 21410725SJohn.Forte@Sun.COM static int 21510725SJohn.Forte@Sun.COM openPppt(int flag, int *fd) 21610725SJohn.Forte@Sun.COM { 21710725SJohn.Forte@Sun.COM int ret = STMF_STATUS_ERROR; 21810725SJohn.Forte@Sun.COM 21910725SJohn.Forte@Sun.COM if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) { 22010725SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 22110725SJohn.Forte@Sun.COM } else { 22210725SJohn.Forte@Sun.COM if (errno == EBUSY) { 22310725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 22410725SJohn.Forte@Sun.COM } else if (errno == EACCES) { 22510725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 22610725SJohn.Forte@Sun.COM } else { 22710725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 22810725SJohn.Forte@Sun.COM } 22910725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)", 23010725SJohn.Forte@Sun.COM PPPT_PATH, errno); 23110725SJohn.Forte@Sun.COM } 23210725SJohn.Forte@Sun.COM 23310725SJohn.Forte@Sun.COM return (ret); 23410725SJohn.Forte@Sun.COM } 23510725SJohn.Forte@Sun.COM 23610725SJohn.Forte@Sun.COM /* 2377836SJohn.Forte@Sun.COM * initializeConfig 2387836SJohn.Forte@Sun.COM * 2397836SJohn.Forte@Sun.COM * This routine should be called before any ioctl requiring initialization 2407836SJohn.Forte@Sun.COM * which is basically everything except stmfGetState(), setStmfState() and 2417836SJohn.Forte@Sun.COM * stmfLoadConfig(). 2427836SJohn.Forte@Sun.COM */ 2437836SJohn.Forte@Sun.COM static int 2447836SJohn.Forte@Sun.COM initializeConfig() 2457836SJohn.Forte@Sun.COM { 2467836SJohn.Forte@Sun.COM int ret; 2477836SJohn.Forte@Sun.COM stmfState state; 2487836SJohn.Forte@Sun.COM 2497836SJohn.Forte@Sun.COM 2507836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2517836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2527836SJohn.Forte@Sun.COM return (ret); 2537836SJohn.Forte@Sun.COM } 2547836SJohn.Forte@Sun.COM 2557836SJohn.Forte@Sun.COM /* if we've already initialized or in the process, return success */ 2567836SJohn.Forte@Sun.COM if (state.configState == STMF_CONFIG_STATE_INIT_DONE || 2577836SJohn.Forte@Sun.COM state.configState == STMF_CONFIG_STATE_INIT) { 2587836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 2597836SJohn.Forte@Sun.COM } 2607836SJohn.Forte@Sun.COM 2617836SJohn.Forte@Sun.COM ret = stmfLoadConfig(); 2627836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2637836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2647836SJohn.Forte@Sun.COM "initializeConfig:stmfLoadConfig:error(%d)", ret); 2657836SJohn.Forte@Sun.COM return (ret); 2667836SJohn.Forte@Sun.COM } 2677836SJohn.Forte@Sun.COM 2687836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2697836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2707836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2717836SJohn.Forte@Sun.COM "initializeConfig:stmfGetState:error(%d)", ret); 2727836SJohn.Forte@Sun.COM return (ret); 2737836SJohn.Forte@Sun.COM } 2747836SJohn.Forte@Sun.COM 2757836SJohn.Forte@Sun.COM if (state.configState != STMF_CONFIG_STATE_INIT_DONE) { 2767836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)", 2777836SJohn.Forte@Sun.COM state.configState); 2787836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 2797836SJohn.Forte@Sun.COM } 2807836SJohn.Forte@Sun.COM 2817836SJohn.Forte@Sun.COM return (ret); 2827836SJohn.Forte@Sun.COM } 2837836SJohn.Forte@Sun.COM 2847836SJohn.Forte@Sun.COM 2857836SJohn.Forte@Sun.COM /* 2867836SJohn.Forte@Sun.COM * groupIoctl 2877836SJohn.Forte@Sun.COM * 2887836SJohn.Forte@Sun.COM * Purpose: issue ioctl for create/delete on group 2897836SJohn.Forte@Sun.COM * 2907836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group cmd 2917836SJohn.Forte@Sun.COM * groupName - groupName to create or delete 2927836SJohn.Forte@Sun.COM */ 2937836SJohn.Forte@Sun.COM static int 2947836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName) 2957836SJohn.Forte@Sun.COM { 2967836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 2977836SJohn.Forte@Sun.COM int ioctlRet; 2987836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 2997836SJohn.Forte@Sun.COM stmf_group_name_t iGroupName; 3007836SJohn.Forte@Sun.COM 3017836SJohn.Forte@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 3027836SJohn.Forte@Sun.COM 3037836SJohn.Forte@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 3047836SJohn.Forte@Sun.COM 3057836SJohn.Forte@Sun.COM iGroupName.name_size = strlen((char *)groupName); 3067836SJohn.Forte@Sun.COM 3077836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3087836SJohn.Forte@Sun.COM /* 3097836SJohn.Forte@Sun.COM * Issue ioctl to create the host group 3107836SJohn.Forte@Sun.COM */ 3117836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3127836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (iGroupName); 3137836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 3147836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3157836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 3167836SJohn.Forte@Sun.COM switch (errno) { 3179585STim.Szeto@Sun.COM case EPERM: 3187836SJohn.Forte@Sun.COM case EACCES: 3197836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 3207836SJohn.Forte@Sun.COM break; 3217836SJohn.Forte@Sun.COM default: 3227836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 3237836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_EXISTS: 3247836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_EXISTS: 3257836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 3267836SJohn.Forte@Sun.COM break; 3277836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_IN_USE: 3287836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_IN_USE: 3297836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_IN_USE; 3307836SJohn.Forte@Sun.COM break; 3317836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 3327836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 3337836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 3347836SJohn.Forte@Sun.COM break; 3357836SJohn.Forte@Sun.COM default: 3367836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 3377836SJohn.Forte@Sun.COM "groupIoctl:error(%d)", 3387836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 3397836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 3407836SJohn.Forte@Sun.COM break; 3417836SJohn.Forte@Sun.COM } 3427836SJohn.Forte@Sun.COM break; 3437836SJohn.Forte@Sun.COM } 3447836SJohn.Forte@Sun.COM } 3457836SJohn.Forte@Sun.COM done: 3467836SJohn.Forte@Sun.COM return (ret); 3477836SJohn.Forte@Sun.COM } 3487836SJohn.Forte@Sun.COM 3497836SJohn.Forte@Sun.COM /* 3509585STim.Szeto@Sun.COM * groupMemberIoctl 3517836SJohn.Forte@Sun.COM * 3527836SJohn.Forte@Sun.COM * Purpose: issue ioctl for add/remove member on group 3537836SJohn.Forte@Sun.COM * 3547836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group member cmd 3557836SJohn.Forte@Sun.COM * groupName - groupName to add to or remove from 3567836SJohn.Forte@Sun.COM * devid - group member to add or remove 3577836SJohn.Forte@Sun.COM */ 3587836SJohn.Forte@Sun.COM static int 3597836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid) 3607836SJohn.Forte@Sun.COM { 3617836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 3627836SJohn.Forte@Sun.COM int ioctlRet; 3637836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 3647836SJohn.Forte@Sun.COM stmf_group_op_data_t stmfGroupData; 3657836SJohn.Forte@Sun.COM 3667836SJohn.Forte@Sun.COM bzero(&stmfGroupData, sizeof (stmfGroupData)); 3677836SJohn.Forte@Sun.COM 3687836SJohn.Forte@Sun.COM bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName)); 3697836SJohn.Forte@Sun.COM 3707836SJohn.Forte@Sun.COM stmfGroupData.group.name_size = strlen((char *)groupName); 3717836SJohn.Forte@Sun.COM stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength; 3727836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1], 3737836SJohn.Forte@Sun.COM devid->identLength); 3747836SJohn.Forte@Sun.COM 3757836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3767836SJohn.Forte@Sun.COM /* 3777836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 3787836SJohn.Forte@Sun.COM */ 3797836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3807836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData); 3817836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData; 3827836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3837836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 3847836SJohn.Forte@Sun.COM switch (errno) { 3857836SJohn.Forte@Sun.COM case EBUSY: 3869884STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 3879884STim.Szeto@Sun.COM case STMF_IOCERR_TG_NEED_TG_OFFLINE: 3889884STim.Szeto@Sun.COM ret = STMF_ERROR_TG_ONLINE; 3899884STim.Szeto@Sun.COM break; 3909884STim.Szeto@Sun.COM default: 3919884STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3929884STim.Szeto@Sun.COM break; 3939884STim.Szeto@Sun.COM } 3947836SJohn.Forte@Sun.COM break; 3959585STim.Szeto@Sun.COM case EPERM: 3967836SJohn.Forte@Sun.COM case EACCES: 3977836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 3987836SJohn.Forte@Sun.COM break; 3997836SJohn.Forte@Sun.COM default: 4007836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 4017836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_ENTRY_EXISTS: 4027836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_ENTRY_EXISTS: 4037836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 4047836SJohn.Forte@Sun.COM break; 4057836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG_ENTRY: 4067836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG_ENTRY: 4077836SJohn.Forte@Sun.COM ret = 4087836SJohn.Forte@Sun.COM STMF_ERROR_MEMBER_NOT_FOUND; 4097836SJohn.Forte@Sun.COM break; 4107836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 4117836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 4127836SJohn.Forte@Sun.COM ret = 4137836SJohn.Forte@Sun.COM STMF_ERROR_GROUP_NOT_FOUND; 4147836SJohn.Forte@Sun.COM break; 4157836SJohn.Forte@Sun.COM default: 4167836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 4177836SJohn.Forte@Sun.COM "groupMemberIoctl:error" 4187836SJohn.Forte@Sun.COM "(%d)", 4197836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 4207836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 4217836SJohn.Forte@Sun.COM break; 4227836SJohn.Forte@Sun.COM } 4237836SJohn.Forte@Sun.COM break; 4247836SJohn.Forte@Sun.COM } 4257836SJohn.Forte@Sun.COM } 4267836SJohn.Forte@Sun.COM done: 4277836SJohn.Forte@Sun.COM return (ret); 4287836SJohn.Forte@Sun.COM } 4297836SJohn.Forte@Sun.COM 4307836SJohn.Forte@Sun.COM /* 4319585STim.Szeto@Sun.COM * qsort function 4329585STim.Szeto@Sun.COM * sort on veIndex 4339585STim.Szeto@Sun.COM */ 4349585STim.Szeto@Sun.COM static int 4359585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2) 4369585STim.Szeto@Sun.COM { 4379585STim.Szeto@Sun.COM 4389585STim.Szeto@Sun.COM stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2; 4399585STim.Szeto@Sun.COM if (v1->veIndex > v2->veIndex) 4409585STim.Szeto@Sun.COM return (1); 4419585STim.Szeto@Sun.COM if (v1->veIndex < v2->veIndex) 4429585STim.Szeto@Sun.COM return (-1); 4439585STim.Szeto@Sun.COM return (0); 4449585STim.Szeto@Sun.COM } 4459585STim.Szeto@Sun.COM 4469585STim.Szeto@Sun.COM /* 4477836SJohn.Forte@Sun.COM * guidCompare 4487836SJohn.Forte@Sun.COM * 4497836SJohn.Forte@Sun.COM * qsort function 4507836SJohn.Forte@Sun.COM * sort on guid 4517836SJohn.Forte@Sun.COM */ 4527836SJohn.Forte@Sun.COM static int 4537836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2) 4547836SJohn.Forte@Sun.COM { 4557836SJohn.Forte@Sun.COM 4567836SJohn.Forte@Sun.COM stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2; 4577836SJohn.Forte@Sun.COM int i; 4587836SJohn.Forte@Sun.COM 4597836SJohn.Forte@Sun.COM for (i = 0; i < sizeof (stmfGuid); i++) { 4607836SJohn.Forte@Sun.COM if (g1->guid[i] > g2->guid[i]) 4617836SJohn.Forte@Sun.COM return (1); 4627836SJohn.Forte@Sun.COM if (g1->guid[i] < g2->guid[i]) 4637836SJohn.Forte@Sun.COM return (-1); 4647836SJohn.Forte@Sun.COM } 4657836SJohn.Forte@Sun.COM 4667836SJohn.Forte@Sun.COM return (0); 4677836SJohn.Forte@Sun.COM } 4687836SJohn.Forte@Sun.COM 4697836SJohn.Forte@Sun.COM /* 4707836SJohn.Forte@Sun.COM * stmfAddToHostGroup 4717836SJohn.Forte@Sun.COM * 4727836SJohn.Forte@Sun.COM * Purpose: Adds an initiator to an existing host group 4737836SJohn.Forte@Sun.COM * 4747836SJohn.Forte@Sun.COM * hostGroupName - name of an existing host group 4757836SJohn.Forte@Sun.COM * hostName - name of initiator to add 4767836SJohn.Forte@Sun.COM */ 4777836SJohn.Forte@Sun.COM int 4787836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 4797836SJohn.Forte@Sun.COM { 4807836SJohn.Forte@Sun.COM int ret; 4817836SJohn.Forte@Sun.COM int fd; 4827836SJohn.Forte@Sun.COM 4837836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 4847836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 4857836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 4867836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 4877836SJohn.Forte@Sun.COM } 4887836SJohn.Forte@Sun.COM 4897836SJohn.Forte@Sun.COM /* call init */ 4907836SJohn.Forte@Sun.COM ret = initializeConfig(); 4917836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4927836SJohn.Forte@Sun.COM return (ret); 4937836SJohn.Forte@Sun.COM } 4947836SJohn.Forte@Sun.COM 4957836SJohn.Forte@Sun.COM /* 4967836SJohn.Forte@Sun.COM * Open control node for stmf 4977836SJohn.Forte@Sun.COM */ 4987836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4997836SJohn.Forte@Sun.COM return (ret); 5007836SJohn.Forte@Sun.COM 5017836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName, 5027836SJohn.Forte@Sun.COM hostName)) != STMF_STATUS_SUCCESS) { 5037836SJohn.Forte@Sun.COM goto done; 5047836SJohn.Forte@Sun.COM } 5057836SJohn.Forte@Sun.COM 5069585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5079585STim.Szeto@Sun.COM goto done; 5089585STim.Szeto@Sun.COM } 5099585STim.Szeto@Sun.COM 5107836SJohn.Forte@Sun.COM ret = psAddHostGroupMember((char *)hostGroupName, 5117836SJohn.Forte@Sun.COM (char *)hostName->ident); 5127836SJohn.Forte@Sun.COM switch (ret) { 5137836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 5147836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 5157836SJohn.Forte@Sun.COM break; 5167836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 5177836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 5187836SJohn.Forte@Sun.COM break; 5197836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 5207836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 5217836SJohn.Forte@Sun.COM break; 5227836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 5237836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 5247836SJohn.Forte@Sun.COM break; 5257836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 5267836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 5277836SJohn.Forte@Sun.COM break; 5287836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 5297836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 5307836SJohn.Forte@Sun.COM break; 5317836SJohn.Forte@Sun.COM default: 5327836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 5337836SJohn.Forte@Sun.COM "stmfAddToHostGroup:psAddHostGroupMember:error(%d)", 5347836SJohn.Forte@Sun.COM ret); 5357836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 5367836SJohn.Forte@Sun.COM break; 5377836SJohn.Forte@Sun.COM } 5387836SJohn.Forte@Sun.COM 5397836SJohn.Forte@Sun.COM done: 5407836SJohn.Forte@Sun.COM (void) close(fd); 5417836SJohn.Forte@Sun.COM return (ret); 5427836SJohn.Forte@Sun.COM } 5437836SJohn.Forte@Sun.COM 5447836SJohn.Forte@Sun.COM /* 5457836SJohn.Forte@Sun.COM * stmfAddToTargetGroup 5467836SJohn.Forte@Sun.COM * 5477836SJohn.Forte@Sun.COM * Purpose: Adds a local port to an existing target group 5487836SJohn.Forte@Sun.COM * 5497836SJohn.Forte@Sun.COM * targetGroupName - name of an existing target group 5507836SJohn.Forte@Sun.COM * targetName - name of target to add 5517836SJohn.Forte@Sun.COM */ 5527836SJohn.Forte@Sun.COM int 5537836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 5547836SJohn.Forte@Sun.COM { 5557836SJohn.Forte@Sun.COM int ret; 5567836SJohn.Forte@Sun.COM int fd; 5577836SJohn.Forte@Sun.COM 5587836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 5597836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 5607836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 5617836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 5627836SJohn.Forte@Sun.COM } 5637836SJohn.Forte@Sun.COM 5647836SJohn.Forte@Sun.COM /* call init */ 5657836SJohn.Forte@Sun.COM ret = initializeConfig(); 5667836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 5677836SJohn.Forte@Sun.COM return (ret); 5687836SJohn.Forte@Sun.COM } 5697836SJohn.Forte@Sun.COM 5707836SJohn.Forte@Sun.COM /* 5717836SJohn.Forte@Sun.COM * Open control node for stmf 5727836SJohn.Forte@Sun.COM */ 5737836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 5747836SJohn.Forte@Sun.COM return (ret); 5757836SJohn.Forte@Sun.COM 5767836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 5777836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 5787836SJohn.Forte@Sun.COM goto done; 5797836SJohn.Forte@Sun.COM } 5807836SJohn.Forte@Sun.COM 5819585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5829585STim.Szeto@Sun.COM goto done; 5839585STim.Szeto@Sun.COM } 5849585STim.Szeto@Sun.COM 5857836SJohn.Forte@Sun.COM ret = psAddTargetGroupMember((char *)targetGroupName, 5867836SJohn.Forte@Sun.COM (char *)targetName->ident); 5877836SJohn.Forte@Sun.COM switch (ret) { 5887836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 5897836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 5907836SJohn.Forte@Sun.COM break; 5917836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 5927836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 5937836SJohn.Forte@Sun.COM break; 5947836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 5957836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 5967836SJohn.Forte@Sun.COM break; 5977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 5987836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 5997836SJohn.Forte@Sun.COM break; 6007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 6017836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 6027836SJohn.Forte@Sun.COM break; 6037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 6047836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 6057836SJohn.Forte@Sun.COM break; 6067836SJohn.Forte@Sun.COM default: 6077836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 6087836SJohn.Forte@Sun.COM "stmfAddToTargetGroup:psAddTargetGroupMember:" 6097836SJohn.Forte@Sun.COM "error(%d)", ret); 6107836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 6117836SJohn.Forte@Sun.COM break; 6127836SJohn.Forte@Sun.COM } 6137836SJohn.Forte@Sun.COM 6147836SJohn.Forte@Sun.COM done: 6157836SJohn.Forte@Sun.COM (void) close(fd); 6167836SJohn.Forte@Sun.COM return (ret); 6177836SJohn.Forte@Sun.COM } 6187836SJohn.Forte@Sun.COM 6197836SJohn.Forte@Sun.COM /* 6207836SJohn.Forte@Sun.COM * addViewEntryIoctl 6217836SJohn.Forte@Sun.COM * 6227836SJohn.Forte@Sun.COM * Purpose: Issues ioctl to add a view entry 6237836SJohn.Forte@Sun.COM * 6247836SJohn.Forte@Sun.COM * lu - Logical Unit identifier to which the view entry is added 6257836SJohn.Forte@Sun.COM * viewEntry - view entry to add 6267836SJohn.Forte@Sun.COM * init - When set to B_TRUE, we are in the init state, i.e. don't call open 6277836SJohn.Forte@Sun.COM */ 6287836SJohn.Forte@Sun.COM static int 6297836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry) 6307836SJohn.Forte@Sun.COM { 6317836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 6327836SJohn.Forte@Sun.COM int ioctlRet; 6337836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 6347836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 6357836SJohn.Forte@Sun.COM 6367836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 6377836SJohn.Forte@Sun.COM /* 6387836SJohn.Forte@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 6397836SJohn.Forte@Sun.COM * false on input 6407836SJohn.Forte@Sun.COM */ 6417836SJohn.Forte@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 6427836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 6437836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 6447836SJohn.Forte@Sun.COM 6457836SJohn.Forte@Sun.COM if (viewEntry->allHosts == B_FALSE) { 6467836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 6477836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6487836SJohn.Forte@Sun.COM ioctlViewEntry.ve_host_group.name_size = 6497836SJohn.Forte@Sun.COM strlen((char *)viewEntry->hostGroup); 6507836SJohn.Forte@Sun.COM } 6517836SJohn.Forte@Sun.COM if (viewEntry->allTargets == B_FALSE) { 6527836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, 6537836SJohn.Forte@Sun.COM &ioctlViewEntry.ve_target_group.name, 6547836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6557836SJohn.Forte@Sun.COM ioctlViewEntry.ve_target_group.name_size = 6567836SJohn.Forte@Sun.COM strlen((char *)viewEntry->targetGroup); 6577836SJohn.Forte@Sun.COM } 6587836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 6597836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 6607836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 6617836SJohn.Forte@Sun.COM } 6627836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 6637836SJohn.Forte@Sun.COM 6647836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 6657836SJohn.Forte@Sun.COM /* 6667836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 6677836SJohn.Forte@Sun.COM */ 6687836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 6697836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 6707836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6717836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 6727836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6737836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl); 6747836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 6757836SJohn.Forte@Sun.COM switch (errno) { 6767836SJohn.Forte@Sun.COM case EBUSY: 6777836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 6787836SJohn.Forte@Sun.COM break; 6799585STim.Szeto@Sun.COM case EPERM: 6809585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 6819585STim.Szeto@Sun.COM break; 6827836SJohn.Forte@Sun.COM case EACCES: 6837836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6847836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6857836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6867836SJohn.Forte@Sun.COM break; 6877836SJohn.Forte@Sun.COM default: 6887836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 6897836SJohn.Forte@Sun.COM break; 6907836SJohn.Forte@Sun.COM } 6917836SJohn.Forte@Sun.COM break; 6927836SJohn.Forte@Sun.COM default: 6937836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6947836SJohn.Forte@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 6957836SJohn.Forte@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 6967836SJohn.Forte@Sun.COM break; 6977836SJohn.Forte@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 6987836SJohn.Forte@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 6997836SJohn.Forte@Sun.COM break; 7007836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 7017836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 7027836SJohn.Forte@Sun.COM break; 7037836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 7047836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_HG; 7057836SJohn.Forte@Sun.COM break; 7067836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 7077836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_TG; 7087836SJohn.Forte@Sun.COM break; 7097836SJohn.Forte@Sun.COM default: 7107836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 7117836SJohn.Forte@Sun.COM "addViewEntryIoctl" 7127836SJohn.Forte@Sun.COM ":error(%d)", 7137836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 7147836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 7157836SJohn.Forte@Sun.COM break; 7167836SJohn.Forte@Sun.COM } 7177836SJohn.Forte@Sun.COM break; 7187836SJohn.Forte@Sun.COM } 7197836SJohn.Forte@Sun.COM goto done; 7207836SJohn.Forte@Sun.COM } 7217836SJohn.Forte@Sun.COM 7227836SJohn.Forte@Sun.COM /* copy lu nbr back to caller's view entry on success */ 7237836SJohn.Forte@Sun.COM viewEntry->veIndex = ioctlViewEntry.ve_ndx; 7247836SJohn.Forte@Sun.COM if (ioctlViewEntry.ve_lu_number_valid) { 7257836SJohn.Forte@Sun.COM bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 7267836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 7277836SJohn.Forte@Sun.COM } 7287836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 7297836SJohn.Forte@Sun.COM 7307836SJohn.Forte@Sun.COM done: 7317836SJohn.Forte@Sun.COM return (ret); 7327836SJohn.Forte@Sun.COM } 7337836SJohn.Forte@Sun.COM 7347836SJohn.Forte@Sun.COM /* 7357836SJohn.Forte@Sun.COM * stmfAddViewEntry 7367836SJohn.Forte@Sun.COM * 7377836SJohn.Forte@Sun.COM * Purpose: Adds a view entry to a logical unit 7387836SJohn.Forte@Sun.COM * 7397836SJohn.Forte@Sun.COM * lu - guid of the logical unit to which the view entry is added 7407836SJohn.Forte@Sun.COM * viewEntry - view entry structure to add 7417836SJohn.Forte@Sun.COM */ 7427836SJohn.Forte@Sun.COM int 7437836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry) 7447836SJohn.Forte@Sun.COM { 7457836SJohn.Forte@Sun.COM int ret; 7467836SJohn.Forte@Sun.COM int fd; 7477836SJohn.Forte@Sun.COM stmfViewEntry iViewEntry; 7487836SJohn.Forte@Sun.COM 7497836SJohn.Forte@Sun.COM if (lu == NULL || viewEntry == NULL) { 7507836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 7517836SJohn.Forte@Sun.COM } 7527836SJohn.Forte@Sun.COM 7537836SJohn.Forte@Sun.COM /* initialize and set internal view entry */ 7547836SJohn.Forte@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 7557836SJohn.Forte@Sun.COM 7567836SJohn.Forte@Sun.COM if (!viewEntry->allHosts) { 7577836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 7587836SJohn.Forte@Sun.COM sizeof (iViewEntry.hostGroup)); 7597836SJohn.Forte@Sun.COM } else { 7607836SJohn.Forte@Sun.COM iViewEntry.allHosts = B_TRUE; 7617836SJohn.Forte@Sun.COM } 7627836SJohn.Forte@Sun.COM 7637836SJohn.Forte@Sun.COM if (!viewEntry->allTargets) { 7647836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 7657836SJohn.Forte@Sun.COM sizeof (iViewEntry.targetGroup)); 7667836SJohn.Forte@Sun.COM } else { 7677836SJohn.Forte@Sun.COM iViewEntry.allTargets = B_TRUE; 7687836SJohn.Forte@Sun.COM } 7697836SJohn.Forte@Sun.COM 7707836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 7717836SJohn.Forte@Sun.COM iViewEntry.luNbrValid = B_TRUE; 7727836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 7737836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 7747836SJohn.Forte@Sun.COM } 7757836SJohn.Forte@Sun.COM 7767836SJohn.Forte@Sun.COM /* 7777836SJohn.Forte@Sun.COM * set users return view entry index valid flag to false 7787836SJohn.Forte@Sun.COM * in case of failure 7797836SJohn.Forte@Sun.COM */ 7807836SJohn.Forte@Sun.COM viewEntry->veIndexValid = B_FALSE; 7817836SJohn.Forte@Sun.COM 7827836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 7837836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 7847836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 7857836SJohn.Forte@Sun.COM } 7867836SJohn.Forte@Sun.COM 7877836SJohn.Forte@Sun.COM /* call init */ 7887836SJohn.Forte@Sun.COM ret = initializeConfig(); 7897836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7907836SJohn.Forte@Sun.COM return (ret); 7917836SJohn.Forte@Sun.COM } 7927836SJohn.Forte@Sun.COM 7937836SJohn.Forte@Sun.COM /* 7947836SJohn.Forte@Sun.COM * Open control node for stmf 7957836SJohn.Forte@Sun.COM */ 7967836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 7977836SJohn.Forte@Sun.COM return (ret); 7987836SJohn.Forte@Sun.COM 7997836SJohn.Forte@Sun.COM /* 8007836SJohn.Forte@Sun.COM * First add the view entry to the driver 8017836SJohn.Forte@Sun.COM */ 8027836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, lu, &iViewEntry); 8037836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 8047836SJohn.Forte@Sun.COM goto done; 8057836SJohn.Forte@Sun.COM } 8067836SJohn.Forte@Sun.COM 8079585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 8089585STim.Szeto@Sun.COM goto done; 8099585STim.Szeto@Sun.COM } 8109585STim.Szeto@Sun.COM 8117836SJohn.Forte@Sun.COM /* 8127836SJohn.Forte@Sun.COM * If the add to driver was successful, add it to the persistent 8137836SJohn.Forte@Sun.COM * store. 8147836SJohn.Forte@Sun.COM */ 8157836SJohn.Forte@Sun.COM ret = psAddViewEntry(lu, &iViewEntry); 8167836SJohn.Forte@Sun.COM switch (ret) { 8177836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 8187836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 8197836SJohn.Forte@Sun.COM break; 8207836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 8217836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 8227836SJohn.Forte@Sun.COM break; 8237836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 8247836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 8257836SJohn.Forte@Sun.COM break; 8267836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 8277836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 8287836SJohn.Forte@Sun.COM break; 8297836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 8307836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 8317836SJohn.Forte@Sun.COM break; 8327836SJohn.Forte@Sun.COM default: 8337836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 8347836SJohn.Forte@Sun.COM "stmfAddViewEntry:psAddViewEntry:error(%d)", ret); 8357836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 8367836SJohn.Forte@Sun.COM break; 8377836SJohn.Forte@Sun.COM } 8387836SJohn.Forte@Sun.COM 8397836SJohn.Forte@Sun.COM done: 8407836SJohn.Forte@Sun.COM (void) close(fd); 8417836SJohn.Forte@Sun.COM 8427836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 8437836SJohn.Forte@Sun.COM /* set caller's view entry on success */ 8447836SJohn.Forte@Sun.COM viewEntry->veIndexValid = iViewEntry.veIndexValid; 8457836SJohn.Forte@Sun.COM viewEntry->veIndex = iViewEntry.veIndex; 8467836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 8477836SJohn.Forte@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 8487836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 8497836SJohn.Forte@Sun.COM } 8507836SJohn.Forte@Sun.COM return (ret); 8517836SJohn.Forte@Sun.COM } 8527836SJohn.Forte@Sun.COM 8537836SJohn.Forte@Sun.COM /* 8547836SJohn.Forte@Sun.COM * stmfClearProviderData 8557836SJohn.Forte@Sun.COM * 8567836SJohn.Forte@Sun.COM * Purpose: delete all provider data for specified provider 8577836SJohn.Forte@Sun.COM * 8587836SJohn.Forte@Sun.COM * providerName - name of provider for which data should be deleted 8597836SJohn.Forte@Sun.COM */ 8607836SJohn.Forte@Sun.COM int 8617836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType) 8627836SJohn.Forte@Sun.COM { 8637836SJohn.Forte@Sun.COM int ret; 8647836SJohn.Forte@Sun.COM int fd; 8657836SJohn.Forte@Sun.COM int ioctlRet; 8667836SJohn.Forte@Sun.COM int savedErrno; 8677836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 8687836SJohn.Forte@Sun.COM stmf_ppioctl_data_t ppi; 8697836SJohn.Forte@Sun.COM 8707836SJohn.Forte@Sun.COM /* call init */ 8717836SJohn.Forte@Sun.COM ret = initializeConfig(); 8727836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 8737836SJohn.Forte@Sun.COM return (ret); 8747836SJohn.Forte@Sun.COM } 8757836SJohn.Forte@Sun.COM 8767836SJohn.Forte@Sun.COM if (providerName == NULL) { 8777836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8787836SJohn.Forte@Sun.COM } 8797836SJohn.Forte@Sun.COM 8807836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 8817836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 8827836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8837836SJohn.Forte@Sun.COM } 8847836SJohn.Forte@Sun.COM 8857836SJohn.Forte@Sun.COM /* 8867836SJohn.Forte@Sun.COM * Open control node for stmf 8877836SJohn.Forte@Sun.COM */ 8887836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 8897836SJohn.Forte@Sun.COM return (ret); 8907836SJohn.Forte@Sun.COM 8917836SJohn.Forte@Sun.COM bzero(&ppi, sizeof (ppi)); 8927836SJohn.Forte@Sun.COM 8937836SJohn.Forte@Sun.COM (void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name)); 8947836SJohn.Forte@Sun.COM 8957836SJohn.Forte@Sun.COM switch (providerType) { 8967836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 8977836SJohn.Forte@Sun.COM ppi.ppi_lu_provider = 1; 8987836SJohn.Forte@Sun.COM break; 8997836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 9007836SJohn.Forte@Sun.COM ppi.ppi_port_provider = 1; 9017836SJohn.Forte@Sun.COM break; 9027836SJohn.Forte@Sun.COM default: 9037836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 9047836SJohn.Forte@Sun.COM goto done; 9057836SJohn.Forte@Sun.COM } 9067836SJohn.Forte@Sun.COM 9077836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 9087836SJohn.Forte@Sun.COM 9097836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 9107836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 9117836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 9127836SJohn.Forte@Sun.COM 9137836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl); 9147836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 9157836SJohn.Forte@Sun.COM savedErrno = errno; 9167836SJohn.Forte@Sun.COM switch (savedErrno) { 9177836SJohn.Forte@Sun.COM case EBUSY: 9187836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9197836SJohn.Forte@Sun.COM break; 9209585STim.Szeto@Sun.COM case EPERM: 9217836SJohn.Forte@Sun.COM case EACCES: 9227836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 9237836SJohn.Forte@Sun.COM break; 9247836SJohn.Forte@Sun.COM default: 9257836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9267836SJohn.Forte@Sun.COM "stmfClearProviderData:ioctl error(%d)", 9277836SJohn.Forte@Sun.COM ioctlRet); 9287836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9297836SJohn.Forte@Sun.COM break; 9307836SJohn.Forte@Sun.COM } 9317836SJohn.Forte@Sun.COM if (savedErrno != ENOENT) { 9327836SJohn.Forte@Sun.COM goto done; 9337836SJohn.Forte@Sun.COM } 9347836SJohn.Forte@Sun.COM } 9357836SJohn.Forte@Sun.COM 9369585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 9379585STim.Szeto@Sun.COM goto done; 9389585STim.Szeto@Sun.COM } 9399585STim.Szeto@Sun.COM 9407836SJohn.Forte@Sun.COM ret = psClearProviderData(providerName, providerType); 9417836SJohn.Forte@Sun.COM switch (ret) { 9427836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 9437836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 9447836SJohn.Forte@Sun.COM break; 9457836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 9467836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 9477836SJohn.Forte@Sun.COM break; 9487836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 9497836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9507836SJohn.Forte@Sun.COM break; 9517836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 9527836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 9537836SJohn.Forte@Sun.COM break; 9547836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 9557836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 9567836SJohn.Forte@Sun.COM break; 9577836SJohn.Forte@Sun.COM default: 9587836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9597836SJohn.Forte@Sun.COM "stmfClearProviderData:psClearProviderData" 9607836SJohn.Forte@Sun.COM ":error(%d)", ret); 9617836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9627836SJohn.Forte@Sun.COM break; 9637836SJohn.Forte@Sun.COM } 9647836SJohn.Forte@Sun.COM 9657836SJohn.Forte@Sun.COM done: 9667836SJohn.Forte@Sun.COM (void) close(fd); 9677836SJohn.Forte@Sun.COM return (ret); 9687836SJohn.Forte@Sun.COM } 9697836SJohn.Forte@Sun.COM 9707836SJohn.Forte@Sun.COM /* 9717836SJohn.Forte@Sun.COM * stmfCreateHostGroup 9727836SJohn.Forte@Sun.COM * 9737836SJohn.Forte@Sun.COM * Purpose: Create a new initiator group 9747836SJohn.Forte@Sun.COM * 9757836SJohn.Forte@Sun.COM * hostGroupName - name of host group to create 9767836SJohn.Forte@Sun.COM */ 9777836SJohn.Forte@Sun.COM int 9787836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName) 9797836SJohn.Forte@Sun.COM { 9807836SJohn.Forte@Sun.COM int ret; 9817836SJohn.Forte@Sun.COM int fd; 9827836SJohn.Forte@Sun.COM 9837836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 9847836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 9857836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 9867836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 9877836SJohn.Forte@Sun.COM } 9887836SJohn.Forte@Sun.COM 9897836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 9907836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 9917836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 9927836SJohn.Forte@Sun.COM } 9937836SJohn.Forte@Sun.COM 9947836SJohn.Forte@Sun.COM /* call init */ 9957836SJohn.Forte@Sun.COM ret = initializeConfig(); 9967836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 9977836SJohn.Forte@Sun.COM return (ret); 9987836SJohn.Forte@Sun.COM } 9997836SJohn.Forte@Sun.COM 10007836SJohn.Forte@Sun.COM /* 10017836SJohn.Forte@Sun.COM * Open control node for stmf 10027836SJohn.Forte@Sun.COM */ 10037836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 10047836SJohn.Forte@Sun.COM return (ret); 10057836SJohn.Forte@Sun.COM 10067836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 10077836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 10087836SJohn.Forte@Sun.COM goto done; 10097836SJohn.Forte@Sun.COM } 10107836SJohn.Forte@Sun.COM 10119585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 10129585STim.Szeto@Sun.COM goto done; 10139585STim.Szeto@Sun.COM } 10149585STim.Szeto@Sun.COM 10157836SJohn.Forte@Sun.COM ret = psCreateHostGroup((char *)hostGroupName); 10167836SJohn.Forte@Sun.COM switch (ret) { 10177836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 10187836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 10197836SJohn.Forte@Sun.COM break; 10207836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 10217836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 10227836SJohn.Forte@Sun.COM break; 10237836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 10247836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 10257836SJohn.Forte@Sun.COM break; 10267836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 10277836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 10287836SJohn.Forte@Sun.COM break; 10297836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 10307836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 10317836SJohn.Forte@Sun.COM break; 10327836SJohn.Forte@Sun.COM default: 10337836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 10347836SJohn.Forte@Sun.COM "stmfCreateHostGroup:psCreateHostGroup:error(%d)", 10357836SJohn.Forte@Sun.COM ret); 10367836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 10377836SJohn.Forte@Sun.COM break; 10387836SJohn.Forte@Sun.COM } 10397836SJohn.Forte@Sun.COM 10407836SJohn.Forte@Sun.COM done: 10417836SJohn.Forte@Sun.COM (void) close(fd); 10427836SJohn.Forte@Sun.COM return (ret); 10437836SJohn.Forte@Sun.COM } 10447836SJohn.Forte@Sun.COM 10457836SJohn.Forte@Sun.COM /* 10469585STim.Szeto@Sun.COM * stmfCreateLu 10479585STim.Szeto@Sun.COM * 10489585STim.Szeto@Sun.COM * Purpose: Create a logical unit 10499585STim.Szeto@Sun.COM * 10509585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 10519585STim.Szeto@Sun.COM * 10529585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 10539585STim.Szeto@Sun.COM * unit 10549585STim.Szeto@Sun.COM */ 10559585STim.Szeto@Sun.COM int 10569585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid) 10579585STim.Szeto@Sun.COM { 10589585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10599585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 10609585STim.Szeto@Sun.COM 10619585STim.Szeto@Sun.COM if (hdl == NULL) { 10629585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10639585STim.Szeto@Sun.COM } 10649585STim.Szeto@Sun.COM 10659585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 10669585STim.Szeto@Sun.COM ret = createDiskLu((diskResource *)luPropsHdl->resource, 10679585STim.Szeto@Sun.COM luGuid); 10689585STim.Szeto@Sun.COM } else { 10699585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10709585STim.Szeto@Sun.COM } 10719585STim.Szeto@Sun.COM 10729585STim.Szeto@Sun.COM return (ret); 10739585STim.Szeto@Sun.COM } 10749585STim.Szeto@Sun.COM 10759585STim.Szeto@Sun.COM /* 10769585STim.Szeto@Sun.COM * stmfCreateLuResource 10779585STim.Szeto@Sun.COM * 10789585STim.Szeto@Sun.COM * Purpose: Create resource handle for a logical unit 10799585STim.Szeto@Sun.COM * 10809585STim.Szeto@Sun.COM * dType - Type of logical unit resource to create 10819585STim.Szeto@Sun.COM * Can be: STMF_DISK 10829585STim.Szeto@Sun.COM * 10839585STim.Szeto@Sun.COM * hdl - pointer to luResource 10849585STim.Szeto@Sun.COM */ 10859585STim.Szeto@Sun.COM int 10869585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl) 10879585STim.Szeto@Sun.COM { 10889585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10899585STim.Szeto@Sun.COM 10909585STim.Szeto@Sun.COM if (dType != STMF_DISK || hdl == NULL) { 10919585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10929585STim.Szeto@Sun.COM } 10939585STim.Szeto@Sun.COM 10949585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 10959585STim.Szeto@Sun.COM if (*hdl == NULL) { 10969585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 10979585STim.Szeto@Sun.COM } 10989585STim.Szeto@Sun.COM 10999585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 11009585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 11019585STim.Szeto@Sun.COM free(*hdl); 11029585STim.Szeto@Sun.COM return (ret); 11039585STim.Szeto@Sun.COM } 11049585STim.Szeto@Sun.COM 11059585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 11069585STim.Szeto@Sun.COM } 11079585STim.Szeto@Sun.COM 11089585STim.Szeto@Sun.COM /* 11099585STim.Szeto@Sun.COM * Creates a disk logical unit 11109585STim.Szeto@Sun.COM * 11119585STim.Szeto@Sun.COM * disk - pointer to diskResource structure that represents the properties 11129585STim.Szeto@Sun.COM * for the disk logical unit to be created. 11139585STim.Szeto@Sun.COM */ 11149585STim.Szeto@Sun.COM static int 11159585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid) 11169585STim.Szeto@Sun.COM { 11179585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 11189585STim.Szeto@Sun.COM int dataFileNameLen = 0; 11199585STim.Szeto@Sun.COM int metaFileNameLen = 0; 11209585STim.Szeto@Sun.COM int serialNumLen = 0; 11219585STim.Szeto@Sun.COM int luAliasLen = 0; 112210113SNattuvetty.Bhavyan@Sun.COM int luMgmtUrlLen = 0; 11239585STim.Szeto@Sun.COM int sluBufSize = 0; 11249585STim.Szeto@Sun.COM int bufOffset = 0; 11259585STim.Szeto@Sun.COM int fd = 0; 11269585STim.Szeto@Sun.COM int ioctlRet; 11279585STim.Szeto@Sun.COM int savedErrno; 11289585STim.Szeto@Sun.COM stmfGuid guid; 11299585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 11309585STim.Szeto@Sun.COM 11319585STim.Szeto@Sun.COM sbd_create_and_reg_lu_t *sbdLu = NULL; 11329585STim.Szeto@Sun.COM 11339585STim.Szeto@Sun.COM /* 11349585STim.Szeto@Sun.COM * Open control node for sbd 11359585STim.Szeto@Sun.COM */ 11369585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 11379585STim.Szeto@Sun.COM return (ret); 11389585STim.Szeto@Sun.COM 11399585STim.Szeto@Sun.COM /* data file name must be specified */ 11409585STim.Szeto@Sun.COM if (disk->luDataFileNameValid) { 11419585STim.Szeto@Sun.COM dataFileNameLen = strlen(disk->luDataFileName); 11429585STim.Szeto@Sun.COM } else { 11439585STim.Szeto@Sun.COM (void) close(fd); 11449585STim.Szeto@Sun.COM return (STMF_ERROR_MISSING_PROP_VAL); 11459585STim.Szeto@Sun.COM } 11469585STim.Szeto@Sun.COM 11479585STim.Szeto@Sun.COM sluBufSize += dataFileNameLen + 1; 11489585STim.Szeto@Sun.COM 11499585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 11509585STim.Szeto@Sun.COM metaFileNameLen = strlen(disk->luMetaFileName); 11519585STim.Szeto@Sun.COM sluBufSize += metaFileNameLen + 1; 11529585STim.Szeto@Sun.COM } 11539585STim.Szeto@Sun.COM 11549585STim.Szeto@Sun.COM serialNumLen = strlen(disk->serialNum); 11559585STim.Szeto@Sun.COM sluBufSize += serialNumLen; 11569585STim.Szeto@Sun.COM 11579585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11589585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 11599585STim.Szeto@Sun.COM sluBufSize += luAliasLen + 1; 11609585STim.Szeto@Sun.COM } 11619585STim.Szeto@Sun.COM 116210113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 116310113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen = strlen(disk->luMgmtUrl); 116410113SNattuvetty.Bhavyan@Sun.COM sluBufSize += luMgmtUrlLen + 1; 116510113SNattuvetty.Bhavyan@Sun.COM } 116610113SNattuvetty.Bhavyan@Sun.COM 11679585STim.Szeto@Sun.COM /* 11689585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 11699585STim.Szeto@Sun.COM * concatenation of variable length fields 11709585STim.Szeto@Sun.COM */ 11719585STim.Szeto@Sun.COM sbdLu = (sbd_create_and_reg_lu_t *)calloc(1, 11729585STim.Szeto@Sun.COM sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8); 11739585STim.Szeto@Sun.COM if (sbdLu == NULL) { 11749585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 11759585STim.Szeto@Sun.COM } 11769585STim.Szeto@Sun.COM 11779585STim.Szeto@Sun.COM sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) + 11789585STim.Szeto@Sun.COM sluBufSize - 8; 11799585STim.Szeto@Sun.COM 11809585STim.Szeto@Sun.COM if (metaFileNameLen) { 11819585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_valid = 1; 11829585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_off = bufOffset; 11839585STim.Szeto@Sun.COM bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]), 11849585STim.Szeto@Sun.COM metaFileNameLen + 1); 11859585STim.Szeto@Sun.COM bufOffset += metaFileNameLen + 1; 11869585STim.Szeto@Sun.COM } 11879585STim.Szeto@Sun.COM 11889585STim.Szeto@Sun.COM bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]), 11899585STim.Szeto@Sun.COM dataFileNameLen + 1); 11909585STim.Szeto@Sun.COM sbdLu->slu_data_fname_off = bufOffset; 11919585STim.Szeto@Sun.COM bufOffset += dataFileNameLen + 1; 11929585STim.Szeto@Sun.COM 11939585STim.Szeto@Sun.COM /* currently, serial # is not passed null terminated to the driver */ 11949585STim.Szeto@Sun.COM if (disk->serialNumValid) { 11959585STim.Szeto@Sun.COM sbdLu->slu_serial_valid = 1; 11969585STim.Szeto@Sun.COM sbdLu->slu_serial_off = bufOffset; 11979585STim.Szeto@Sun.COM sbdLu->slu_serial_size = serialNumLen; 11989585STim.Szeto@Sun.COM bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]), 11999585STim.Szeto@Sun.COM serialNumLen); 12009585STim.Szeto@Sun.COM bufOffset += serialNumLen; 12019585STim.Szeto@Sun.COM } 12029585STim.Szeto@Sun.COM 12039585STim.Szeto@Sun.COM if (disk->luAliasValid) { 12049585STim.Szeto@Sun.COM sbdLu->slu_alias_valid = 1; 12059585STim.Szeto@Sun.COM sbdLu->slu_alias_off = bufOffset; 12069585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]), 12079585STim.Szeto@Sun.COM luAliasLen + 1); 12089585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 12099585STim.Szeto@Sun.COM } 12109585STim.Szeto@Sun.COM 121110113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 121210113SNattuvetty.Bhavyan@Sun.COM sbdLu->slu_mgmt_url_valid = 1; 121310113SNattuvetty.Bhavyan@Sun.COM sbdLu->slu_mgmt_url_off = bufOffset; 121410113SNattuvetty.Bhavyan@Sun.COM bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]), 121510113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen + 1); 121610113SNattuvetty.Bhavyan@Sun.COM bufOffset += luMgmtUrlLen + 1; 121710113SNattuvetty.Bhavyan@Sun.COM } 121810113SNattuvetty.Bhavyan@Sun.COM 12199585STim.Szeto@Sun.COM if (disk->luSizeValid) { 12209585STim.Szeto@Sun.COM sbdLu->slu_lu_size_valid = 1; 12219585STim.Szeto@Sun.COM sbdLu->slu_lu_size = disk->luSize; 12229585STim.Szeto@Sun.COM } 12239585STim.Szeto@Sun.COM 12249585STim.Szeto@Sun.COM if (disk->luGuidValid) { 12259585STim.Szeto@Sun.COM sbdLu->slu_guid_valid = 1; 12269585STim.Szeto@Sun.COM bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid)); 12279585STim.Szeto@Sun.COM } 12289585STim.Szeto@Sun.COM 12299585STim.Szeto@Sun.COM if (disk->vidValid) { 12309585STim.Szeto@Sun.COM sbdLu->slu_vid_valid = 1; 12319585STim.Szeto@Sun.COM bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid)); 12329585STim.Szeto@Sun.COM } 12339585STim.Szeto@Sun.COM 12349585STim.Szeto@Sun.COM if (disk->pidValid) { 12359585STim.Szeto@Sun.COM sbdLu->slu_pid_valid = 1; 12369585STim.Szeto@Sun.COM bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid)); 12379585STim.Szeto@Sun.COM } 12389585STim.Szeto@Sun.COM 12399585STim.Szeto@Sun.COM if (disk->revValid) { 12409585STim.Szeto@Sun.COM sbdLu->slu_rev_valid = 1; 12419585STim.Szeto@Sun.COM bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev)); 12429585STim.Szeto@Sun.COM } 12439585STim.Szeto@Sun.COM 12449585STim.Szeto@Sun.COM if (disk->companyIdValid) { 12459585STim.Szeto@Sun.COM sbdLu->slu_company_id_valid = 1; 12469585STim.Szeto@Sun.COM sbdLu->slu_company_id = disk->companyId; 12479585STim.Szeto@Sun.COM } 12489585STim.Szeto@Sun.COM 124910765SJohn.Forte@Sun.COM if (disk->hostIdValid) { 125010765SJohn.Forte@Sun.COM sbdLu->slu_host_id_valid = 1; 125110765SJohn.Forte@Sun.COM sbdLu->slu_host_id = disk->hostId; 125210765SJohn.Forte@Sun.COM } 125310765SJohn.Forte@Sun.COM 12549585STim.Szeto@Sun.COM if (disk->blkSizeValid) { 12559585STim.Szeto@Sun.COM sbdLu->slu_blksize_valid = 1; 12569585STim.Szeto@Sun.COM sbdLu->slu_blksize = disk->blkSize; 12579585STim.Szeto@Sun.COM } 12589585STim.Szeto@Sun.COM 12599585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 12609585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 12619585STim.Szeto@Sun.COM sbdLu->slu_write_protected = 1; 12629585STim.Szeto@Sun.COM } 12639585STim.Szeto@Sun.COM } 12649585STim.Szeto@Sun.COM 12659585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 12669585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable_valid = 1; 12679585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 12689585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable = 1; 12699585STim.Szeto@Sun.COM } 12709585STim.Szeto@Sun.COM } 12719585STim.Szeto@Sun.COM 12729585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 12739585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size; 12749585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 12759585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size; 12769585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 12779585STim.Szeto@Sun.COM 12789585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl); 12799585STim.Szeto@Sun.COM if (ioctlRet != 0) { 12809585STim.Szeto@Sun.COM savedErrno = errno; 12819585STim.Szeto@Sun.COM switch (savedErrno) { 12829585STim.Szeto@Sun.COM case EBUSY: 12839585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 12849585STim.Szeto@Sun.COM break; 12859585STim.Szeto@Sun.COM case EPERM: 12869585STim.Szeto@Sun.COM case EACCES: 12879585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 12889585STim.Szeto@Sun.COM break; 12899585STim.Szeto@Sun.COM default: 12909585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 12919585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 12929585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 12939585STim.Szeto@Sun.COM "createDiskLu:ioctl " 12949585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 12959585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 12969585STim.Szeto@Sun.COM } 12979585STim.Szeto@Sun.COM break; 12989585STim.Szeto@Sun.COM } 12999585STim.Szeto@Sun.COM } 13009585STim.Szeto@Sun.COM 13019585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 13029585STim.Szeto@Sun.COM goto done; 13039585STim.Szeto@Sun.COM } 13049585STim.Szeto@Sun.COM 13059585STim.Szeto@Sun.COM /* 13069585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 13079585STim.Szeto@Sun.COM * NULL 13089585STim.Szeto@Sun.COM */ 13099585STim.Szeto@Sun.COM if (createdGuid) { 13109585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, createdGuid->guid, 13119585STim.Szeto@Sun.COM sizeof (sbdLu->slu_guid)); 13129585STim.Szeto@Sun.COM } 13139585STim.Szeto@Sun.COM 13149585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid)); 13159585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 13169585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luMetaFileName); 13179585STim.Szeto@Sun.COM } else { 13189585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luDataFileName); 13199585STim.Szeto@Sun.COM } 13209585STim.Szeto@Sun.COM done: 13219585STim.Szeto@Sun.COM free(sbdLu); 13229585STim.Szeto@Sun.COM (void) close(fd); 13239585STim.Szeto@Sun.COM return (ret); 13249585STim.Szeto@Sun.COM } 13259585STim.Szeto@Sun.COM 13269585STim.Szeto@Sun.COM 13279585STim.Szeto@Sun.COM /* 13289585STim.Szeto@Sun.COM * stmfImportLu 13299585STim.Szeto@Sun.COM * 13309585STim.Szeto@Sun.COM * Purpose: Import a previously created logical unit 13319585STim.Szeto@Sun.COM * 13329585STim.Szeto@Sun.COM * dType - Type of logical unit 13339585STim.Szeto@Sun.COM * Can be: STMF_DISK 13349585STim.Szeto@Sun.COM * 13359585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the imported logical 13369585STim.Szeto@Sun.COM * unit 13379585STim.Szeto@Sun.COM * 13389585STim.Szeto@Sun.COM * fname - A file name where the metadata resides 13399585STim.Szeto@Sun.COM * 13409585STim.Szeto@Sun.COM */ 13419585STim.Szeto@Sun.COM int 13429585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid) 13439585STim.Szeto@Sun.COM { 13449585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 13459585STim.Szeto@Sun.COM 13469585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 13479585STim.Szeto@Sun.COM ret = importDiskLu(fname, luGuid); 13489585STim.Szeto@Sun.COM } else { 13499585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13509585STim.Szeto@Sun.COM } 13519585STim.Szeto@Sun.COM 13529585STim.Szeto@Sun.COM return (ret); 13539585STim.Szeto@Sun.COM } 13549585STim.Szeto@Sun.COM 13559585STim.Szeto@Sun.COM /* 13569585STim.Szeto@Sun.COM * importDiskLu 13579585STim.Szeto@Sun.COM * 13589585STim.Szeto@Sun.COM * filename - filename to import 13599585STim.Szeto@Sun.COM * createdGuid - if not NULL, on success contains the imported guid 13609585STim.Szeto@Sun.COM * 13619585STim.Szeto@Sun.COM */ 13629585STim.Szeto@Sun.COM static int 13639585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid) 13649585STim.Szeto@Sun.COM { 13659585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 13669585STim.Szeto@Sun.COM int fd = 0; 13679585STim.Szeto@Sun.COM int ioctlRet; 13689585STim.Szeto@Sun.COM int savedErrno; 13699585STim.Szeto@Sun.COM int metaFileNameLen; 13709585STim.Szeto@Sun.COM stmfGuid iGuid; 13719585STim.Szeto@Sun.COM int iluBufSize = 0; 13729585STim.Szeto@Sun.COM sbd_import_lu_t *sbdLu = NULL; 13739585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 13749585STim.Szeto@Sun.COM 13759585STim.Szeto@Sun.COM if (fname == NULL) { 13769585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13779585STim.Szeto@Sun.COM } 13789585STim.Szeto@Sun.COM 13799585STim.Szeto@Sun.COM /* 13809585STim.Szeto@Sun.COM * Open control node for sbd 13819585STim.Szeto@Sun.COM */ 13829585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 13839585STim.Szeto@Sun.COM return (ret); 13849585STim.Szeto@Sun.COM 13859585STim.Szeto@Sun.COM metaFileNameLen = strlen(fname); 13869585STim.Szeto@Sun.COM iluBufSize += metaFileNameLen + 1; 13879585STim.Szeto@Sun.COM 13889585STim.Szeto@Sun.COM /* 13899585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 13909585STim.Szeto@Sun.COM * concatenation of variable length fields 13919585STim.Szeto@Sun.COM */ 13929585STim.Szeto@Sun.COM sbdLu = (sbd_import_lu_t *)calloc(1, 13939585STim.Szeto@Sun.COM sizeof (sbd_import_lu_t) + iluBufSize - 8); 13949585STim.Szeto@Sun.COM if (sbdLu == NULL) { 13959585STim.Szeto@Sun.COM (void) close(fd); 13969585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 13979585STim.Szeto@Sun.COM } 13989585STim.Szeto@Sun.COM 13999585STim.Szeto@Sun.COM /* 14009585STim.Szeto@Sun.COM * Accept either a data file or meta data file. 14019585STim.Szeto@Sun.COM * sbd will do the right thing here either way. 14029585STim.Szeto@Sun.COM * i.e. if it's a data file, it assumes that the 14039585STim.Szeto@Sun.COM * meta data is shared with the data. 14049585STim.Szeto@Sun.COM */ 14059585STim.Szeto@Sun.COM (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen); 14069585STim.Szeto@Sun.COM 14079585STim.Szeto@Sun.COM sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8; 14089585STim.Szeto@Sun.COM 14099585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 14109585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size; 14119585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 14129585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size; 14139585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 14149585STim.Szeto@Sun.COM 14159585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl); 14169585STim.Szeto@Sun.COM if (ioctlRet != 0) { 14179585STim.Szeto@Sun.COM savedErrno = errno; 14189585STim.Szeto@Sun.COM switch (savedErrno) { 14199585STim.Szeto@Sun.COM case EBUSY: 14209585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 14219585STim.Szeto@Sun.COM break; 14229585STim.Szeto@Sun.COM case EPERM: 14239585STim.Szeto@Sun.COM case EACCES: 14249585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 14259585STim.Szeto@Sun.COM break; 14269585STim.Szeto@Sun.COM default: 14279585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 14289585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 14299585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 14309585STim.Szeto@Sun.COM "importDiskLu:ioctl " 14319585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 14329585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 14339585STim.Szeto@Sun.COM } 14349585STim.Szeto@Sun.COM break; 14359585STim.Szeto@Sun.COM } 14369585STim.Szeto@Sun.COM } 14379585STim.Szeto@Sun.COM 14389585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 14399585STim.Szeto@Sun.COM goto done; 14409585STim.Szeto@Sun.COM } 14419585STim.Szeto@Sun.COM 14429585STim.Szeto@Sun.COM /* 14439585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 14449585STim.Szeto@Sun.COM * NULL and add it to the persistent store for sbd 14459585STim.Szeto@Sun.COM */ 14469585STim.Szeto@Sun.COM if (createdGuid) { 14479585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, createdGuid->guid, 14489585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 14499585STim.Szeto@Sun.COM ret = addGuidToDiskStore(createdGuid, fname); 14509585STim.Szeto@Sun.COM } else { 14519585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, iGuid.guid, 14529585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 14539585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&iGuid, fname); 14549585STim.Szeto@Sun.COM } 14559585STim.Szeto@Sun.COM done: 14569585STim.Szeto@Sun.COM free(sbdLu); 14579585STim.Szeto@Sun.COM (void) close(fd); 14589585STim.Szeto@Sun.COM return (ret); 14599585STim.Szeto@Sun.COM } 14609585STim.Szeto@Sun.COM 14619585STim.Szeto@Sun.COM /* 14629585STim.Szeto@Sun.COM * diskError 14639585STim.Szeto@Sun.COM * 14649585STim.Szeto@Sun.COM * Purpose: Translate sbd driver error 14659585STim.Szeto@Sun.COM */ 14669585STim.Szeto@Sun.COM static void 14679585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret) 14689585STim.Szeto@Sun.COM { 14699585STim.Szeto@Sun.COM switch (stmfError) { 14709585STim.Szeto@Sun.COM case SBD_RET_META_CREATION_FAILED: 14719585STim.Szeto@Sun.COM case SBD_RET_ZFS_META_CREATE_FAILED: 14729585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_CREATION; 14739585STim.Szeto@Sun.COM break; 14749585STim.Szeto@Sun.COM case SBD_RET_INVALID_BLKSIZE: 14759585STim.Szeto@Sun.COM *ret = STMF_ERROR_INVALID_BLKSIZE; 14769585STim.Szeto@Sun.COM break; 14779585STim.Szeto@Sun.COM case SBD_RET_FILE_ALREADY_REGISTERED: 14789585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_IN_USE; 14799585STim.Szeto@Sun.COM break; 14809585STim.Szeto@Sun.COM case SBD_RET_GUID_ALREADY_REGISTERED: 14819585STim.Szeto@Sun.COM *ret = STMF_ERROR_GUID_IN_USE; 14829585STim.Szeto@Sun.COM break; 14839585STim.Szeto@Sun.COM case SBD_RET_META_PATH_NOT_ABSOLUTE: 14849585STim.Szeto@Sun.COM case SBD_RET_META_FILE_LOOKUP_FAILED: 14859585STim.Szeto@Sun.COM case SBD_RET_META_FILE_OPEN_FAILED: 14869585STim.Szeto@Sun.COM case SBD_RET_META_FILE_GETATTR_FAILED: 14879585STim.Szeto@Sun.COM case SBD_RET_NO_META: 14889585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_FILE_NAME; 14899585STim.Szeto@Sun.COM break; 14909585STim.Szeto@Sun.COM case SBD_RET_DATA_PATH_NOT_ABSOLUTE: 14919585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_LOOKUP_FAILED: 14929585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_OPEN_FAILED: 14939585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_GETATTR_FAILED: 14949585STim.Szeto@Sun.COM *ret = STMF_ERROR_DATA_FILE_NAME; 14959585STim.Szeto@Sun.COM break; 14969585STim.Szeto@Sun.COM case SBD_RET_FILE_SIZE_ERROR: 14979585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_SIZE_INVALID; 14989585STim.Szeto@Sun.COM break; 14999585STim.Szeto@Sun.COM case SBD_RET_SIZE_OUT_OF_RANGE: 15009585STim.Szeto@Sun.COM *ret = STMF_ERROR_SIZE_OUT_OF_RANGE; 15019585STim.Szeto@Sun.COM break; 15029585STim.Szeto@Sun.COM case SBD_RET_LU_BUSY: 15039585STim.Szeto@Sun.COM *ret = STMF_ERROR_LU_BUSY; 15049585STim.Szeto@Sun.COM break; 15059585STim.Szeto@Sun.COM case SBD_RET_WRITE_CACHE_SET_FAILED: 15069585STim.Szeto@Sun.COM *ret = STMF_ERROR_WRITE_CACHE_SET; 15079585STim.Szeto@Sun.COM break; 150810725SJohn.Forte@Sun.COM case SBD_RET_ACCESS_STATE_FAILED: 150910725SJohn.Forte@Sun.COM *ret = STMF_ERROR_ACCESS_STATE_SET; 151010725SJohn.Forte@Sun.COM break; 15119585STim.Szeto@Sun.COM default: 15129585STim.Szeto@Sun.COM *ret = STMF_STATUS_ERROR; 15139585STim.Szeto@Sun.COM break; 15149585STim.Szeto@Sun.COM } 15159585STim.Szeto@Sun.COM } 15169585STim.Szeto@Sun.COM 15179585STim.Szeto@Sun.COM /* 15189585STim.Szeto@Sun.COM * Creates a logical unit resource of type STMF_DISK. 15199585STim.Szeto@Sun.COM * 15209585STim.Szeto@Sun.COM * No defaults should be set here as all defaults are derived from the 15219585STim.Szeto@Sun.COM * driver's default settings. 15229585STim.Szeto@Sun.COM */ 15239585STim.Szeto@Sun.COM static int 15249585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl) 15259585STim.Szeto@Sun.COM { 15269585STim.Szeto@Sun.COM hdl->type = STMF_DISK; 15279585STim.Szeto@Sun.COM 15289585STim.Szeto@Sun.COM hdl->resource = calloc(1, sizeof (diskResource)); 15299585STim.Szeto@Sun.COM if (hdl->resource == NULL) { 15309585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 15319585STim.Szeto@Sun.COM } 15329585STim.Szeto@Sun.COM 15339585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 15349585STim.Szeto@Sun.COM } 15359585STim.Szeto@Sun.COM 15369585STim.Szeto@Sun.COM /* 15379585STim.Szeto@Sun.COM * stmfDeleteLu 15389585STim.Szeto@Sun.COM * 15399585STim.Szeto@Sun.COM * Purpose: Delete a logical unit 15409585STim.Szeto@Sun.COM * 15419585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 15429585STim.Szeto@Sun.COM * 15439585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 15449585STim.Szeto@Sun.COM * unit 15459585STim.Szeto@Sun.COM */ 15469585STim.Szeto@Sun.COM int 15479585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid) 15489585STim.Szeto@Sun.COM { 15499585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15509585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 15519585STim.Szeto@Sun.COM 15529585STim.Szeto@Sun.COM if (luGuid == NULL) { 15539585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15549585STim.Szeto@Sun.COM } 15559585STim.Szeto@Sun.COM 15569585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 15579585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 15589585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 15599585STim.Szeto@Sun.COM return (ret); 15609585STim.Szeto@Sun.COM } else { 15619585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 15629585STim.Szeto@Sun.COM ret = deleteDiskLu(luGuid); 15639585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 15649585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 15659585STim.Szeto@Sun.COM } else { 15669585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15679585STim.Szeto@Sun.COM } 15689585STim.Szeto@Sun.COM } 15699585STim.Szeto@Sun.COM 15709585STim.Szeto@Sun.COM return (ret); 15719585STim.Szeto@Sun.COM } 15729585STim.Szeto@Sun.COM 15739585STim.Szeto@Sun.COM static int 15749585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid) 15759585STim.Szeto@Sun.COM { 15769585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15779585STim.Szeto@Sun.COM int fd; 15789585STim.Szeto@Sun.COM int savedErrno; 15799585STim.Szeto@Sun.COM int ioctlRet; 15809585STim.Szeto@Sun.COM sbd_delete_lu_t deleteLu = {0}; 15819585STim.Szeto@Sun.COM 15829585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 15839585STim.Szeto@Sun.COM 15849585STim.Szeto@Sun.COM /* 15859585STim.Szeto@Sun.COM * Open control node for sbd 15869585STim.Szeto@Sun.COM */ 15879585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 15889585STim.Szeto@Sun.COM return (ret); 15899585STim.Szeto@Sun.COM 15909585STim.Szeto@Sun.COM ret = removeGuidFromDiskStore(luGuid); 15919585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 15929585STim.Szeto@Sun.COM goto done; 15939585STim.Szeto@Sun.COM } 15949585STim.Szeto@Sun.COM 15959585STim.Szeto@Sun.COM bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid)); 15969585STim.Szeto@Sun.COM deleteLu.dlu_by_guid = 1; 15979585STim.Szeto@Sun.COM 15989585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 15999585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (deleteLu); 16009585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu; 16019585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl); 16029585STim.Szeto@Sun.COM if (ioctlRet != 0) { 16039585STim.Szeto@Sun.COM savedErrno = errno; 16049585STim.Szeto@Sun.COM switch (savedErrno) { 16059585STim.Szeto@Sun.COM case EBUSY: 16069585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 16079585STim.Szeto@Sun.COM break; 16089585STim.Szeto@Sun.COM case EPERM: 16099585STim.Szeto@Sun.COM case EACCES: 16109585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 16119585STim.Szeto@Sun.COM break; 16129585STim.Szeto@Sun.COM case ENOENT: 16139585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 16149585STim.Szeto@Sun.COM break; 16159585STim.Szeto@Sun.COM default: 16169585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 16179585STim.Szeto@Sun.COM "deleteDiskLu:ioctl error(%d) (%d) (%d)", 16189585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 16199585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 16209585STim.Szeto@Sun.COM break; 16219585STim.Szeto@Sun.COM } 16229585STim.Szeto@Sun.COM } 16239585STim.Szeto@Sun.COM 16249585STim.Szeto@Sun.COM done: 16259585STim.Szeto@Sun.COM (void) close(fd); 16269585STim.Szeto@Sun.COM return (ret); 16279585STim.Szeto@Sun.COM } 16289585STim.Szeto@Sun.COM 16299585STim.Szeto@Sun.COM /* 163010725SJohn.Forte@Sun.COM * stmfLuStandby 163110725SJohn.Forte@Sun.COM * 163210725SJohn.Forte@Sun.COM * Purpose: Sets access state to standby 163310725SJohn.Forte@Sun.COM * 163410725SJohn.Forte@Sun.COM * luGuid - guid of registered logical unit 163510725SJohn.Forte@Sun.COM * 163610725SJohn.Forte@Sun.COM */ 163710725SJohn.Forte@Sun.COM int 163810725SJohn.Forte@Sun.COM stmfLuStandby(stmfGuid *luGuid) 163910725SJohn.Forte@Sun.COM { 164010725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 164110725SJohn.Forte@Sun.COM stmfLogicalUnitProperties luProps; 164210725SJohn.Forte@Sun.COM 164310725SJohn.Forte@Sun.COM if (luGuid == NULL) { 164410725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 164510725SJohn.Forte@Sun.COM } 164610725SJohn.Forte@Sun.COM 164710725SJohn.Forte@Sun.COM /* Check logical unit provider name to call correct dtype function */ 164810725SJohn.Forte@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 164910725SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 165010725SJohn.Forte@Sun.COM return (ret); 165110725SJohn.Forte@Sun.COM } else { 165210725SJohn.Forte@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 165310725SJohn.Forte@Sun.COM ret = setDiskStandby(luGuid); 165410725SJohn.Forte@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 165510725SJohn.Forte@Sun.COM return (STMF_ERROR_NOT_FOUND); 165610725SJohn.Forte@Sun.COM } else { 165710725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 165810725SJohn.Forte@Sun.COM } 165910725SJohn.Forte@Sun.COM } 166010725SJohn.Forte@Sun.COM 166110725SJohn.Forte@Sun.COM return (ret); 166210725SJohn.Forte@Sun.COM } 166310725SJohn.Forte@Sun.COM 166410725SJohn.Forte@Sun.COM static int 166510725SJohn.Forte@Sun.COM setDiskStandby(stmfGuid *luGuid) 166610725SJohn.Forte@Sun.COM { 166710725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 166810725SJohn.Forte@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 166910725SJohn.Forte@Sun.COM sbd_set_lu_standby_t sbdLu = {0}; 167010725SJohn.Forte@Sun.COM int ioctlRet; 167110725SJohn.Forte@Sun.COM int savedErrno; 167210725SJohn.Forte@Sun.COM int fd = 0; 167310725SJohn.Forte@Sun.COM 167410725SJohn.Forte@Sun.COM /* 167510725SJohn.Forte@Sun.COM * Open control node for sbd 167610725SJohn.Forte@Sun.COM */ 167710725SJohn.Forte@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 167810725SJohn.Forte@Sun.COM return (ret); 167910725SJohn.Forte@Sun.COM 168010725SJohn.Forte@Sun.COM bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid)); 168110725SJohn.Forte@Sun.COM 168210725SJohn.Forte@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 168310725SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t); 168410725SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu; 168510725SJohn.Forte@Sun.COM 168610725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl); 168710725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 168810725SJohn.Forte@Sun.COM savedErrno = errno; 168910725SJohn.Forte@Sun.COM switch (savedErrno) { 169010725SJohn.Forte@Sun.COM case EBUSY: 169110725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 169210725SJohn.Forte@Sun.COM break; 169310725SJohn.Forte@Sun.COM case EPERM: 169410725SJohn.Forte@Sun.COM case EACCES: 169510725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 169610725SJohn.Forte@Sun.COM break; 169710725SJohn.Forte@Sun.COM default: 169810725SJohn.Forte@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 169910725SJohn.Forte@Sun.COM if (ret == STMF_STATUS_ERROR) { 170010725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 170110725SJohn.Forte@Sun.COM "setDiskStandby:ioctl " 170210725SJohn.Forte@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 170310725SJohn.Forte@Sun.COM sbdIoctl.stmf_error, savedErrno); 170410725SJohn.Forte@Sun.COM } 170510725SJohn.Forte@Sun.COM break; 170610725SJohn.Forte@Sun.COM } 170710725SJohn.Forte@Sun.COM } 170810725SJohn.Forte@Sun.COM return (ret); 170910725SJohn.Forte@Sun.COM } 171010725SJohn.Forte@Sun.COM 171110725SJohn.Forte@Sun.COM /* 17129585STim.Szeto@Sun.COM * stmfModifyLu 17139585STim.Szeto@Sun.COM * 17149585STim.Szeto@Sun.COM * Purpose: Modify properties of a logical unit 17159585STim.Szeto@Sun.COM * 17169585STim.Szeto@Sun.COM * luGuid - guid of registered logical unit 17179585STim.Szeto@Sun.COM * prop - property to modify 17189585STim.Szeto@Sun.COM * propVal - property value to set 17199585STim.Szeto@Sun.COM * 17209585STim.Szeto@Sun.COM */ 17219585STim.Szeto@Sun.COM int 17229585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal) 17239585STim.Szeto@Sun.COM { 17249585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 17259585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 17269585STim.Szeto@Sun.COM 17279585STim.Szeto@Sun.COM if (luGuid == NULL) { 17289585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17299585STim.Szeto@Sun.COM } 17309585STim.Szeto@Sun.COM 17319585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 17329585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 17339585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 17349585STim.Szeto@Sun.COM return (ret); 17359585STim.Szeto@Sun.COM } else { 17369585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 17379585STim.Szeto@Sun.COM ret = modifyDiskLuProp(luGuid, NULL, prop, propVal); 17389585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 17399585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 17409585STim.Szeto@Sun.COM } else { 17419585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17429585STim.Szeto@Sun.COM } 17439585STim.Szeto@Sun.COM } 17449585STim.Szeto@Sun.COM 17459585STim.Szeto@Sun.COM return (ret); 17469585STim.Szeto@Sun.COM } 17479585STim.Szeto@Sun.COM 17489585STim.Szeto@Sun.COM /* 17499585STim.Szeto@Sun.COM * stmfModifyLuByFname 17509585STim.Szeto@Sun.COM * 17519585STim.Szeto@Sun.COM * Purpose: Modify a device by filename. Device does not need to be registered. 17529585STim.Szeto@Sun.COM * 17539585STim.Szeto@Sun.COM * dType - type of device to modify 17549585STim.Szeto@Sun.COM * STMF_DISK 17559585STim.Szeto@Sun.COM * 17569585STim.Szeto@Sun.COM * fname - filename or meta filename 17579585STim.Szeto@Sun.COM * prop - valid property identifier 17589585STim.Szeto@Sun.COM * propVal - property value 17599585STim.Szeto@Sun.COM * 17609585STim.Szeto@Sun.COM */ 17619585STim.Szeto@Sun.COM int 17629585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop, 17639585STim.Szeto@Sun.COM const char *propVal) 17649585STim.Szeto@Sun.COM { 17659585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 17669585STim.Szeto@Sun.COM if (fname == NULL) { 17679585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17689585STim.Szeto@Sun.COM } 17699585STim.Szeto@Sun.COM 17709585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 17719585STim.Szeto@Sun.COM ret = modifyDiskLuProp(NULL, fname, prop, propVal); 17729585STim.Szeto@Sun.COM } else { 17739585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17749585STim.Szeto@Sun.COM } 17759585STim.Szeto@Sun.COM 17769585STim.Szeto@Sun.COM return (ret); 17779585STim.Szeto@Sun.COM } 17789585STim.Szeto@Sun.COM 17799585STim.Szeto@Sun.COM static int 17809585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop, 17819585STim.Szeto@Sun.COM const char *propVal) 17829585STim.Szeto@Sun.COM { 17839585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 17849585STim.Szeto@Sun.COM luResource hdl = NULL; 17859585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl; 17869585STim.Szeto@Sun.COM 17879585STim.Szeto@Sun.COM ret = stmfCreateLuResource(STMF_DISK, &hdl); 17889585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17899585STim.Szeto@Sun.COM return (ret); 17909585STim.Szeto@Sun.COM } 17919585STim.Szeto@Sun.COM ret = validateModifyDiskProp(prop); 17929585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17939585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 17949585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROP); 17959585STim.Szeto@Sun.COM } 17969585STim.Szeto@Sun.COM ret = stmfSetLuProp(hdl, prop, propVal); 17979585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17989585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 17999585STim.Szeto@Sun.COM return (ret); 18009585STim.Szeto@Sun.COM } 18019585STim.Szeto@Sun.COM luPropsHdl = hdl; 18029585STim.Szeto@Sun.COM ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname); 18039585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 18049585STim.Szeto@Sun.COM return (ret); 18059585STim.Szeto@Sun.COM } 18069585STim.Szeto@Sun.COM 18079585STim.Szeto@Sun.COM static int 18089585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop) 18099585STim.Szeto@Sun.COM { 18109585STim.Szeto@Sun.COM switch (prop) { 18119585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 18129585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 181310113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 18149585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 18159585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 18169585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 18179585STim.Szeto@Sun.COM break; 18189585STim.Szeto@Sun.COM default: 18199585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 18209585STim.Szeto@Sun.COM break; 18219585STim.Szeto@Sun.COM } 18229585STim.Szeto@Sun.COM } 18239585STim.Szeto@Sun.COM 18249585STim.Szeto@Sun.COM static int 18259585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname) 18269585STim.Szeto@Sun.COM { 18279585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 18289585STim.Szeto@Sun.COM int luAliasLen = 0; 182910113SNattuvetty.Bhavyan@Sun.COM int luMgmtUrlLen = 0; 18309585STim.Szeto@Sun.COM int mluBufSize = 0; 18319585STim.Szeto@Sun.COM int bufOffset = 0; 18329585STim.Szeto@Sun.COM int fd = 0; 18339585STim.Szeto@Sun.COM int ioctlRet; 18349585STim.Szeto@Sun.COM int savedErrno; 18359585STim.Szeto@Sun.COM int fnameSize = 0; 18369585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 18379585STim.Szeto@Sun.COM 18389585STim.Szeto@Sun.COM sbd_modify_lu_t *sbdLu = NULL; 18399585STim.Szeto@Sun.COM 18409585STim.Szeto@Sun.COM if (luGuid == NULL && fname == NULL) { 18419585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 18429585STim.Szeto@Sun.COM } 18439585STim.Szeto@Sun.COM 18449585STim.Szeto@Sun.COM if (fname) { 18459585STim.Szeto@Sun.COM fnameSize = strlen(fname) + 1; 18469585STim.Szeto@Sun.COM mluBufSize += fnameSize; 18479585STim.Szeto@Sun.COM } 18489585STim.Szeto@Sun.COM 18499585STim.Szeto@Sun.COM /* 18509585STim.Szeto@Sun.COM * Open control node for sbd 18519585STim.Szeto@Sun.COM */ 18529585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 18539585STim.Szeto@Sun.COM return (ret); 18549585STim.Szeto@Sun.COM 18559585STim.Szeto@Sun.COM if (disk->luAliasValid) { 18569585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 18579585STim.Szeto@Sun.COM mluBufSize += luAliasLen + 1; 18589585STim.Szeto@Sun.COM } 18599585STim.Szeto@Sun.COM 186010113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 186110113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen = strlen(disk->luMgmtUrl); 186210113SNattuvetty.Bhavyan@Sun.COM mluBufSize += luMgmtUrlLen + 1; 186310113SNattuvetty.Bhavyan@Sun.COM } 186410113SNattuvetty.Bhavyan@Sun.COM 18659585STim.Szeto@Sun.COM /* 18669585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 18679585STim.Szeto@Sun.COM * concatenation of variable length fields 18689585STim.Szeto@Sun.COM */ 18699585STim.Szeto@Sun.COM sbdLu = (sbd_modify_lu_t *)calloc(1, 18709585STim.Szeto@Sun.COM sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize); 18719585STim.Szeto@Sun.COM if (sbdLu == NULL) { 18729585STim.Szeto@Sun.COM (void) close(fd); 18739585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 18749585STim.Szeto@Sun.COM } 18759585STim.Szeto@Sun.COM 18769585STim.Szeto@Sun.COM sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) + 18779585STim.Szeto@Sun.COM mluBufSize - 8 + fnameSize; 18789585STim.Szeto@Sun.COM 18799585STim.Szeto@Sun.COM if (disk->luAliasValid) { 18809585STim.Szeto@Sun.COM sbdLu->mlu_alias_valid = 1; 18819585STim.Szeto@Sun.COM sbdLu->mlu_alias_off = bufOffset; 18829585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]), 18839585STim.Szeto@Sun.COM luAliasLen + 1); 18849585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 18859585STim.Szeto@Sun.COM } 18869585STim.Szeto@Sun.COM 188710113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 188810113SNattuvetty.Bhavyan@Sun.COM sbdLu->mlu_mgmt_url_valid = 1; 188910113SNattuvetty.Bhavyan@Sun.COM sbdLu->mlu_mgmt_url_off = bufOffset; 189010113SNattuvetty.Bhavyan@Sun.COM bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]), 189110113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen + 1); 189210113SNattuvetty.Bhavyan@Sun.COM bufOffset += luMgmtUrlLen + 1; 189310113SNattuvetty.Bhavyan@Sun.COM } 189410113SNattuvetty.Bhavyan@Sun.COM 18959585STim.Szeto@Sun.COM if (disk->luSizeValid) { 18969585STim.Szeto@Sun.COM sbdLu->mlu_lu_size_valid = 1; 18979585STim.Szeto@Sun.COM sbdLu->mlu_lu_size = disk->luSize; 18989585STim.Szeto@Sun.COM } 18999585STim.Szeto@Sun.COM 19009585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 19019585STim.Szeto@Sun.COM sbdLu->mlu_write_protected_valid = 1; 19029585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 19039585STim.Szeto@Sun.COM sbdLu->mlu_write_protected = 1; 19049585STim.Szeto@Sun.COM } 19059585STim.Szeto@Sun.COM } 19069585STim.Szeto@Sun.COM 19079585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 19089585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable_valid = 1; 19099585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 19109585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable = 1; 19119585STim.Szeto@Sun.COM } 19129585STim.Szeto@Sun.COM } 19139585STim.Szeto@Sun.COM 19149585STim.Szeto@Sun.COM if (luGuid) { 19159585STim.Szeto@Sun.COM bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid)); 19169585STim.Szeto@Sun.COM sbdLu->mlu_by_guid = 1; 19179585STim.Szeto@Sun.COM } else { 19189585STim.Szeto@Sun.COM sbdLu->mlu_fname_off = bufOffset; 19199585STim.Szeto@Sun.COM bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1); 19209585STim.Szeto@Sun.COM sbdLu->mlu_by_fname = 1; 19219585STim.Szeto@Sun.COM } 19229585STim.Szeto@Sun.COM 19239585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 19249585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size; 19259585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 19269585STim.Szeto@Sun.COM 19279585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl); 19289585STim.Szeto@Sun.COM if (ioctlRet != 0) { 19299585STim.Szeto@Sun.COM savedErrno = errno; 19309585STim.Szeto@Sun.COM switch (savedErrno) { 19319585STim.Szeto@Sun.COM case EBUSY: 19329585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 19339585STim.Szeto@Sun.COM break; 19349585STim.Szeto@Sun.COM case EPERM: 19359585STim.Szeto@Sun.COM case EACCES: 19369585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 19379585STim.Szeto@Sun.COM break; 19389585STim.Szeto@Sun.COM default: 19399585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 19409585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 19419585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 19429585STim.Szeto@Sun.COM "modifyDiskLu:ioctl " 19439585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 19449585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 19459585STim.Szeto@Sun.COM } 19469585STim.Szeto@Sun.COM break; 19479585STim.Szeto@Sun.COM } 19489585STim.Szeto@Sun.COM } 19499585STim.Szeto@Sun.COM 19509585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 19519585STim.Szeto@Sun.COM goto done; 19529585STim.Szeto@Sun.COM } 19539585STim.Szeto@Sun.COM 19549585STim.Szeto@Sun.COM done: 19559585STim.Szeto@Sun.COM free(sbdLu); 19569585STim.Szeto@Sun.COM (void) close(fd); 19579585STim.Szeto@Sun.COM return (ret); 19589585STim.Szeto@Sun.COM } 19599585STim.Szeto@Sun.COM 19609585STim.Szeto@Sun.COM /* 19619585STim.Szeto@Sun.COM * removeGuidFromDiskStore 19629585STim.Szeto@Sun.COM * 19639585STim.Szeto@Sun.COM * Purpose: delete a logical unit from the sbd provider data 19649585STim.Szeto@Sun.COM */ 19659585STim.Szeto@Sun.COM static int 19669585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid) 19679585STim.Szeto@Sun.COM { 19689585STim.Szeto@Sun.COM return (persistDiskGuid(guid, NULL, B_FALSE)); 19699585STim.Szeto@Sun.COM } 19709585STim.Szeto@Sun.COM 19719585STim.Szeto@Sun.COM 19729585STim.Szeto@Sun.COM /* 19739585STim.Szeto@Sun.COM * addGuidToDiskStore 19749585STim.Szeto@Sun.COM * 19759585STim.Szeto@Sun.COM * Purpose: add a logical unit to the sbd provider data 19769585STim.Szeto@Sun.COM */ 19779585STim.Szeto@Sun.COM static int 19789585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename) 19799585STim.Szeto@Sun.COM { 19809585STim.Szeto@Sun.COM return (persistDiskGuid(guid, filename, B_TRUE)); 19819585STim.Szeto@Sun.COM } 19829585STim.Szeto@Sun.COM 19839585STim.Szeto@Sun.COM 19849585STim.Szeto@Sun.COM /* 19859585STim.Szeto@Sun.COM * persistDiskGuid 19869585STim.Szeto@Sun.COM * 19879585STim.Szeto@Sun.COM * Purpose: Persist or unpersist a guid for the sbd provider data 19889585STim.Szeto@Sun.COM * 19899585STim.Szeto@Sun.COM */ 19909585STim.Szeto@Sun.COM static int 19919585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist) 19929585STim.Szeto@Sun.COM { 19939585STim.Szeto@Sun.COM char guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0}; 19949585STim.Szeto@Sun.COM nvlist_t *nvl = NULL; 19959585STim.Szeto@Sun.COM 19969585STim.Szeto@Sun.COM uint64_t setToken; 19979585STim.Szeto@Sun.COM boolean_t retryGetProviderData = B_FALSE; 19989585STim.Szeto@Sun.COM boolean_t newData = B_FALSE; 19999585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 20009585STim.Szeto@Sun.COM int retryCnt = 0; 20019585STim.Szeto@Sun.COM int stmfRet; 20029585STim.Szeto@Sun.COM 20039585STim.Szeto@Sun.COM /* if we're persisting a guid, there must be a filename */ 20049585STim.Szeto@Sun.COM if (persist && !filename) { 20059585STim.Szeto@Sun.COM return (1); 20069585STim.Szeto@Sun.COM } 20079585STim.Szeto@Sun.COM 20089585STim.Szeto@Sun.COM /* guid is stored in lowercase ascii hex */ 20099585STim.Szeto@Sun.COM (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 20109585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" 20119585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x", 20129585STim.Szeto@Sun.COM guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3], 20139585STim.Szeto@Sun.COM guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7], 20149585STim.Szeto@Sun.COM guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11], 20159585STim.Szeto@Sun.COM guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]); 20169585STim.Szeto@Sun.COM 20179585STim.Szeto@Sun.COM 20189585STim.Szeto@Sun.COM do { 20199585STim.Szeto@Sun.COM retryGetProviderData = B_FALSE; 20209585STim.Szeto@Sun.COM stmfRet = stmfGetProviderDataProt("sbd", &nvl, 20219585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 20229585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 20239585STim.Szeto@Sun.COM if (persist && stmfRet == STMF_ERROR_NOT_FOUND) { 20249585STim.Szeto@Sun.COM ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); 20259585STim.Szeto@Sun.COM if (ret != 0) { 20269585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20279585STim.Szeto@Sun.COM "unpersistGuid:nvlist_alloc(%d)", 20289585STim.Szeto@Sun.COM ret); 20299585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 20309585STim.Szeto@Sun.COM goto done; 20319585STim.Szeto@Sun.COM } 20329585STim.Szeto@Sun.COM newData = B_TRUE; 20339585STim.Szeto@Sun.COM } else { 203410725SJohn.Forte@Sun.COM /* 203510725SJohn.Forte@Sun.COM * if we're persisting the data, it's 203610725SJohn.Forte@Sun.COM * an error. Otherwise, just return 203710725SJohn.Forte@Sun.COM */ 203810725SJohn.Forte@Sun.COM if (persist) { 203910725SJohn.Forte@Sun.COM ret = stmfRet; 204010725SJohn.Forte@Sun.COM } 20419585STim.Szeto@Sun.COM goto done; 20429585STim.Szeto@Sun.COM } 20439585STim.Szeto@Sun.COM } 20449585STim.Szeto@Sun.COM if (persist) { 20459585STim.Szeto@Sun.COM ret = nvlist_add_string(nvl, guidAsciiBuf, filename); 20469585STim.Szeto@Sun.COM } else { 20479585STim.Szeto@Sun.COM ret = nvlist_remove(nvl, guidAsciiBuf, 20489585STim.Szeto@Sun.COM DATA_TYPE_STRING); 20499585STim.Szeto@Sun.COM if (ret == ENOENT) { 20509585STim.Szeto@Sun.COM ret = 0; 20519585STim.Szeto@Sun.COM } 20529585STim.Szeto@Sun.COM } 20539585STim.Szeto@Sun.COM if (ret == 0) { 20549585STim.Szeto@Sun.COM if (newData) { 20559585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 20569585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, NULL); 20579585STim.Szeto@Sun.COM } else { 20589585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 20599585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 20609585STim.Szeto@Sun.COM } 20619585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 20629585STim.Szeto@Sun.COM if (stmfRet == STMF_ERROR_BUSY) { 20639585STim.Szeto@Sun.COM /* get/set failed, try again */ 20649585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 20659585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 20669585STim.Szeto@Sun.COM ret = stmfRet; 20679585STim.Szeto@Sun.COM break; 20689585STim.Szeto@Sun.COM } 20699585STim.Szeto@Sun.COM continue; 20709585STim.Szeto@Sun.COM } else if (stmfRet == 20719585STim.Szeto@Sun.COM STMF_ERROR_PROV_DATA_STALE) { 20729585STim.Szeto@Sun.COM /* update failed, try again */ 20739585STim.Szeto@Sun.COM nvlist_free(nvl); 20749585STim.Szeto@Sun.COM nvl = NULL; 20759585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 20769585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 20779585STim.Szeto@Sun.COM ret = stmfRet; 20789585STim.Szeto@Sun.COM break; 20799585STim.Szeto@Sun.COM } 20809585STim.Szeto@Sun.COM continue; 20819585STim.Szeto@Sun.COM } else { 20829585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20839585STim.Szeto@Sun.COM "unpersistGuid:error(%x)", stmfRet); 20849585STim.Szeto@Sun.COM ret = stmfRet; 20859585STim.Szeto@Sun.COM } 20869585STim.Szeto@Sun.COM break; 20879585STim.Szeto@Sun.COM } 20889585STim.Szeto@Sun.COM } else { 20899585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20909585STim.Szeto@Sun.COM "unpersistGuid:error nvlist_add/remove(%d)", 20919585STim.Szeto@Sun.COM ret); 20929585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 20939585STim.Szeto@Sun.COM } 20949585STim.Szeto@Sun.COM } while (retryGetProviderData); 20959585STim.Szeto@Sun.COM 20969585STim.Szeto@Sun.COM done: 20979585STim.Szeto@Sun.COM nvlist_free(nvl); 20989585STim.Szeto@Sun.COM return (ret); 20999585STim.Szeto@Sun.COM } 21009585STim.Szeto@Sun.COM 21019585STim.Szeto@Sun.COM 21029585STim.Szeto@Sun.COM /* 21039585STim.Szeto@Sun.COM * stmfGetLuProp 21049585STim.Szeto@Sun.COM * 21059585STim.Szeto@Sun.COM * Purpose: Get current value for a resource property 21069585STim.Szeto@Sun.COM * 21079585STim.Szeto@Sun.COM * hdl - luResource from a previous call to stmfCreateLuResource 21089585STim.Szeto@Sun.COM * 21099585STim.Szeto@Sun.COM * resourceProp - a valid resource property type 21109585STim.Szeto@Sun.COM * 21119585STim.Szeto@Sun.COM * propVal - void pointer to a pointer of the value to be retrieved 21129585STim.Szeto@Sun.COM */ 21139585STim.Szeto@Sun.COM int 21149585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen) 21159585STim.Szeto@Sun.COM { 21169585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21179585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 21189585STim.Szeto@Sun.COM if (hdl == NULL || propLen == NULL || propVal == NULL) { 21199585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21209585STim.Szeto@Sun.COM } 21219585STim.Szeto@Sun.COM 21229585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 21239585STim.Szeto@Sun.COM ret = getDiskProp(luPropsHdl, prop, propVal, propLen); 21249585STim.Szeto@Sun.COM } else { 21259585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21269585STim.Szeto@Sun.COM } 21279585STim.Szeto@Sun.COM 21289585STim.Szeto@Sun.COM return (ret); 21299585STim.Szeto@Sun.COM } 21309585STim.Szeto@Sun.COM 21319585STim.Szeto@Sun.COM /* 21329585STim.Szeto@Sun.COM * stmfGetLuResource 21339585STim.Szeto@Sun.COM * 21349585STim.Szeto@Sun.COM * Purpose: Get a logical unit resource handle for a given logical unit. 21359585STim.Szeto@Sun.COM * 21369585STim.Szeto@Sun.COM * hdl - pointer to luResource 21379585STim.Szeto@Sun.COM */ 21389585STim.Szeto@Sun.COM int 21399585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl) 21409585STim.Szeto@Sun.COM { 21419585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21429585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 21439585STim.Szeto@Sun.COM 214411691SSrivijitha.Dugganapalli@Sun.COM if (hdl == NULL) { 214511691SSrivijitha.Dugganapalli@Sun.COM return (STMF_ERROR_INVALID_ARG); 214611691SSrivijitha.Dugganapalli@Sun.COM } 21479585STim.Szeto@Sun.COM 21489585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 21499585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 21509585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 21519585STim.Szeto@Sun.COM return (ret); 21529585STim.Szeto@Sun.COM } else { 21539585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 21549585STim.Szeto@Sun.COM ret = getDiskAllProps(luGuid, hdl); 21559585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 21569585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 21579585STim.Szeto@Sun.COM } else { 21589585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21599585STim.Szeto@Sun.COM } 21609585STim.Szeto@Sun.COM } 21619585STim.Szeto@Sun.COM 21629585STim.Szeto@Sun.COM return (ret); 21639585STim.Szeto@Sun.COM } 21649585STim.Szeto@Sun.COM 21659585STim.Szeto@Sun.COM /* 21669585STim.Szeto@Sun.COM * getDiskAllProps 21679585STim.Szeto@Sun.COM * 21689585STim.Szeto@Sun.COM * Purpose: load all disk properties from sbd driver 21699585STim.Szeto@Sun.COM * 21709585STim.Szeto@Sun.COM * luGuid - guid of disk device for which properties are to be retrieved 21719585STim.Szeto@Sun.COM * hdl - allocated luResource into which properties are to be copied 21729585STim.Szeto@Sun.COM * 21739585STim.Szeto@Sun.COM */ 21749585STim.Szeto@Sun.COM static int 21759585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl) 21769585STim.Szeto@Sun.COM { 21779585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21789585STim.Szeto@Sun.COM int fd; 21799585STim.Szeto@Sun.COM sbd_lu_props_t *sbdProps; 21809585STim.Szeto@Sun.COM int ioctlRet; 21819585STim.Szeto@Sun.COM int savedErrno; 21829585STim.Szeto@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 21839585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 21849585STim.Szeto@Sun.COM 21859585STim.Szeto@Sun.COM /* 21869585STim.Szeto@Sun.COM * Open control node for sbd 21879585STim.Szeto@Sun.COM */ 21889585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 21899585STim.Szeto@Sun.COM return (ret); 21909585STim.Szeto@Sun.COM 21919585STim.Szeto@Sun.COM 21929585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 21939585STim.Szeto@Sun.COM if (*hdl == NULL) { 21949585STim.Szeto@Sun.COM (void) close(fd); 21959585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 21969585STim.Szeto@Sun.COM } 21979585STim.Szeto@Sun.COM 21989585STim.Szeto@Sun.COM sbdProps = calloc(1, sbdPropsSize); 21999585STim.Szeto@Sun.COM if (sbdProps == NULL) { 22009585STim.Szeto@Sun.COM free(*hdl); 22019585STim.Szeto@Sun.COM (void) close(fd); 22029585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 22039585STim.Szeto@Sun.COM } 22049585STim.Szeto@Sun.COM 22059585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 22069585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 22079585STim.Szeto@Sun.COM free(*hdl); 220810725SJohn.Forte@Sun.COM free(sbdProps); 22099585STim.Szeto@Sun.COM (void) close(fd); 22109585STim.Szeto@Sun.COM return (ret); 22119585STim.Szeto@Sun.COM } 22129585STim.Szeto@Sun.COM 22139585STim.Szeto@Sun.COM sbdProps->slp_input_guid = 1; 22149585STim.Szeto@Sun.COM bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid)); 22159585STim.Szeto@Sun.COM 22169585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 22179585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdPropsSize; 22189585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps; 22199585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 22209585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 22219585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl); 22229585STim.Szeto@Sun.COM if (ioctlRet != 0) { 22239585STim.Szeto@Sun.COM savedErrno = errno; 22249585STim.Szeto@Sun.COM switch (savedErrno) { 22259585STim.Szeto@Sun.COM case EBUSY: 22269585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 22279585STim.Szeto@Sun.COM break; 22289585STim.Szeto@Sun.COM case EPERM: 22299585STim.Szeto@Sun.COM case EACCES: 22309585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 22319585STim.Szeto@Sun.COM break; 22329585STim.Szeto@Sun.COM case ENOENT: 22339585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 22349585STim.Szeto@Sun.COM break; 22359585STim.Szeto@Sun.COM default: 22369585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 22379585STim.Szeto@Sun.COM "getDiskAllProps:ioctl error(%d) (%d) (%d)", 22389585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 22399585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 22409585STim.Szeto@Sun.COM break; 22419585STim.Szeto@Sun.COM } 22429585STim.Szeto@Sun.COM } 22439585STim.Szeto@Sun.COM 22449585STim.Szeto@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 22459585STim.Szeto@Sun.COM ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps); 22469585STim.Szeto@Sun.COM } 22479585STim.Szeto@Sun.COM 224810725SJohn.Forte@Sun.COM free(sbdProps); 22499585STim.Szeto@Sun.COM (void) close(fd); 22509585STim.Szeto@Sun.COM return (ret); 22519585STim.Szeto@Sun.COM } 22529585STim.Szeto@Sun.COM 22539585STim.Szeto@Sun.COM /* 22549585STim.Szeto@Sun.COM * loadDiskPropsFromDriver 22559585STim.Szeto@Sun.COM * 22569585STim.Szeto@Sun.COM * Purpose: Retrieve all disk type properties from sbd driver 22579585STim.Szeto@Sun.COM * 22589585STim.Szeto@Sun.COM * hdl - Allocated luResourceImpl 22599585STim.Szeto@Sun.COM * sbdProps - sbd_lu_props_t structure returned from sbd driver 22609585STim.Szeto@Sun.COM * 22619585STim.Szeto@Sun.COM */ 22629585STim.Szeto@Sun.COM static int 22639585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps) 22649585STim.Szeto@Sun.COM { 22659585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 22669585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 22679585STim.Szeto@Sun.COM /* copy guid */ 22689585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 22699585STim.Szeto@Sun.COM bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid)); 22709585STim.Szeto@Sun.COM 22719585STim.Szeto@Sun.COM if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) { 22729585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 22739585STim.Szeto@Sun.COM if (strlcpy(diskLu->luMetaFileName, 22749585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]), 22759585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) >= 22769585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 22779585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 22789585STim.Szeto@Sun.COM } 22799585STim.Szeto@Sun.COM } 22809585STim.Szeto@Sun.COM 22819585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 22829585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 22839585STim.Szeto@Sun.COM if (strlcpy(diskLu->luDataFileName, 22849585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]), 22859585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) >= 22869585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 22879585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 22889585STim.Szeto@Sun.COM } 22899585STim.Szeto@Sun.COM } 22909585STim.Szeto@Sun.COM 22919585STim.Szeto@Sun.COM if (sbdProps->slp_serial_valid) { 22929585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 22939585STim.Szeto@Sun.COM bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]), 22949585STim.Szeto@Sun.COM diskLu->serialNum, sbdProps->slp_serial_size); 22959585STim.Szeto@Sun.COM } 22969585STim.Szeto@Sun.COM 229710113SNattuvetty.Bhavyan@Sun.COM if (sbdProps->slp_mgmt_url_valid) { 229810113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 229910113SNattuvetty.Bhavyan@Sun.COM if (strlcpy(diskLu->luMgmtUrl, 230010113SNattuvetty.Bhavyan@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]), 230110113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) >= 230210113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 230310113SNattuvetty.Bhavyan@Sun.COM return (STMF_STATUS_ERROR); 230410113SNattuvetty.Bhavyan@Sun.COM } 230510113SNattuvetty.Bhavyan@Sun.COM } 230610113SNattuvetty.Bhavyan@Sun.COM 23079585STim.Szeto@Sun.COM if (sbdProps->slp_alias_valid) { 23089585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 23099585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 23109585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]), 23119585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 23129585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23139585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 23149585STim.Szeto@Sun.COM } 23159585STim.Szeto@Sun.COM } else { /* set alias to data filename if not set */ 23169585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 23179585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 23189585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 23199585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[ 23209585STim.Szeto@Sun.COM sbdProps->slp_data_fname_off]), 23219585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 23229585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23239585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 23249585STim.Szeto@Sun.COM } 23259585STim.Szeto@Sun.COM } 23269585STim.Szeto@Sun.COM } 23279585STim.Szeto@Sun.COM 23289585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 23299585STim.Szeto@Sun.COM bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid)); 23309585STim.Szeto@Sun.COM 23319585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 23329585STim.Szeto@Sun.COM bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid)); 23339585STim.Szeto@Sun.COM 23349585STim.Szeto@Sun.COM diskLu->revValid = B_TRUE; 23359585STim.Szeto@Sun.COM bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev)); 23369585STim.Szeto@Sun.COM 23379585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 23389585STim.Szeto@Sun.COM if (sbdProps->slp_write_protected) { 23399585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 23409585STim.Szeto@Sun.COM } 23419585STim.Szeto@Sun.COM 23429585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 23439585STim.Szeto@Sun.COM if (sbdProps->slp_writeback_cache_disable_cur) { 23449585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 23459585STim.Szeto@Sun.COM } 23469585STim.Szeto@Sun.COM 23479585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 23489585STim.Szeto@Sun.COM diskLu->blkSize = sbdProps->slp_blksize; 23499585STim.Szeto@Sun.COM 23509585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 23519585STim.Szeto@Sun.COM diskLu->luSize = sbdProps->slp_lu_size; 23529585STim.Szeto@Sun.COM 235310725SJohn.Forte@Sun.COM diskLu->accessState = sbdProps->slp_access_state; 235410725SJohn.Forte@Sun.COM 23559585STim.Szeto@Sun.COM return (ret); 23569585STim.Szeto@Sun.COM } 23579585STim.Szeto@Sun.COM 235811103SJohn.Forte@Sun.COM /* 235911103SJohn.Forte@Sun.COM * stmfGetGlobalLuProp 236011103SJohn.Forte@Sun.COM * 236111103SJohn.Forte@Sun.COM * Purpose: get a global property for a device type 236211103SJohn.Forte@Sun.COM * 236311103SJohn.Forte@Sun.COM */ 236411103SJohn.Forte@Sun.COM int 236511103SJohn.Forte@Sun.COM stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal, 236611103SJohn.Forte@Sun.COM size_t *propLen) 236711103SJohn.Forte@Sun.COM { 236811103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 236911103SJohn.Forte@Sun.COM if (dType != STMF_DISK || propVal == NULL) { 237011103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 237111103SJohn.Forte@Sun.COM } 237211103SJohn.Forte@Sun.COM 237311103SJohn.Forte@Sun.COM ret = getDiskGlobalProp(prop, propVal, propLen); 237411103SJohn.Forte@Sun.COM 237511103SJohn.Forte@Sun.COM return (ret); 237611103SJohn.Forte@Sun.COM } 237711103SJohn.Forte@Sun.COM 237811103SJohn.Forte@Sun.COM /* 237911103SJohn.Forte@Sun.COM * getDiskGlobalProp 238011103SJohn.Forte@Sun.COM * 238111103SJohn.Forte@Sun.COM * Purpose: get global property from sbd driver 238211103SJohn.Forte@Sun.COM * 238311103SJohn.Forte@Sun.COM */ 238411103SJohn.Forte@Sun.COM static int 238511103SJohn.Forte@Sun.COM getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen) 238611103SJohn.Forte@Sun.COM { 238711103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 238811103SJohn.Forte@Sun.COM int fd; 238911103SJohn.Forte@Sun.COM sbd_global_props_t *sbdProps; 239011103SJohn.Forte@Sun.COM void *sbd_realloc; 239111103SJohn.Forte@Sun.COM int retryCnt = 0; 239211103SJohn.Forte@Sun.COM boolean_t retry; 239311103SJohn.Forte@Sun.COM int ioctlRet; 239411103SJohn.Forte@Sun.COM int savedErrno; 239511103SJohn.Forte@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 239611103SJohn.Forte@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 239711103SJohn.Forte@Sun.COM size_t reqLen; 239811103SJohn.Forte@Sun.COM 239911103SJohn.Forte@Sun.COM switch (prop) { 240011103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 240111103SJohn.Forte@Sun.COM break; 240211103SJohn.Forte@Sun.COM default: 240311103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_PROP); 240411103SJohn.Forte@Sun.COM } 240511103SJohn.Forte@Sun.COM 240611103SJohn.Forte@Sun.COM /* 240711103SJohn.Forte@Sun.COM * Open control node for sbd 240811103SJohn.Forte@Sun.COM */ 240911103SJohn.Forte@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 241011103SJohn.Forte@Sun.COM return (ret); 241111103SJohn.Forte@Sun.COM 241211103SJohn.Forte@Sun.COM sbdProps = calloc(1, sbdPropsSize); 241311103SJohn.Forte@Sun.COM if (sbdProps == NULL) { 241411103SJohn.Forte@Sun.COM (void) close(fd); 241511103SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 241611103SJohn.Forte@Sun.COM } 241711103SJohn.Forte@Sun.COM 241811103SJohn.Forte@Sun.COM do { 241911103SJohn.Forte@Sun.COM retry = B_FALSE; 242011103SJohn.Forte@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 242111103SJohn.Forte@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 242211103SJohn.Forte@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 242311103SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl); 242411103SJohn.Forte@Sun.COM if (ioctlRet != 0) { 242511103SJohn.Forte@Sun.COM savedErrno = errno; 242611103SJohn.Forte@Sun.COM switch (savedErrno) { 242711103SJohn.Forte@Sun.COM case EBUSY: 242811103SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 242911103SJohn.Forte@Sun.COM break; 243011103SJohn.Forte@Sun.COM case EPERM: 243111103SJohn.Forte@Sun.COM case EACCES: 243211103SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 243311103SJohn.Forte@Sun.COM break; 243411103SJohn.Forte@Sun.COM case ENOMEM: 243511103SJohn.Forte@Sun.COM if (sbdIoctl.stmf_error == 243611103SJohn.Forte@Sun.COM SBD_RET_INSUFFICIENT_BUF_SPACE && 243711103SJohn.Forte@Sun.COM retryCnt++ < 3) { 243811103SJohn.Forte@Sun.COM sbdPropsSize = 243911103SJohn.Forte@Sun.COM sizeof (*sbdProps) + 244011103SJohn.Forte@Sun.COM sbdProps-> 244111103SJohn.Forte@Sun.COM mlu_buf_size_needed; 244211103SJohn.Forte@Sun.COM 244311103SJohn.Forte@Sun.COM sbd_realloc = sbdProps; 244411103SJohn.Forte@Sun.COM sbdProps = realloc(sbdProps, 244511103SJohn.Forte@Sun.COM sbdPropsSize); 244611103SJohn.Forte@Sun.COM if (sbdProps == NULL) { 244711103SJohn.Forte@Sun.COM free(sbd_realloc); 244811103SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 244911103SJohn.Forte@Sun.COM break; 245011103SJohn.Forte@Sun.COM } 245111103SJohn.Forte@Sun.COM retry = B_TRUE; 245211103SJohn.Forte@Sun.COM } else { 245311103SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 245411103SJohn.Forte@Sun.COM } 245511103SJohn.Forte@Sun.COM break; 245611103SJohn.Forte@Sun.COM default: 245711103SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 245811103SJohn.Forte@Sun.COM "getDiskGlobalProp:ioctl error(%d)" 245911103SJohn.Forte@Sun.COM "(%d)(%d)", ioctlRet, 246011103SJohn.Forte@Sun.COM sbdIoctl.stmf_error, savedErrno); 246111103SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 246211103SJohn.Forte@Sun.COM break; 246311103SJohn.Forte@Sun.COM } 246411103SJohn.Forte@Sun.COM 246511103SJohn.Forte@Sun.COM } 246611103SJohn.Forte@Sun.COM } while (retry); 246711103SJohn.Forte@Sun.COM 246811103SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 246911103SJohn.Forte@Sun.COM goto done; 247011103SJohn.Forte@Sun.COM } 247111103SJohn.Forte@Sun.COM 247211103SJohn.Forte@Sun.COM switch (prop) { 247311103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 247411103SJohn.Forte@Sun.COM if (sbdProps->mlu_mgmt_url_valid == 0) { 247511103SJohn.Forte@Sun.COM ret = STMF_ERROR_NO_PROP; 247611103SJohn.Forte@Sun.COM goto done; 247711103SJohn.Forte@Sun.COM } 247811103SJohn.Forte@Sun.COM if ((reqLen = strlcpy(propVal, (char *)&( 247911103SJohn.Forte@Sun.COM sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]), 248011103SJohn.Forte@Sun.COM *propLen)) >= *propLen) { 248111103SJohn.Forte@Sun.COM *propLen = reqLen + 1; 248211103SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 248311103SJohn.Forte@Sun.COM goto done; 248411103SJohn.Forte@Sun.COM } 248511103SJohn.Forte@Sun.COM break; 248611103SJohn.Forte@Sun.COM } 248711103SJohn.Forte@Sun.COM 248811103SJohn.Forte@Sun.COM done: 248911103SJohn.Forte@Sun.COM free(sbdProps); 249011103SJohn.Forte@Sun.COM (void) close(fd); 249111103SJohn.Forte@Sun.COM return (ret); 249211103SJohn.Forte@Sun.COM } 249311103SJohn.Forte@Sun.COM 249411103SJohn.Forte@Sun.COM /* 249511103SJohn.Forte@Sun.COM * stmfSetGlobalLuProp 249611103SJohn.Forte@Sun.COM * 249711103SJohn.Forte@Sun.COM * Purpose: set a global property for a device type 249811103SJohn.Forte@Sun.COM * 249911103SJohn.Forte@Sun.COM */ 250011103SJohn.Forte@Sun.COM int 250111103SJohn.Forte@Sun.COM stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal) 250211103SJohn.Forte@Sun.COM { 250311103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 250411103SJohn.Forte@Sun.COM if (dType != STMF_DISK || propVal == NULL) { 250511103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 250611103SJohn.Forte@Sun.COM } 250711103SJohn.Forte@Sun.COM 250811103SJohn.Forte@Sun.COM ret = setDiskGlobalProp(prop, propVal); 250911103SJohn.Forte@Sun.COM 251011103SJohn.Forte@Sun.COM return (ret); 251111103SJohn.Forte@Sun.COM } 251211103SJohn.Forte@Sun.COM 251311103SJohn.Forte@Sun.COM /* 251411103SJohn.Forte@Sun.COM * setDiskGlobalProp 251511103SJohn.Forte@Sun.COM * 251611103SJohn.Forte@Sun.COM * Purpose: set properties for resource of type disk 251711103SJohn.Forte@Sun.COM * 251811103SJohn.Forte@Sun.COM * resourceProp - valid resource identifier 251911103SJohn.Forte@Sun.COM * propVal - valid resource value 252011103SJohn.Forte@Sun.COM */ 252111103SJohn.Forte@Sun.COM static int 252211103SJohn.Forte@Sun.COM setDiskGlobalProp(uint32_t resourceProp, const char *propVal) 252311103SJohn.Forte@Sun.COM { 252411103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 252511103SJohn.Forte@Sun.COM sbd_global_props_t *sbdGlobalProps = NULL; 252611103SJohn.Forte@Sun.COM int sbdGlobalPropsSize = 0; 252711103SJohn.Forte@Sun.COM int propLen; 252811103SJohn.Forte@Sun.COM int mluBufSize = 0; 252911103SJohn.Forte@Sun.COM int fd; 253011103SJohn.Forte@Sun.COM int savedErrno; 253111103SJohn.Forte@Sun.COM int ioctlRet; 253211103SJohn.Forte@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 253311103SJohn.Forte@Sun.COM 253411103SJohn.Forte@Sun.COM switch (resourceProp) { 253511103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 253611103SJohn.Forte@Sun.COM break; 253711103SJohn.Forte@Sun.COM default: 253811103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_PROP); 253911103SJohn.Forte@Sun.COM break; 254011103SJohn.Forte@Sun.COM } 254111103SJohn.Forte@Sun.COM 254211103SJohn.Forte@Sun.COM /* 254311103SJohn.Forte@Sun.COM * Open control node for sbd 254411103SJohn.Forte@Sun.COM */ 254511103SJohn.Forte@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 254611103SJohn.Forte@Sun.COM return (ret); 254711103SJohn.Forte@Sun.COM 254811103SJohn.Forte@Sun.COM propLen = strlen(propVal); 254911103SJohn.Forte@Sun.COM mluBufSize += propLen + 1; 255011103SJohn.Forte@Sun.COM sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 + 255111103SJohn.Forte@Sun.COM max(8, mluBufSize); 255211103SJohn.Forte@Sun.COM /* 255311103SJohn.Forte@Sun.COM * 8 is the size of the buffer set aside for 255411103SJohn.Forte@Sun.COM * concatenation of variable length fields 255511103SJohn.Forte@Sun.COM */ 255611103SJohn.Forte@Sun.COM sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize); 255711103SJohn.Forte@Sun.COM if (sbdGlobalProps == NULL) { 255811103SJohn.Forte@Sun.COM (void) close(fd); 255911103SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 256011103SJohn.Forte@Sun.COM } 256111103SJohn.Forte@Sun.COM 256211103SJohn.Forte@Sun.COM sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize; 256311103SJohn.Forte@Sun.COM 256411103SJohn.Forte@Sun.COM switch (resourceProp) { 256511103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 256611103SJohn.Forte@Sun.COM sbdGlobalProps->mlu_mgmt_url_valid = 1; 256711103SJohn.Forte@Sun.COM bcopy(propVal, &(sbdGlobalProps->mlu_buf), 256811103SJohn.Forte@Sun.COM propLen + 1); 256911103SJohn.Forte@Sun.COM break; 257011103SJohn.Forte@Sun.COM default: 257111103SJohn.Forte@Sun.COM ret = STMF_ERROR_NO_PROP; 257211103SJohn.Forte@Sun.COM goto done; 257311103SJohn.Forte@Sun.COM } 257411103SJohn.Forte@Sun.COM 257511103SJohn.Forte@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 257611103SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size; 257711103SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps; 257811103SJohn.Forte@Sun.COM 257911103SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl); 258011103SJohn.Forte@Sun.COM if (ioctlRet != 0) { 258111103SJohn.Forte@Sun.COM savedErrno = errno; 258211103SJohn.Forte@Sun.COM switch (savedErrno) { 258311103SJohn.Forte@Sun.COM case EBUSY: 258411103SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 258511103SJohn.Forte@Sun.COM break; 258611103SJohn.Forte@Sun.COM case EPERM: 258711103SJohn.Forte@Sun.COM case EACCES: 258811103SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 258911103SJohn.Forte@Sun.COM break; 259011103SJohn.Forte@Sun.COM default: 259111103SJohn.Forte@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 259211103SJohn.Forte@Sun.COM if (ret == STMF_STATUS_ERROR) { 259311103SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 259411103SJohn.Forte@Sun.COM "modifyDiskLu:ioctl " 259511103SJohn.Forte@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 259611103SJohn.Forte@Sun.COM sbdIoctl.stmf_error, savedErrno); 259711103SJohn.Forte@Sun.COM } 259811103SJohn.Forte@Sun.COM break; 259911103SJohn.Forte@Sun.COM } 260011103SJohn.Forte@Sun.COM } 260111103SJohn.Forte@Sun.COM 260211103SJohn.Forte@Sun.COM done: 260311103SJohn.Forte@Sun.COM free(sbdGlobalProps); 260411103SJohn.Forte@Sun.COM (void) close(fd); 260511103SJohn.Forte@Sun.COM return (ret); 260611103SJohn.Forte@Sun.COM } 260711103SJohn.Forte@Sun.COM 26089585STim.Szeto@Sun.COM 26099585STim.Szeto@Sun.COM /* 26109585STim.Szeto@Sun.COM * stmfSetLuProp 26119585STim.Szeto@Sun.COM * 26129585STim.Szeto@Sun.COM * Purpose: set a property on an luResource 26139585STim.Szeto@Sun.COM * 26149585STim.Szeto@Sun.COM * hdl - allocated luResource 26159585STim.Szeto@Sun.COM * prop - property identifier 26169585STim.Szeto@Sun.COM * propVal - property value to be set 26179585STim.Szeto@Sun.COM */ 26189585STim.Szeto@Sun.COM int 26199585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal) 26209585STim.Szeto@Sun.COM { 26219585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 26229585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 26239585STim.Szeto@Sun.COM if (hdl == NULL) { 26249585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26259585STim.Szeto@Sun.COM } 26269585STim.Szeto@Sun.COM 26279585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 26289585STim.Szeto@Sun.COM ret = setDiskProp(luPropsHdl, prop, propVal); 26299585STim.Szeto@Sun.COM } else { 26309585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26319585STim.Szeto@Sun.COM } 26329585STim.Szeto@Sun.COM 26339585STim.Szeto@Sun.COM return (ret); 26349585STim.Szeto@Sun.COM } 26359585STim.Szeto@Sun.COM 26369585STim.Szeto@Sun.COM /* 26379585STim.Szeto@Sun.COM * getDiskProp 26389585STim.Szeto@Sun.COM * 26399585STim.Szeto@Sun.COM * Purpose: retrieve a given property from a logical unit resource of type disk 26409585STim.Szeto@Sun.COM * 26419585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 26429585STim.Szeto@Sun.COM * prop - property identifier 26439585STim.Szeto@Sun.COM * propVal - pointer to character to contain the retrieved property value 26449585STim.Szeto@Sun.COM * propLen - On input this is the length of propVal. On failure, it contains the 26459585STim.Szeto@Sun.COM * number of bytes required for propVal 26469585STim.Szeto@Sun.COM */ 26479585STim.Szeto@Sun.COM static int 26489585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen) 26499585STim.Szeto@Sun.COM { 26509585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 26519585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 265210725SJohn.Forte@Sun.COM char accessState[20]; 26539585STim.Szeto@Sun.COM size_t reqLen; 26549585STim.Szeto@Sun.COM 265510725SJohn.Forte@Sun.COM if (prop == STMF_LU_PROP_ACCESS_STATE) { 265610725SJohn.Forte@Sun.COM if (diskLu->accessState == SBD_LU_ACTIVE) { 265710725SJohn.Forte@Sun.COM (void) strlcpy(accessState, STMF_ACCESS_ACTIVE, 265810725SJohn.Forte@Sun.COM sizeof (accessState)); 265910725SJohn.Forte@Sun.COM } else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) { 266010725SJohn.Forte@Sun.COM (void) strlcpy(accessState, 266110725SJohn.Forte@Sun.COM STMF_ACCESS_STANDBY_TO_ACTIVE, 266210725SJohn.Forte@Sun.COM sizeof (accessState)); 266310725SJohn.Forte@Sun.COM } else if (diskLu->accessState == SBD_LU_STANDBY) { 266410725SJohn.Forte@Sun.COM (void) strlcpy(accessState, STMF_ACCESS_STANDBY, 266510725SJohn.Forte@Sun.COM sizeof (accessState)); 266610725SJohn.Forte@Sun.COM } else if (diskLu->accessState == 266710725SJohn.Forte@Sun.COM SBD_LU_TRANSITION_TO_STANDBY) { 266810725SJohn.Forte@Sun.COM (void) strlcpy(accessState, 266910725SJohn.Forte@Sun.COM STMF_ACCESS_ACTIVE_TO_STANDBY, 267010725SJohn.Forte@Sun.COM sizeof (accessState)); 267110725SJohn.Forte@Sun.COM } 267210725SJohn.Forte@Sun.COM if ((reqLen = strlcpy(propVal, accessState, 267310725SJohn.Forte@Sun.COM *propLen)) >= *propLen) { 267410725SJohn.Forte@Sun.COM *propLen = reqLen + 1; 267510725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 267610725SJohn.Forte@Sun.COM } 267710725SJohn.Forte@Sun.COM return (0); 267810725SJohn.Forte@Sun.COM } 267910725SJohn.Forte@Sun.COM 268010725SJohn.Forte@Sun.COM if (diskLu->accessState != SBD_LU_ACTIVE) { 268110725SJohn.Forte@Sun.COM return (STMF_ERROR_NO_PROP_STANDBY); 268210725SJohn.Forte@Sun.COM } 268310725SJohn.Forte@Sun.COM 26849585STim.Szeto@Sun.COM switch (prop) { 26859585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 26869585STim.Szeto@Sun.COM if (diskLu->blkSizeValid == B_FALSE) { 26879585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 26889585STim.Szeto@Sun.COM } 26899585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, "%llu", 26909585STim.Szeto@Sun.COM (u_longlong_t)diskLu->blkSize); 26919585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 26929585STim.Szeto@Sun.COM *propLen = reqLen + 1; 26939585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26949585STim.Szeto@Sun.COM } 26959585STim.Szeto@Sun.COM break; 26969585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 26979585STim.Szeto@Sun.COM if (diskLu->luDataFileNameValid == B_FALSE) { 26989585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 26999585STim.Szeto@Sun.COM } 27009585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luDataFileName, 27019585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27029585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27039585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27049585STim.Szeto@Sun.COM } 27059585STim.Szeto@Sun.COM break; 27069585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 27079585STim.Szeto@Sun.COM if (diskLu->luMetaFileNameValid == B_FALSE) { 27089585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27099585STim.Szeto@Sun.COM } 27109585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName, 27119585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27129585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27139585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27149585STim.Szeto@Sun.COM } 27159585STim.Szeto@Sun.COM break; 271610113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 271710113SNattuvetty.Bhavyan@Sun.COM if (diskLu->luMgmtUrlValid == B_FALSE) { 271810113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_NO_PROP); 271910113SNattuvetty.Bhavyan@Sun.COM } 272010113SNattuvetty.Bhavyan@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl, 272110113SNattuvetty.Bhavyan@Sun.COM *propLen)) >= *propLen) { 272210113SNattuvetty.Bhavyan@Sun.COM *propLen = reqLen + 1; 272310113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_ARG); 272410113SNattuvetty.Bhavyan@Sun.COM } 272510113SNattuvetty.Bhavyan@Sun.COM break; 27269585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 27279585STim.Szeto@Sun.COM if (diskLu->luGuidValid == B_FALSE) { 27289585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27299585STim.Szeto@Sun.COM } 27309585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, 27319585STim.Szeto@Sun.COM "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 27329585STim.Szeto@Sun.COM "%02X%02X%02X%02X", 27339585STim.Szeto@Sun.COM diskLu->luGuid[0], diskLu->luGuid[1], 27349585STim.Szeto@Sun.COM diskLu->luGuid[2], diskLu->luGuid[3], 27359585STim.Szeto@Sun.COM diskLu->luGuid[4], diskLu->luGuid[5], 27369585STim.Szeto@Sun.COM diskLu->luGuid[6], diskLu->luGuid[7], 27379585STim.Szeto@Sun.COM diskLu->luGuid[8], diskLu->luGuid[9], 27389585STim.Szeto@Sun.COM diskLu->luGuid[10], diskLu->luGuid[11], 27399585STim.Szeto@Sun.COM diskLu->luGuid[12], diskLu->luGuid[13], 27409585STim.Szeto@Sun.COM diskLu->luGuid[14], diskLu->luGuid[15]); 27419585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 27429585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27439585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27449585STim.Szeto@Sun.COM } 27459585STim.Szeto@Sun.COM break; 27469585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 27479585STim.Szeto@Sun.COM if (diskLu->serialNumValid == B_FALSE) { 27489585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27499585STim.Szeto@Sun.COM } 27509585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->serialNum, 27519585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27529585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27539585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27549585STim.Szeto@Sun.COM } 27559585STim.Szeto@Sun.COM break; 27569585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 27579585STim.Szeto@Sun.COM if (diskLu->luSizeValid == B_FALSE) { 27589585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27599585STim.Szeto@Sun.COM } 27609585STim.Szeto@Sun.COM (void) snprintf(propVal, *propLen, "%llu", 27619585STim.Szeto@Sun.COM (u_longlong_t)diskLu->luSize); 27629585STim.Szeto@Sun.COM break; 27639585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 27649585STim.Szeto@Sun.COM if (diskLu->luAliasValid == B_FALSE) { 27659585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27669585STim.Szeto@Sun.COM } 27679585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luAlias, 27689585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27699585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27709585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27719585STim.Szeto@Sun.COM } 27729585STim.Szeto@Sun.COM break; 27739585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 27749585STim.Szeto@Sun.COM if (diskLu->vidValid == B_FALSE) { 27759585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27769585STim.Szeto@Sun.COM } 27779585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->vid)) { 27789585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27799585STim.Szeto@Sun.COM } 27809585STim.Szeto@Sun.COM bcopy(diskLu->vid, propVal, sizeof (diskLu->vid)); 27819585STim.Szeto@Sun.COM propVal[sizeof (diskLu->vid)] = 0; 27829585STim.Szeto@Sun.COM break; 27839585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 27849585STim.Szeto@Sun.COM if (diskLu->pidValid == B_FALSE) { 27859585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27869585STim.Szeto@Sun.COM } 27879585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->pid)) { 27889585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27899585STim.Szeto@Sun.COM } 27909585STim.Szeto@Sun.COM bcopy(diskLu->pid, propVal, sizeof (diskLu->pid)); 27919585STim.Szeto@Sun.COM propVal[sizeof (diskLu->pid)] = 0; 27929585STim.Szeto@Sun.COM break; 27939585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 27949585STim.Szeto@Sun.COM if (diskLu->writeProtectEnableValid == B_FALSE) { 27959585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27969585STim.Szeto@Sun.COM } 27979585STim.Szeto@Sun.COM if (diskLu->writeProtectEnable) { 27989585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 27999585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28009585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28019585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28029585STim.Szeto@Sun.COM } 28039585STim.Szeto@Sun.COM } else { 28049585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 28059585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28069585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28079585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28089585STim.Szeto@Sun.COM } 28099585STim.Szeto@Sun.COM } 28109585STim.Szeto@Sun.COM break; 28119585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 28129585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisableValid == B_FALSE) { 28139585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 28149585STim.Szeto@Sun.COM } 28159585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisable) { 28169585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 28179585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28189585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28199585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28209585STim.Szeto@Sun.COM } 28219585STim.Szeto@Sun.COM } else { 28229585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 28239585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28249585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28259585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28269585STim.Szeto@Sun.COM } 28279585STim.Szeto@Sun.COM } 28289585STim.Szeto@Sun.COM break; 28299585STim.Szeto@Sun.COM default: 283011691SSrivijitha.Dugganapalli@Sun.COM ret = STMF_ERROR_INVALID_PROP; 28319585STim.Szeto@Sun.COM break; 28329585STim.Szeto@Sun.COM } 28339585STim.Szeto@Sun.COM 28349585STim.Szeto@Sun.COM return (ret); 28359585STim.Szeto@Sun.COM } 28369585STim.Szeto@Sun.COM 28379585STim.Szeto@Sun.COM /* 28389585STim.Szeto@Sun.COM * setDiskProp 28399585STim.Szeto@Sun.COM * 28409585STim.Szeto@Sun.COM * Purpose: set properties for resource of type disk 28419585STim.Szeto@Sun.COM * 28429585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 28439585STim.Szeto@Sun.COM * resourceProp - valid resource identifier 28449585STim.Szeto@Sun.COM * propVal - valid resource value 28459585STim.Szeto@Sun.COM */ 28469585STim.Szeto@Sun.COM static int 28479585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal) 28489585STim.Szeto@Sun.COM { 28499585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 28509585STim.Szeto@Sun.COM int i; 28519585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 28529585STim.Szeto@Sun.COM unsigned long long numericProp = 0; 28539585STim.Szeto@Sun.COM char guidProp[LU_ASCII_GUID_SIZE + 1]; 28549585STim.Szeto@Sun.COM char ouiProp[OUI_ASCII_SIZE + 1]; 285510765SJohn.Forte@Sun.COM char hostIdProp[HOST_ID_ASCII_SIZE + 1]; 28569585STim.Szeto@Sun.COM unsigned int oui[OUI_SIZE]; 285710765SJohn.Forte@Sun.COM unsigned int hostId[HOST_ID_SIZE]; 28589585STim.Szeto@Sun.COM unsigned int guid[LU_GUID_SIZE]; 28599585STim.Szeto@Sun.COM int propSize; 28609585STim.Szeto@Sun.COM 28619585STim.Szeto@Sun.COM 28629585STim.Szeto@Sun.COM if (propVal == NULL) { 28639585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28649585STim.Szeto@Sun.COM } 28659585STim.Szeto@Sun.COM 28669585STim.Szeto@Sun.COM switch (resourceProp) { 28679585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 28689585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, propVal, 28699585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 28709585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 28719585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 28729585STim.Szeto@Sun.COM } 28739585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 28749585STim.Szeto@Sun.COM break; 2875*11865SSrivijitha.Dugganapalli@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: { 2876*11865SSrivijitha.Dugganapalli@Sun.COM const char *tmp = propVal; 2877*11865SSrivijitha.Dugganapalli@Sun.COM while (*tmp) { 2878*11865SSrivijitha.Dugganapalli@Sun.COM if (!isdigit(*tmp++)) { 2879*11865SSrivijitha.Dugganapalli@Sun.COM return (STMF_ERROR_INVALID_ARG); 2880*11865SSrivijitha.Dugganapalli@Sun.COM } 2881*11865SSrivijitha.Dugganapalli@Sun.COM } 28829585STim.Szeto@Sun.COM (void) sscanf(propVal, "%llu", &numericProp); 28839585STim.Szeto@Sun.COM if (numericProp > UINT16_MAX) { 28849585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 28859585STim.Szeto@Sun.COM } 28869585STim.Szeto@Sun.COM diskLu->blkSize = numericProp; 28879585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 28889585STim.Szeto@Sun.COM break; 2889*11865SSrivijitha.Dugganapalli@Sun.COM } 28909585STim.Szeto@Sun.COM case STMF_LU_PROP_COMPANY_ID: 28919585STim.Szeto@Sun.COM if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >= 28929585STim.Szeto@Sun.COM sizeof (ouiProp)) { 28939585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28949585STim.Szeto@Sun.COM } 28959585STim.Szeto@Sun.COM if (checkHexUpper(ouiProp) != 0) { 28969585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28979585STim.Szeto@Sun.COM } 28989585STim.Szeto@Sun.COM (void) sscanf(ouiProp, "%2X%2X%2X", 28999585STim.Szeto@Sun.COM &oui[0], &oui[1], &oui[2]); 29009585STim.Szeto@Sun.COM 29019585STim.Szeto@Sun.COM diskLu->companyId = 0; 29029585STim.Szeto@Sun.COM diskLu->companyId += oui[0] << 16; 29039585STim.Szeto@Sun.COM diskLu->companyId += oui[1] << 8; 29049585STim.Szeto@Sun.COM diskLu->companyId += oui[2]; 290510765SJohn.Forte@Sun.COM if (diskLu->companyId == 0) { 290610765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 290710765SJohn.Forte@Sun.COM } 29089585STim.Szeto@Sun.COM diskLu->companyIdValid = B_TRUE; 29099585STim.Szeto@Sun.COM break; 291010765SJohn.Forte@Sun.COM case STMF_LU_PROP_HOST_ID: 291110765SJohn.Forte@Sun.COM if ((strlcpy(hostIdProp, propVal, 291210765SJohn.Forte@Sun.COM sizeof (hostIdProp))) >= sizeof (hostIdProp)) { 291310765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 291410765SJohn.Forte@Sun.COM } 291510765SJohn.Forte@Sun.COM if (checkHexUpper(hostIdProp) != 0) { 291610765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 291710765SJohn.Forte@Sun.COM } 291810765SJohn.Forte@Sun.COM (void) sscanf(hostIdProp, "%2X%2X%2X%2X", 291910765SJohn.Forte@Sun.COM &hostId[0], &hostId[1], &hostId[2], &hostId[3]); 292010765SJohn.Forte@Sun.COM 292110765SJohn.Forte@Sun.COM diskLu->hostId = 0; 292210765SJohn.Forte@Sun.COM diskLu->hostId += hostId[0] << 24; 292310765SJohn.Forte@Sun.COM diskLu->hostId += hostId[1] << 16; 292410765SJohn.Forte@Sun.COM diskLu->hostId += hostId[2] << 8; 292510765SJohn.Forte@Sun.COM diskLu->hostId += hostId[3]; 292610765SJohn.Forte@Sun.COM if (diskLu->hostId == 0) { 292710765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 292810765SJohn.Forte@Sun.COM } 292910765SJohn.Forte@Sun.COM diskLu->hostIdValid = B_TRUE; 293010765SJohn.Forte@Sun.COM break; 29319585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 29329585STim.Szeto@Sun.COM if (strlen(propVal) != LU_ASCII_GUID_SIZE) { 29339585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29349585STim.Szeto@Sun.COM } 29359585STim.Szeto@Sun.COM 29369585STim.Szeto@Sun.COM if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >= 29379585STim.Szeto@Sun.COM sizeof (guidProp)) { 29389585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29399585STim.Szeto@Sun.COM } 29409585STim.Szeto@Sun.COM 29419585STim.Szeto@Sun.COM if (checkHexUpper(guidProp) != 0) { 29429585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29439585STim.Szeto@Sun.COM } 29449585STim.Szeto@Sun.COM 29459585STim.Szeto@Sun.COM (void) sscanf(guidProp, 29469585STim.Szeto@Sun.COM "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X", 29479585STim.Szeto@Sun.COM &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], 29489585STim.Szeto@Sun.COM &guid[5], &guid[6], &guid[7], &guid[8], &guid[9], 29499585STim.Szeto@Sun.COM &guid[10], &guid[11], &guid[12], &guid[13], 29509585STim.Szeto@Sun.COM &guid[14], &guid[15]); 29519585STim.Szeto@Sun.COM for (i = 0; i < sizeof (diskLu->luGuid); i++) { 29529585STim.Szeto@Sun.COM diskLu->luGuid[i] = guid[i]; 29539585STim.Szeto@Sun.COM } 29549585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 29559585STim.Szeto@Sun.COM break; 29569585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 29579585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luDataFileName, propVal, 29589585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName))) >= 29599585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 29609585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29619585STim.Szeto@Sun.COM } 29629585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 29639585STim.Szeto@Sun.COM break; 29649585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 29659585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luMetaFileName, propVal, 29669585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName))) >= 29679585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 29689585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29699585STim.Szeto@Sun.COM } 29709585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 29719585STim.Szeto@Sun.COM break; 297210113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 297310113SNattuvetty.Bhavyan@Sun.COM if ((strlcpy(diskLu->luMgmtUrl, propVal, 297410113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl))) >= 297510113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 297610113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 297710113SNattuvetty.Bhavyan@Sun.COM } 297810113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 297910113SNattuvetty.Bhavyan@Sun.COM break; 29809585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 29819585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 29829585STim.Szeto@Sun.COM sizeof (diskLu->pid)) { 29839585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29849585STim.Szeto@Sun.COM } 29859585STim.Szeto@Sun.COM (void) strncpy(diskLu->pid, propVal, propSize); 29869585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 29879585STim.Szeto@Sun.COM break; 29889585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 29899585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 29909585STim.Szeto@Sun.COM (sizeof (diskLu->serialNum) - 1)) { 29919585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29929585STim.Szeto@Sun.COM } 29939585STim.Szeto@Sun.COM (void) strncpy(diskLu->serialNum, propVal, propSize); 29949585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 29959585STim.Szeto@Sun.COM break; 29969585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 29979585STim.Szeto@Sun.COM if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) { 29989585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29999585STim.Szeto@Sun.COM } 30009585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 30019585STim.Szeto@Sun.COM break; 30029585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 30039585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 30049585STim.Szeto@Sun.COM sizeof (diskLu->vid)) { 30059585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 30069585STim.Szeto@Sun.COM } 30079585STim.Szeto@Sun.COM (void) strncpy(diskLu->vid, propVal, propSize); 30089585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 30099585STim.Szeto@Sun.COM break; 30109585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 30119585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 30129585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 30139585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 30149585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_FALSE; 30159585STim.Szeto@Sun.COM } else { 30169585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30179585STim.Szeto@Sun.COM } 30189585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 30199585STim.Szeto@Sun.COM break; 30209585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 30219585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 30229585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 30239585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 30249585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_FALSE; 30259585STim.Szeto@Sun.COM } else { 30269585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30279585STim.Szeto@Sun.COM } 30289585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 30299585STim.Szeto@Sun.COM break; 303010725SJohn.Forte@Sun.COM case STMF_LU_PROP_ACCESS_STATE: 303110725SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_PROP; 303210725SJohn.Forte@Sun.COM break; 30339585STim.Szeto@Sun.COM default: 303411691SSrivijitha.Dugganapalli@Sun.COM ret = STMF_ERROR_INVALID_PROP; 30359585STim.Szeto@Sun.COM break; 30369585STim.Szeto@Sun.COM } 30379585STim.Szeto@Sun.COM return (ret); 30389585STim.Szeto@Sun.COM } 30399585STim.Szeto@Sun.COM 30409585STim.Szeto@Sun.COM static int 30419585STim.Szeto@Sun.COM checkHexUpper(char *buf) 30429585STim.Szeto@Sun.COM { 30439585STim.Szeto@Sun.COM int i; 30449585STim.Szeto@Sun.COM 30459585STim.Szeto@Sun.COM for (i = 0; i < strlen(buf); i++) { 30469585STim.Szeto@Sun.COM if (isxdigit(buf[i])) { 30479585STim.Szeto@Sun.COM buf[i] = toupper(buf[i]); 30489585STim.Szeto@Sun.COM continue; 30499585STim.Szeto@Sun.COM } 30509585STim.Szeto@Sun.COM return (-1); 30519585STim.Szeto@Sun.COM } 30529585STim.Szeto@Sun.COM 30539585STim.Szeto@Sun.COM return (0); 30549585STim.Szeto@Sun.COM } 30559585STim.Szeto@Sun.COM 30569585STim.Szeto@Sun.COM /* 30579585STim.Szeto@Sun.COM * Given a numeric suffix, convert the value into a number of bits that the 30589585STim.Szeto@Sun.COM * resulting value must be shifted. 30599585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 30609585STim.Szeto@Sun.COM */ 30619585STim.Szeto@Sun.COM static int 30629585STim.Szeto@Sun.COM strToShift(const char *buf) 30639585STim.Szeto@Sun.COM { 30649585STim.Szeto@Sun.COM const char *ends = "BKMGTPE"; 30659585STim.Szeto@Sun.COM int i; 30669585STim.Szeto@Sun.COM 30679585STim.Szeto@Sun.COM if (buf[0] == '\0') 30689585STim.Szeto@Sun.COM return (0); 30699585STim.Szeto@Sun.COM 30709585STim.Szeto@Sun.COM for (i = 0; i < strlen(ends); i++) { 30719585STim.Szeto@Sun.COM if (toupper(buf[0]) == ends[i]) 30729585STim.Szeto@Sun.COM return (10*i); 30739585STim.Szeto@Sun.COM } 30749585STim.Szeto@Sun.COM 30759585STim.Szeto@Sun.COM return (-1); 30769585STim.Szeto@Sun.COM } 30779585STim.Szeto@Sun.COM 30789585STim.Szeto@Sun.COM int 30799585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl) 30809585STim.Szeto@Sun.COM { 30819585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 30829585STim.Szeto@Sun.COM if (hdl == NULL) { 30839585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30849585STim.Szeto@Sun.COM } 30859585STim.Szeto@Sun.COM 30869585STim.Szeto@Sun.COM luResourceImpl *hdlImpl = hdl; 30879585STim.Szeto@Sun.COM free(hdlImpl->resource); 30889585STim.Szeto@Sun.COM free(hdlImpl); 30899585STim.Szeto@Sun.COM return (ret); 30909585STim.Szeto@Sun.COM } 30919585STim.Szeto@Sun.COM 30929585STim.Szeto@Sun.COM /* 30939585STim.Szeto@Sun.COM * Convert a string of the form '100G' into a real number. Used when setting 30949585STim.Szeto@Sun.COM * the size of a logical unit. 30959585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 30969585STim.Szeto@Sun.COM */ 30979585STim.Szeto@Sun.COM static int 30989585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num) 30999585STim.Szeto@Sun.COM { 31009585STim.Szeto@Sun.COM char *end; 31019585STim.Szeto@Sun.COM int shift; 31029585STim.Szeto@Sun.COM 31039585STim.Szeto@Sun.COM *num = 0; 31049585STim.Szeto@Sun.COM 31059585STim.Szeto@Sun.COM /* Check to see if this looks like a number. */ 31069585STim.Szeto@Sun.COM if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 31079585STim.Szeto@Sun.COM return (-1); 31089585STim.Szeto@Sun.COM } 31099585STim.Szeto@Sun.COM 31109585STim.Szeto@Sun.COM /* Rely on stroull() to process the numeric portion. */ 31119585STim.Szeto@Sun.COM errno = 0; 31129585STim.Szeto@Sun.COM *num = strtoull(value, &end, 10); 31139585STim.Szeto@Sun.COM 31149585STim.Szeto@Sun.COM /* 31159585STim.Szeto@Sun.COM * Check for ERANGE, which indicates that the value is too large to fit 31169585STim.Szeto@Sun.COM * in a 64-bit value. 31179585STim.Szeto@Sun.COM */ 31189585STim.Szeto@Sun.COM if (errno == ERANGE) { 31199585STim.Szeto@Sun.COM return (-1); 31209585STim.Szeto@Sun.COM } 31219585STim.Szeto@Sun.COM 31229585STim.Szeto@Sun.COM /* 31239585STim.Szeto@Sun.COM * If we have a decimal value, then do the computation with floating 31249585STim.Szeto@Sun.COM * point arithmetic. Otherwise, use standard arithmetic. 31259585STim.Szeto@Sun.COM */ 31269585STim.Szeto@Sun.COM if (*end == '.') { 31279585STim.Szeto@Sun.COM double fval = strtod(value, &end); 31289585STim.Szeto@Sun.COM 31299585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 31309585STim.Szeto@Sun.COM return (-1); 31319585STim.Szeto@Sun.COM } 31329585STim.Szeto@Sun.COM 31339585STim.Szeto@Sun.COM fval *= pow(2, shift); 31349585STim.Szeto@Sun.COM 31359585STim.Szeto@Sun.COM if (fval > UINT64_MAX) { 31369585STim.Szeto@Sun.COM return (-1); 31379585STim.Szeto@Sun.COM } 31389585STim.Szeto@Sun.COM 31399585STim.Szeto@Sun.COM *num = (uint64_t)fval; 31409585STim.Szeto@Sun.COM } else { 31419585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 31429585STim.Szeto@Sun.COM return (-1); 31439585STim.Szeto@Sun.COM } 31449585STim.Szeto@Sun.COM 31459585STim.Szeto@Sun.COM /* Check for overflow */ 31469585STim.Szeto@Sun.COM if (shift >= 64 || (*num << shift) >> shift != *num) { 31479585STim.Szeto@Sun.COM return (-1); 31489585STim.Szeto@Sun.COM } 31499585STim.Szeto@Sun.COM 31509585STim.Szeto@Sun.COM *num <<= shift; 31519585STim.Szeto@Sun.COM } 31529585STim.Szeto@Sun.COM 31539585STim.Szeto@Sun.COM return (0); 31549585STim.Szeto@Sun.COM } 31559585STim.Szeto@Sun.COM 31569585STim.Szeto@Sun.COM /* 31577836SJohn.Forte@Sun.COM * stmfCreateTargetGroup 31587836SJohn.Forte@Sun.COM * 31597836SJohn.Forte@Sun.COM * Purpose: Create a local port group 31607836SJohn.Forte@Sun.COM * 31617836SJohn.Forte@Sun.COM * targetGroupName - name of local port group to create 31627836SJohn.Forte@Sun.COM */ 31637836SJohn.Forte@Sun.COM int 31647836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName) 31657836SJohn.Forte@Sun.COM { 31667836SJohn.Forte@Sun.COM int ret; 31677836SJohn.Forte@Sun.COM int fd; 31687836SJohn.Forte@Sun.COM 31697836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 31707836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 31717836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 31727836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31737836SJohn.Forte@Sun.COM } 31747836SJohn.Forte@Sun.COM 31757836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 31767836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 31777836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 31787836SJohn.Forte@Sun.COM } 31797836SJohn.Forte@Sun.COM 31807836SJohn.Forte@Sun.COM /* call init */ 31817836SJohn.Forte@Sun.COM ret = initializeConfig(); 31827836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 31837836SJohn.Forte@Sun.COM return (ret); 31847836SJohn.Forte@Sun.COM } 31857836SJohn.Forte@Sun.COM 31867836SJohn.Forte@Sun.COM /* 31877836SJohn.Forte@Sun.COM * Open control node for stmf 31887836SJohn.Forte@Sun.COM */ 31897836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 31907836SJohn.Forte@Sun.COM return (ret); 31917836SJohn.Forte@Sun.COM 31927836SJohn.Forte@Sun.COM /* 31937836SJohn.Forte@Sun.COM * Add the group to the driver 31947836SJohn.Forte@Sun.COM */ 31957836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 31967836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 31977836SJohn.Forte@Sun.COM goto done; 31987836SJohn.Forte@Sun.COM } 31997836SJohn.Forte@Sun.COM 32009585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 32019585STim.Szeto@Sun.COM goto done; 32029585STim.Szeto@Sun.COM } 32039585STim.Szeto@Sun.COM 32047836SJohn.Forte@Sun.COM /* 32057836SJohn.Forte@Sun.COM * If the add to the driver was successful, add it to the persistent 32067836SJohn.Forte@Sun.COM * store. 32077836SJohn.Forte@Sun.COM */ 32087836SJohn.Forte@Sun.COM ret = psCreateTargetGroup((char *)targetGroupName); 32097836SJohn.Forte@Sun.COM switch (ret) { 32107836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 32117836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 32127836SJohn.Forte@Sun.COM break; 32137836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 32147836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 32157836SJohn.Forte@Sun.COM break; 32167836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 32177836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 32187836SJohn.Forte@Sun.COM break; 32197836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 32207836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 32217836SJohn.Forte@Sun.COM break; 32227836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 32237836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 32247836SJohn.Forte@Sun.COM break; 32257836SJohn.Forte@Sun.COM default: 32267836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 32277836SJohn.Forte@Sun.COM "stmfCreateTargetGroup:psCreateTargetGroup" 32287836SJohn.Forte@Sun.COM ":error(%d)", ret); 32297836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 32307836SJohn.Forte@Sun.COM break; 32317836SJohn.Forte@Sun.COM } 32327836SJohn.Forte@Sun.COM 32337836SJohn.Forte@Sun.COM done: 32347836SJohn.Forte@Sun.COM (void) close(fd); 32357836SJohn.Forte@Sun.COM return (ret); 32367836SJohn.Forte@Sun.COM } 32377836SJohn.Forte@Sun.COM 32387836SJohn.Forte@Sun.COM /* 32397836SJohn.Forte@Sun.COM * stmfDeleteHostGroup 32407836SJohn.Forte@Sun.COM * 32417836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 32427836SJohn.Forte@Sun.COM * 32437836SJohn.Forte@Sun.COM * hostGroupName - group to delete 32447836SJohn.Forte@Sun.COM */ 32457836SJohn.Forte@Sun.COM int 32467836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName) 32477836SJohn.Forte@Sun.COM { 32487836SJohn.Forte@Sun.COM int ret; 32497836SJohn.Forte@Sun.COM int fd; 32507836SJohn.Forte@Sun.COM 32517836SJohn.Forte@Sun.COM if (hostGroupName == NULL) { 32527836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 32537836SJohn.Forte@Sun.COM } 32547836SJohn.Forte@Sun.COM 32557836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 32567836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 32577836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 32587836SJohn.Forte@Sun.COM } 32597836SJohn.Forte@Sun.COM 32607836SJohn.Forte@Sun.COM /* call init */ 32617836SJohn.Forte@Sun.COM ret = initializeConfig(); 32627836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 32637836SJohn.Forte@Sun.COM return (ret); 32647836SJohn.Forte@Sun.COM } 32657836SJohn.Forte@Sun.COM 32667836SJohn.Forte@Sun.COM /* 32677836SJohn.Forte@Sun.COM * Open control node for stmf 32687836SJohn.Forte@Sun.COM */ 32697836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 32707836SJohn.Forte@Sun.COM return (ret); 32717836SJohn.Forte@Sun.COM 32727836SJohn.Forte@Sun.COM /* 32737836SJohn.Forte@Sun.COM * Remove the group from the driver 32747836SJohn.Forte@Sun.COM */ 32757836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP, 32767836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 32777836SJohn.Forte@Sun.COM goto done; 32787836SJohn.Forte@Sun.COM } 32797836SJohn.Forte@Sun.COM 32809585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 32819585STim.Szeto@Sun.COM goto done; 32829585STim.Szeto@Sun.COM } 32839585STim.Szeto@Sun.COM 32847836SJohn.Forte@Sun.COM /* 32857836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 32867836SJohn.Forte@Sun.COM * persistent store. 32877836SJohn.Forte@Sun.COM */ 32887836SJohn.Forte@Sun.COM ret = psDeleteHostGroup((char *)hostGroupName); 32897836SJohn.Forte@Sun.COM switch (ret) { 32907836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 32917836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 32927836SJohn.Forte@Sun.COM break; 32937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 32947836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 32957836SJohn.Forte@Sun.COM break; 32967836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 32977836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 32987836SJohn.Forte@Sun.COM break; 32997836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33007836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33017836SJohn.Forte@Sun.COM break; 33027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33037836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33047836SJohn.Forte@Sun.COM break; 33057836SJohn.Forte@Sun.COM default: 33067836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 33077836SJohn.Forte@Sun.COM "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)", 33087836SJohn.Forte@Sun.COM ret); 33097836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33107836SJohn.Forte@Sun.COM break; 33117836SJohn.Forte@Sun.COM } 33127836SJohn.Forte@Sun.COM 33137836SJohn.Forte@Sun.COM done: 33147836SJohn.Forte@Sun.COM (void) close(fd); 33157836SJohn.Forte@Sun.COM return (ret); 33167836SJohn.Forte@Sun.COM } 33177836SJohn.Forte@Sun.COM 33187836SJohn.Forte@Sun.COM /* 33197836SJohn.Forte@Sun.COM * stmfDeleteTargetGroup 33207836SJohn.Forte@Sun.COM * 33217836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 33227836SJohn.Forte@Sun.COM * 33237836SJohn.Forte@Sun.COM * targetGroupName - group to delete 33247836SJohn.Forte@Sun.COM */ 33257836SJohn.Forte@Sun.COM int 33267836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName) 33277836SJohn.Forte@Sun.COM { 33287836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 33297836SJohn.Forte@Sun.COM int fd; 33307836SJohn.Forte@Sun.COM 33317836SJohn.Forte@Sun.COM if (targetGroupName == NULL) { 33327836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 33337836SJohn.Forte@Sun.COM } 33347836SJohn.Forte@Sun.COM 33357836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 33367836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 33377836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 33387836SJohn.Forte@Sun.COM } 33397836SJohn.Forte@Sun.COM 33407836SJohn.Forte@Sun.COM /* call init */ 33417836SJohn.Forte@Sun.COM ret = initializeConfig(); 33427836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 33437836SJohn.Forte@Sun.COM return (ret); 33447836SJohn.Forte@Sun.COM } 33457836SJohn.Forte@Sun.COM 33467836SJohn.Forte@Sun.COM /* 33477836SJohn.Forte@Sun.COM * Open control node for stmf 33487836SJohn.Forte@Sun.COM */ 33497836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 33507836SJohn.Forte@Sun.COM return (ret); 33517836SJohn.Forte@Sun.COM 33527836SJohn.Forte@Sun.COM /* 33537836SJohn.Forte@Sun.COM * Remove the group from the driver 33547836SJohn.Forte@Sun.COM */ 33557836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP, 33567836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 33577836SJohn.Forte@Sun.COM goto done; 33587836SJohn.Forte@Sun.COM } 33597836SJohn.Forte@Sun.COM 33609585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 33619585STim.Szeto@Sun.COM goto done; 33629585STim.Szeto@Sun.COM } 33639585STim.Szeto@Sun.COM 33647836SJohn.Forte@Sun.COM /* 33657836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 33667836SJohn.Forte@Sun.COM * persistent store. 33677836SJohn.Forte@Sun.COM */ 33687836SJohn.Forte@Sun.COM ret = psDeleteTargetGroup((char *)targetGroupName); 33697836SJohn.Forte@Sun.COM switch (ret) { 33707836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 33717836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 33727836SJohn.Forte@Sun.COM break; 33737836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 33747836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 33757836SJohn.Forte@Sun.COM break; 33767836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 33777836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 33787836SJohn.Forte@Sun.COM break; 33797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33807836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33817836SJohn.Forte@Sun.COM break; 33827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33837836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33847836SJohn.Forte@Sun.COM break; 33857836SJohn.Forte@Sun.COM default: 33867836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 33877836SJohn.Forte@Sun.COM "stmfDeleteTargetGroup:psDeleteTargetGroup" 33887836SJohn.Forte@Sun.COM ":error(%d)", ret); 33897836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33907836SJohn.Forte@Sun.COM break; 33917836SJohn.Forte@Sun.COM } 33927836SJohn.Forte@Sun.COM 33937836SJohn.Forte@Sun.COM done: 33947836SJohn.Forte@Sun.COM (void) close(fd); 33957836SJohn.Forte@Sun.COM return (ret); 33967836SJohn.Forte@Sun.COM } 33977836SJohn.Forte@Sun.COM 33987836SJohn.Forte@Sun.COM /* 33997836SJohn.Forte@Sun.COM * stmfDevidFromIscsiName 34007836SJohn.Forte@Sun.COM * 34017836SJohn.Forte@Sun.COM * Purpose: convert an iSCSI name to an stmf devid 34027836SJohn.Forte@Sun.COM * 34037836SJohn.Forte@Sun.COM * iscsiName - unicode nul terminated utf-8 encoded iSCSI name 34047836SJohn.Forte@Sun.COM * devid - on success, contains the converted iscsi name 34057836SJohn.Forte@Sun.COM */ 34067836SJohn.Forte@Sun.COM int 34077836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid) 34087836SJohn.Forte@Sun.COM { 34097836SJohn.Forte@Sun.COM if (devid == NULL || iscsiName == NULL) 34107836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34117836SJohn.Forte@Sun.COM 34127836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 34137836SJohn.Forte@Sun.COM 34147836SJohn.Forte@Sun.COM /* Validate size of target */ 34157836SJohn.Forte@Sun.COM if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME || 34167836SJohn.Forte@Sun.COM devid->identLength < strlen(EUI) || 34177836SJohn.Forte@Sun.COM devid->identLength < strlen(IQN)) { 34187836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34197836SJohn.Forte@Sun.COM } 34207836SJohn.Forte@Sun.COM 34217836SJohn.Forte@Sun.COM if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) && 34227836SJohn.Forte@Sun.COM strncmp(iscsiName, IQN, strlen(IQN)) != 0) { 34237836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34247836SJohn.Forte@Sun.COM } 34257836SJohn.Forte@Sun.COM 34267836SJohn.Forte@Sun.COM /* copy UTF-8 bytes to ident */ 34277836SJohn.Forte@Sun.COM bcopy(iscsiName, devid->ident, devid->identLength); 34287836SJohn.Forte@Sun.COM 34297836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 34307836SJohn.Forte@Sun.COM } 34317836SJohn.Forte@Sun.COM 34327836SJohn.Forte@Sun.COM /* 34337836SJohn.Forte@Sun.COM * stmfDevidFromWwn 34347836SJohn.Forte@Sun.COM * 34357836SJohn.Forte@Sun.COM * Purpose: convert a WWN to an stmf devid 34367836SJohn.Forte@Sun.COM * 34377836SJohn.Forte@Sun.COM * wwn - 8-byte wwn identifier 34387836SJohn.Forte@Sun.COM * devid - on success, contains the converted wwn 34397836SJohn.Forte@Sun.COM */ 34407836SJohn.Forte@Sun.COM int 34417836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid) 34427836SJohn.Forte@Sun.COM { 34437836SJohn.Forte@Sun.COM if (wwn == NULL || devid == NULL) 34447836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34457836SJohn.Forte@Sun.COM 34467836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 34477836SJohn.Forte@Sun.COM 34487836SJohn.Forte@Sun.COM /* Copy eui prefix */ 34497836SJohn.Forte@Sun.COM (void) bcopy(WWN, devid->ident, strlen(WWN)); 34507836SJohn.Forte@Sun.COM 34517836SJohn.Forte@Sun.COM /* Convert to ASCII uppercase hexadecimal string */ 34527836SJohn.Forte@Sun.COM (void) snprintf((char *)&devid->ident[strlen(WWN)], 34537836SJohn.Forte@Sun.COM sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X", 34547836SJohn.Forte@Sun.COM wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 34557836SJohn.Forte@Sun.COM 34567836SJohn.Forte@Sun.COM devid->identLength = strlen((char *)devid->ident); 34577836SJohn.Forte@Sun.COM 34587836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 34597836SJohn.Forte@Sun.COM } 34607836SJohn.Forte@Sun.COM 34617836SJohn.Forte@Sun.COM /* 34627836SJohn.Forte@Sun.COM * stmfFreeMemory 34637836SJohn.Forte@Sun.COM * 34647836SJohn.Forte@Sun.COM * Purpose: Free memory allocated by this library 34657836SJohn.Forte@Sun.COM * 34667836SJohn.Forte@Sun.COM * memory - previously allocated pointer of memory managed by library 34677836SJohn.Forte@Sun.COM */ 34687836SJohn.Forte@Sun.COM void 34697836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory) 34707836SJohn.Forte@Sun.COM { 34717836SJohn.Forte@Sun.COM free(memory); 34727836SJohn.Forte@Sun.COM } 34737836SJohn.Forte@Sun.COM 34747836SJohn.Forte@Sun.COM /* 34759585STim.Szeto@Sun.COM * get host group, target group list from stmf 34767836SJohn.Forte@Sun.COM * 34779585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 34787836SJohn.Forte@Sun.COM */ 34799585STim.Szeto@Sun.COM static int 34809585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType) 34819585STim.Szeto@Sun.COM { 34829585STim.Szeto@Sun.COM int ret; 34839585STim.Szeto@Sun.COM int fd; 34849585STim.Szeto@Sun.COM int ioctlRet; 34859585STim.Szeto@Sun.COM int i; 34869585STim.Szeto@Sun.COM int cmd; 34879585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 34889585STim.Szeto@Sun.COM /* framework group list */ 34899585STim.Szeto@Sun.COM stmf_group_name_t *iGroupList = NULL; 34909585STim.Szeto@Sun.COM uint32_t groupListSize; 34919585STim.Szeto@Sun.COM 34929585STim.Szeto@Sun.COM if (groupList == NULL) { 34939585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 34949585STim.Szeto@Sun.COM } 34959585STim.Szeto@Sun.COM 34969585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 34979585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_LIST; 34989585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 34999585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_LIST; 35009585STim.Szeto@Sun.COM } else { 35019585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 35029585STim.Szeto@Sun.COM } 35039585STim.Szeto@Sun.COM 35049585STim.Szeto@Sun.COM /* call init */ 35059585STim.Szeto@Sun.COM ret = initializeConfig(); 35069585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 35079585STim.Szeto@Sun.COM return (ret); 35089585STim.Szeto@Sun.COM } 35099585STim.Szeto@Sun.COM 35109585STim.Szeto@Sun.COM /* 35119585STim.Szeto@Sun.COM * Open control node for stmf 35129585STim.Szeto@Sun.COM */ 35139585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 35149585STim.Szeto@Sun.COM return (ret); 35159585STim.Szeto@Sun.COM 35169585STim.Szeto@Sun.COM /* 35179585STim.Szeto@Sun.COM * Allocate ioctl input buffer 35189585STim.Szeto@Sun.COM */ 35199585STim.Szeto@Sun.COM groupListSize = ALLOC_GROUP; 35209585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_group_name_t)); 35219585STim.Szeto@Sun.COM iGroupList = (stmf_group_name_t *)calloc(1, groupListSize); 35229585STim.Szeto@Sun.COM if (iGroupList == NULL) { 35239585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 35249585STim.Szeto@Sun.COM goto done; 35259585STim.Szeto@Sun.COM } 35269585STim.Szeto@Sun.COM 35279585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 35289585STim.Szeto@Sun.COM /* 35299585STim.Szeto@Sun.COM * Issue ioctl to get the group list 35309585STim.Szeto@Sun.COM */ 35319585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 35329585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 35339585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 35349585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35359585STim.Szeto@Sun.COM if (ioctlRet != 0) { 35369585STim.Szeto@Sun.COM switch (errno) { 35379585STim.Szeto@Sun.COM case EBUSY: 35389585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 35399585STim.Szeto@Sun.COM break; 35409585STim.Szeto@Sun.COM case EPERM: 35419585STim.Szeto@Sun.COM case EACCES: 35429585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 35439585STim.Szeto@Sun.COM break; 35449585STim.Szeto@Sun.COM default: 35459585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 35469585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 35479585STim.Szeto@Sun.COM errno); 35489585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 35499585STim.Szeto@Sun.COM break; 35509585STim.Szeto@Sun.COM } 35519585STim.Szeto@Sun.COM goto done; 35529585STim.Szeto@Sun.COM } 35539585STim.Szeto@Sun.COM /* 35549585STim.Szeto@Sun.COM * Check whether input buffer was large enough 35559585STim.Szeto@Sun.COM */ 35569585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) { 35579585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 35589585STim.Szeto@Sun.COM sizeof (stmf_group_name_t); 35599585STim.Szeto@Sun.COM iGroupList = realloc(iGroupList, groupListSize); 35609585STim.Szeto@Sun.COM if (iGroupList == NULL) { 35619585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 35629585STim.Szeto@Sun.COM goto done; 35639585STim.Szeto@Sun.COM } 35649585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 35659585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 35669585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35679585STim.Szeto@Sun.COM if (ioctlRet != 0) { 35689585STim.Szeto@Sun.COM switch (errno) { 35699585STim.Szeto@Sun.COM case EBUSY: 35709585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 35719585STim.Szeto@Sun.COM break; 35729585STim.Szeto@Sun.COM case EPERM: 35739585STim.Szeto@Sun.COM case EACCES: 35749585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 35759585STim.Szeto@Sun.COM break; 35769585STim.Szeto@Sun.COM default: 35779585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 35789585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 35799585STim.Szeto@Sun.COM errno); 35809585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 35819585STim.Szeto@Sun.COM break; 35829585STim.Szeto@Sun.COM } 35839585STim.Szeto@Sun.COM goto done; 35849585STim.Szeto@Sun.COM } 35859585STim.Szeto@Sun.COM } 35869585STim.Szeto@Sun.COM 35879585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 358810236SSrivijitha.Dugganapalli@Sun.COM *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) + 358910236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries); 35909585STim.Szeto@Sun.COM if (*groupList == NULL) { 35919585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 35929585STim.Szeto@Sun.COM goto done; 35939585STim.Szeto@Sun.COM } 35949585STim.Szeto@Sun.COM (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries; 35959585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 359610113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupList[i].name, (*groupList)->name[i], 35979585STim.Szeto@Sun.COM sizeof (stmfGroupName)); 35989585STim.Szeto@Sun.COM } 35999585STim.Szeto@Sun.COM 36009585STim.Szeto@Sun.COM done: 36019585STim.Szeto@Sun.COM free(iGroupList); 36029585STim.Szeto@Sun.COM (void) close(fd); 36039585STim.Szeto@Sun.COM return (ret); 36049585STim.Szeto@Sun.COM } 36059585STim.Szeto@Sun.COM 36069585STim.Szeto@Sun.COM /* 36079585STim.Szeto@Sun.COM * get host group members, target group members from stmf 36089585STim.Szeto@Sun.COM * 36099585STim.Szeto@Sun.COM * groupProps - allocated on success 36109585STim.Szeto@Sun.COM * 36119585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 36129585STim.Szeto@Sun.COM */ 36139585STim.Szeto@Sun.COM static int 36149585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps, 36159585STim.Szeto@Sun.COM int groupType) 36167836SJohn.Forte@Sun.COM { 36177836SJohn.Forte@Sun.COM int ret; 36189585STim.Szeto@Sun.COM int fd; 36199585STim.Szeto@Sun.COM int ioctlRet; 36209585STim.Szeto@Sun.COM int i; 36219585STim.Szeto@Sun.COM int cmd; 36229585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 36239585STim.Szeto@Sun.COM /* framework group list */ 36249585STim.Szeto@Sun.COM stmf_group_name_t iGroupName; 36259585STim.Szeto@Sun.COM stmf_ge_ident_t *iGroupMembers; 36269585STim.Szeto@Sun.COM uint32_t groupListSize; 36279585STim.Szeto@Sun.COM 36289585STim.Szeto@Sun.COM if (groupName == NULL) { 36299585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 36309585STim.Szeto@Sun.COM } 36319585STim.Szeto@Sun.COM 36329585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 36339585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_ENTRIES; 36349585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 36359585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_ENTRIES; 36369585STim.Szeto@Sun.COM } else { 36377836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36387836SJohn.Forte@Sun.COM } 36397836SJohn.Forte@Sun.COM 36409585STim.Szeto@Sun.COM /* call init */ 36419585STim.Szeto@Sun.COM ret = initializeConfig(); 36429585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 36439585STim.Szeto@Sun.COM return (ret); 36449585STim.Szeto@Sun.COM } 36459585STim.Szeto@Sun.COM 36469585STim.Szeto@Sun.COM /* 36479585STim.Szeto@Sun.COM * Open control node for stmf 36489585STim.Szeto@Sun.COM */ 36499585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 36509585STim.Szeto@Sun.COM return (ret); 36519585STim.Szeto@Sun.COM 36529585STim.Szeto@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 36539585STim.Szeto@Sun.COM 36549585STim.Szeto@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 36559585STim.Szeto@Sun.COM 36569585STim.Szeto@Sun.COM iGroupName.name_size = strlen((char *)groupName); 36579585STim.Szeto@Sun.COM 36589585STim.Szeto@Sun.COM /* 36599585STim.Szeto@Sun.COM * Allocate ioctl input buffer 36609585STim.Szeto@Sun.COM */ 36619585STim.Szeto@Sun.COM groupListSize = ALLOC_GRP_MEMBER; 36629585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_ge_ident_t)); 36639585STim.Szeto@Sun.COM iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize); 36649585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 36659585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 36669585STim.Szeto@Sun.COM goto done; 36679585STim.Szeto@Sun.COM } 36689585STim.Szeto@Sun.COM 36699585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 36709585STim.Szeto@Sun.COM /* 36719585STim.Szeto@Sun.COM * Issue ioctl to get the group list 36729585STim.Szeto@Sun.COM */ 36739585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 36749585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 36759585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 36769585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 36779585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 36789585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 36799585STim.Szeto@Sun.COM if (ioctlRet != 0) { 36809585STim.Szeto@Sun.COM switch (errno) { 36819585STim.Szeto@Sun.COM case EBUSY: 36829585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 36839585STim.Szeto@Sun.COM break; 36849585STim.Szeto@Sun.COM case EPERM: 36859585STim.Szeto@Sun.COM case EACCES: 36869585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 36879585STim.Szeto@Sun.COM break; 36889585STim.Szeto@Sun.COM default: 36899585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 36909585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 36919585STim.Szeto@Sun.COM errno); 36929585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 36939585STim.Szeto@Sun.COM break; 36949585STim.Szeto@Sun.COM } 36959585STim.Szeto@Sun.COM goto done; 36969585STim.Szeto@Sun.COM } 36979585STim.Szeto@Sun.COM /* 36989585STim.Szeto@Sun.COM * Check whether input buffer was large enough 36999585STim.Szeto@Sun.COM */ 37009585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) { 37019585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 37029585STim.Szeto@Sun.COM sizeof (stmf_ge_ident_t); 37039585STim.Szeto@Sun.COM iGroupMembers = realloc(iGroupMembers, groupListSize); 37049585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 37059585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37069585STim.Szeto@Sun.COM goto done; 37079585STim.Szeto@Sun.COM } 37089585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 37099585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 37109585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 37119585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 37129585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 37139585STim.Szeto@Sun.COM if (ioctlRet != 0) { 37149585STim.Szeto@Sun.COM switch (errno) { 37159585STim.Szeto@Sun.COM case EBUSY: 37169585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 37179585STim.Szeto@Sun.COM break; 37189585STim.Szeto@Sun.COM case EPERM: 37199585STim.Szeto@Sun.COM case EACCES: 37209585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 37219585STim.Szeto@Sun.COM break; 37229585STim.Szeto@Sun.COM default: 37239585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 37249585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 37259585STim.Szeto@Sun.COM errno); 37269585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 37279585STim.Szeto@Sun.COM break; 37289585STim.Szeto@Sun.COM } 37299585STim.Szeto@Sun.COM goto done; 37309585STim.Szeto@Sun.COM } 37319585STim.Szeto@Sun.COM } 37329585STim.Szeto@Sun.COM 37339585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 37349585STim.Szeto@Sun.COM *groupProps = (stmfGroupProperties *)calloc(1, 373510236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupProperties) + 373610236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries); 37379585STim.Szeto@Sun.COM if (*groupProps == NULL) { 37389585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37399585STim.Szeto@Sun.COM goto done; 37409585STim.Szeto@Sun.COM } 37419585STim.Szeto@Sun.COM (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries; 37429585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 37439585STim.Szeto@Sun.COM (*groupProps)->name[i].identLength = 374410113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size; 374510113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident, 374610113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size); 37479585STim.Szeto@Sun.COM } 37489585STim.Szeto@Sun.COM 37499585STim.Szeto@Sun.COM done: 37509585STim.Szeto@Sun.COM free(iGroupMembers); 37519585STim.Szeto@Sun.COM (void) close(fd); 37529585STim.Szeto@Sun.COM return (ret); 37539585STim.Szeto@Sun.COM } 37549585STim.Szeto@Sun.COM 37559585STim.Szeto@Sun.COM /* 37569585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 37579585STim.Szeto@Sun.COM */ 37589585STim.Szeto@Sun.COM static int 37599585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type) 37609585STim.Szeto@Sun.COM { 37619585STim.Szeto@Sun.COM int ret; 37629585STim.Szeto@Sun.COM 37639585STim.Szeto@Sun.COM if (groupList == NULL) { 37649585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 37659585STim.Szeto@Sun.COM } 37669585STim.Szeto@Sun.COM 37679585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 37689585STim.Szeto@Sun.COM ret = psGetHostGroupList(groupList); 37699585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 37709585STim.Szeto@Sun.COM ret = psGetTargetGroupList(groupList); 37719585STim.Szeto@Sun.COM } else { 37729585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 37739585STim.Szeto@Sun.COM } 37747836SJohn.Forte@Sun.COM switch (ret) { 37757836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 37767836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 37777836SJohn.Forte@Sun.COM break; 37787836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 37797836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 37807836SJohn.Forte@Sun.COM break; 37817836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 37827836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37837836SJohn.Forte@Sun.COM break; 37847836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 37857836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 37867836SJohn.Forte@Sun.COM break; 37877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 37887836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 37897836SJohn.Forte@Sun.COM break; 37907836SJohn.Forte@Sun.COM default: 37917836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37927836SJohn.Forte@Sun.COM "stmfGetHostGroupList:psGetHostGroupList:error(%d)", 37937836SJohn.Forte@Sun.COM ret); 37947836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37957836SJohn.Forte@Sun.COM break; 37967836SJohn.Forte@Sun.COM } 37977836SJohn.Forte@Sun.COM 37987836SJohn.Forte@Sun.COM return (ret); 37997836SJohn.Forte@Sun.COM } 38007836SJohn.Forte@Sun.COM 38017836SJohn.Forte@Sun.COM /* 38029585STim.Szeto@Sun.COM * stmfGetHostGroupList 38037836SJohn.Forte@Sun.COM * 38049585STim.Szeto@Sun.COM * Purpose: Retrieves the list of initiator group oids 38059585STim.Szeto@Sun.COM * 38069585STim.Szeto@Sun.COM * hostGroupList - pointer to pointer to hostGroupList structure 38079585STim.Szeto@Sun.COM * on success, this contains the host group list. 38087836SJohn.Forte@Sun.COM */ 38097836SJohn.Forte@Sun.COM int 38109585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList) 38119585STim.Szeto@Sun.COM { 38129585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 38139585STim.Szeto@Sun.COM 38149585STim.Szeto@Sun.COM if (hostGroupList == NULL) { 38159585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 38169585STim.Szeto@Sun.COM } 38179585STim.Szeto@Sun.COM 38189585STim.Szeto@Sun.COM ret = groupListIoctl(hostGroupList, HOST_GROUP); 38199585STim.Szeto@Sun.COM return (ret); 38209585STim.Szeto@Sun.COM } 38219585STim.Szeto@Sun.COM 38229585STim.Szeto@Sun.COM 38239585STim.Szeto@Sun.COM /* 38249585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 38259585STim.Szeto@Sun.COM */ 38269585STim.Szeto@Sun.COM static int 38279585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName, 38289585STim.Szeto@Sun.COM stmfGroupProperties **groupProp, int type) 38297836SJohn.Forte@Sun.COM { 38307836SJohn.Forte@Sun.COM int ret; 38317836SJohn.Forte@Sun.COM 38329585STim.Szeto@Sun.COM if (groupName == NULL) { 38337836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38347836SJohn.Forte@Sun.COM } 38357836SJohn.Forte@Sun.COM 38369585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 38379585STim.Szeto@Sun.COM ret = psGetHostGroupMemberList((char *)groupName, groupProp); 38389585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 38399585STim.Szeto@Sun.COM ret = psGetTargetGroupMemberList((char *)groupName, groupProp); 38409585STim.Szeto@Sun.COM } else { 38419585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 38429585STim.Szeto@Sun.COM } 38437836SJohn.Forte@Sun.COM switch (ret) { 38447836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 38457836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 38467836SJohn.Forte@Sun.COM break; 38477836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 38487836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 38497836SJohn.Forte@Sun.COM break; 38507836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 38517836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 38527836SJohn.Forte@Sun.COM break; 38537836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 38547836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 38557836SJohn.Forte@Sun.COM break; 38567836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 38577836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 38587836SJohn.Forte@Sun.COM break; 38597836SJohn.Forte@Sun.COM default: 38607836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 38619585STim.Szeto@Sun.COM "iLoadGroupMembersFromPs:psGetHostGroupList:" 38629585STim.Szeto@Sun.COM "error(%d)", ret); 38637836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 38647836SJohn.Forte@Sun.COM break; 38657836SJohn.Forte@Sun.COM } 38667836SJohn.Forte@Sun.COM 38677836SJohn.Forte@Sun.COM return (ret); 38687836SJohn.Forte@Sun.COM } 38697836SJohn.Forte@Sun.COM 38707836SJohn.Forte@Sun.COM /* 38719585STim.Szeto@Sun.COM * stmfGetHostGroupMembers 38729585STim.Szeto@Sun.COM * 38739585STim.Szeto@Sun.COM * Purpose: Retrieves the group properties for a host group 38749585STim.Szeto@Sun.COM * 38759585STim.Szeto@Sun.COM * groupName - name of group for which to retrieve host group members. 38769585STim.Szeto@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 38779585STim.Szeto@Sun.COM * on success, this contains the list of group members. 38789585STim.Szeto@Sun.COM */ 38799585STim.Szeto@Sun.COM int 38809585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName, 38819585STim.Szeto@Sun.COM stmfGroupProperties **groupProp) 38829585STim.Szeto@Sun.COM { 38839585STim.Szeto@Sun.COM int ret; 38849585STim.Szeto@Sun.COM 38859585STim.Szeto@Sun.COM if (groupName == NULL || groupProp == NULL) { 38869585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 38879585STim.Szeto@Sun.COM } 38889585STim.Szeto@Sun.COM 38899585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP); 38909585STim.Szeto@Sun.COM 38919585STim.Szeto@Sun.COM return (ret); 38929585STim.Szeto@Sun.COM } 38939585STim.Szeto@Sun.COM 38949585STim.Szeto@Sun.COM /* 38957836SJohn.Forte@Sun.COM * stmfGetProviderData 38967836SJohn.Forte@Sun.COM * 38977836SJohn.Forte@Sun.COM * Purpose: Get provider data list 38987836SJohn.Forte@Sun.COM * 38997836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 39007836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 39017836SJohn.Forte@Sun.COM * retrieved. 39027836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 39037836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 39047836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 39057836SJohn.Forte@Sun.COM */ 39067836SJohn.Forte@Sun.COM int 39077836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType) 39087836SJohn.Forte@Sun.COM { 39097836SJohn.Forte@Sun.COM return (stmfGetProviderDataProt(providerName, nvl, providerType, 39107836SJohn.Forte@Sun.COM NULL)); 39117836SJohn.Forte@Sun.COM } 39127836SJohn.Forte@Sun.COM 39137836SJohn.Forte@Sun.COM /* 39147836SJohn.Forte@Sun.COM * stmfGetProviderDataProt 39157836SJohn.Forte@Sun.COM * 39167836SJohn.Forte@Sun.COM * Purpose: Get provider data list with token 39177836SJohn.Forte@Sun.COM * 39187836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 39197836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 39207836SJohn.Forte@Sun.COM * retrieved. 39217836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 39227836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 39237836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 39247836SJohn.Forte@Sun.COM * setToken - Returns the stale data token 39257836SJohn.Forte@Sun.COM */ 39267836SJohn.Forte@Sun.COM int 39277836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType, 39287836SJohn.Forte@Sun.COM uint64_t *setToken) 39297836SJohn.Forte@Sun.COM { 39307836SJohn.Forte@Sun.COM int ret; 39317836SJohn.Forte@Sun.COM 39327836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 39337836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39347836SJohn.Forte@Sun.COM } 39357836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 39367836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 39377836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39387836SJohn.Forte@Sun.COM } 39397836SJohn.Forte@Sun.COM /* call init */ 39407836SJohn.Forte@Sun.COM ret = initializeConfig(); 39417836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39427836SJohn.Forte@Sun.COM return (ret); 39437836SJohn.Forte@Sun.COM } 39449585STim.Szeto@Sun.COM return (getProviderData(providerName, nvl, providerType, setToken)); 39457836SJohn.Forte@Sun.COM } 39467836SJohn.Forte@Sun.COM 39477836SJohn.Forte@Sun.COM /* 39487836SJohn.Forte@Sun.COM * stmfGetProviderDataList 39497836SJohn.Forte@Sun.COM * 39507836SJohn.Forte@Sun.COM * Purpose: Get the list of providers currently persisting data 39517836SJohn.Forte@Sun.COM * 39527836SJohn.Forte@Sun.COM * providerList - pointer to pointer to an stmfProviderList structure allocated 39537836SJohn.Forte@Sun.COM * by the caller. Will contain the list of providers on success. 39547836SJohn.Forte@Sun.COM */ 39557836SJohn.Forte@Sun.COM int 39567836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList) 39577836SJohn.Forte@Sun.COM { 39587836SJohn.Forte@Sun.COM int ret; 39597836SJohn.Forte@Sun.COM 39607836SJohn.Forte@Sun.COM ret = psGetProviderDataList(providerList); 39617836SJohn.Forte@Sun.COM switch (ret) { 39627836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 39637836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 39647836SJohn.Forte@Sun.COM break; 39657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 39667836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39677836SJohn.Forte@Sun.COM break; 39687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 39697836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 39707836SJohn.Forte@Sun.COM break; 39717836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 39727836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 39737836SJohn.Forte@Sun.COM break; 39747836SJohn.Forte@Sun.COM default: 39757836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39767836SJohn.Forte@Sun.COM "stmfGetProviderDataList:psGetProviderDataList" 39777836SJohn.Forte@Sun.COM ":error(%d)", ret); 39787836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39797836SJohn.Forte@Sun.COM break; 39807836SJohn.Forte@Sun.COM } 39817836SJohn.Forte@Sun.COM 39827836SJohn.Forte@Sun.COM return (ret); 39837836SJohn.Forte@Sun.COM } 39847836SJohn.Forte@Sun.COM 39857836SJohn.Forte@Sun.COM 39867836SJohn.Forte@Sun.COM /* 39877836SJohn.Forte@Sun.COM * stmfGetSessionList 39887836SJohn.Forte@Sun.COM * 39897836SJohn.Forte@Sun.COM * Purpose: Retrieves the session list for a target (devid) 39907836SJohn.Forte@Sun.COM * 39917836SJohn.Forte@Sun.COM * devid - devid of target for which to retrieve session information. 39927836SJohn.Forte@Sun.COM * sessionList - pointer to pointer to stmfSessionList structure 39937836SJohn.Forte@Sun.COM * on success, this contains the list of initiator sessions. 39947836SJohn.Forte@Sun.COM */ 39957836SJohn.Forte@Sun.COM int 39967836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList) 39977836SJohn.Forte@Sun.COM { 39987836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 39997836SJohn.Forte@Sun.COM int fd; 40007836SJohn.Forte@Sun.COM int ioctlRet; 40017836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_SESSION_LIST; 40027836SJohn.Forte@Sun.COM int i; 40037836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 400410261SCharles.Ting@Sun.COM slist_scsi_session_t *fSessionList, *fSessionListP = NULL; 40057836SJohn.Forte@Sun.COM uint8_t ident[260]; 40067836SJohn.Forte@Sun.COM uint32_t fSessionListSize; 40077836SJohn.Forte@Sun.COM 40087836SJohn.Forte@Sun.COM if (sessionList == NULL || devid == NULL) { 40097836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 40107836SJohn.Forte@Sun.COM } 40117836SJohn.Forte@Sun.COM 40127836SJohn.Forte@Sun.COM /* call init */ 40137836SJohn.Forte@Sun.COM ret = initializeConfig(); 40147836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 40157836SJohn.Forte@Sun.COM return (ret); 40167836SJohn.Forte@Sun.COM } 40177836SJohn.Forte@Sun.COM 40187836SJohn.Forte@Sun.COM /* 40197836SJohn.Forte@Sun.COM * Open control node for stmf 40207836SJohn.Forte@Sun.COM */ 40217836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 40227836SJohn.Forte@Sun.COM return (ret); 40237836SJohn.Forte@Sun.COM 40247836SJohn.Forte@Sun.COM /* 40257836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 40267836SJohn.Forte@Sun.COM */ 40279585STim.Szeto@Sun.COM fSessionListSize = ALLOC_SESSION; 40287836SJohn.Forte@Sun.COM fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t)); 40297836SJohn.Forte@Sun.COM fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize); 403010261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 40317836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 403210261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 403310261SCharles.Ting@Sun.COM goto done; 40347836SJohn.Forte@Sun.COM } 40357836SJohn.Forte@Sun.COM 40367836SJohn.Forte@Sun.COM ident[IDENT_LENGTH_BYTE] = devid->identLength; 40377836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1], 40387836SJohn.Forte@Sun.COM devid->identLength); 40397836SJohn.Forte@Sun.COM 40407836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 40417836SJohn.Forte@Sun.COM /* 40427836SJohn.Forte@Sun.COM * Issue ioctl to get the session list 40437836SJohn.Forte@Sun.COM */ 40447836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 40457836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident; 40467836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ident); 40477836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 40487836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 40497836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40507836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40517836SJohn.Forte@Sun.COM switch (errno) { 40527836SJohn.Forte@Sun.COM case EBUSY: 40537836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40547836SJohn.Forte@Sun.COM break; 40559585STim.Szeto@Sun.COM case EPERM: 40567836SJohn.Forte@Sun.COM case EACCES: 40577836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40587836SJohn.Forte@Sun.COM break; 40597836SJohn.Forte@Sun.COM default: 40607836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40617836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl errno(%d)", 40627836SJohn.Forte@Sun.COM errno); 40637836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40647836SJohn.Forte@Sun.COM break; 40657836SJohn.Forte@Sun.COM } 40667836SJohn.Forte@Sun.COM goto done; 40677836SJohn.Forte@Sun.COM } 40687836SJohn.Forte@Sun.COM /* 40697836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 40707836SJohn.Forte@Sun.COM */ 40719585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) { 40727836SJohn.Forte@Sun.COM fSessionListSize = stmfIoctl.stmf_obuf_max_nentries * 40737836SJohn.Forte@Sun.COM sizeof (slist_scsi_session_t); 40747836SJohn.Forte@Sun.COM fSessionList = realloc(fSessionList, fSessionListSize); 40757836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 407610261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 407710261SCharles.Ting@Sun.COM goto done; 40787836SJohn.Forte@Sun.COM } 407910261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 40807836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 40817836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 40827836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40837836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40847836SJohn.Forte@Sun.COM switch (errno) { 40857836SJohn.Forte@Sun.COM case EBUSY: 40867836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40877836SJohn.Forte@Sun.COM break; 40889585STim.Szeto@Sun.COM case EPERM: 40897836SJohn.Forte@Sun.COM case EACCES: 40907836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40917836SJohn.Forte@Sun.COM break; 40927836SJohn.Forte@Sun.COM default: 40937836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40947836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl " 40957836SJohn.Forte@Sun.COM "errno(%d)", errno); 40967836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40977836SJohn.Forte@Sun.COM break; 40987836SJohn.Forte@Sun.COM } 40997836SJohn.Forte@Sun.COM goto done; 41007836SJohn.Forte@Sun.COM } 41017836SJohn.Forte@Sun.COM } 41027836SJohn.Forte@Sun.COM 41037836SJohn.Forte@Sun.COM /* 41047836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 41057836SJohn.Forte@Sun.COM */ 41067836SJohn.Forte@Sun.COM *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) + 41077836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession)); 41087836SJohn.Forte@Sun.COM if (*sessionList == NULL) { 41097836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 41107836SJohn.Forte@Sun.COM free(sessionList); 41117836SJohn.Forte@Sun.COM goto done; 41127836SJohn.Forte@Sun.COM } 41137836SJohn.Forte@Sun.COM 41147836SJohn.Forte@Sun.COM (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 41157836SJohn.Forte@Sun.COM 41167836SJohn.Forte@Sun.COM /* 41177836SJohn.Forte@Sun.COM * copy session info to caller's buffer 41187836SJohn.Forte@Sun.COM */ 41197836SJohn.Forte@Sun.COM for (i = 0; i < (*sessionList)->cnt; i++) { 41207836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.identLength = 41217836SJohn.Forte@Sun.COM fSessionList->initiator[IDENT_LENGTH_BYTE]; 41227836SJohn.Forte@Sun.COM bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]), 41237836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.ident, 41247836SJohn.Forte@Sun.COM STMF_IDENT_LENGTH); 41257836SJohn.Forte@Sun.COM bcopy(&(fSessionList->alias), 41267836SJohn.Forte@Sun.COM &((*sessionList)->session[i].alias), 41277836SJohn.Forte@Sun.COM sizeof ((*sessionList)->session[i].alias)); 41287836SJohn.Forte@Sun.COM bcopy(&(fSessionList++->creation_time), 41297836SJohn.Forte@Sun.COM &((*sessionList)->session[i].creationTime), 41307836SJohn.Forte@Sun.COM sizeof (time_t)); 41317836SJohn.Forte@Sun.COM } 41327836SJohn.Forte@Sun.COM done: 41337836SJohn.Forte@Sun.COM (void) close(fd); 413410261SCharles.Ting@Sun.COM free(fSessionListP); 41357836SJohn.Forte@Sun.COM return (ret); 41367836SJohn.Forte@Sun.COM } 41377836SJohn.Forte@Sun.COM 41387836SJohn.Forte@Sun.COM /* 41397836SJohn.Forte@Sun.COM * stmfGetTargetGroupList 41407836SJohn.Forte@Sun.COM * 41417836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target groups 41427836SJohn.Forte@Sun.COM * 41437836SJohn.Forte@Sun.COM * targetGroupList - pointer to a pointer to an stmfGroupList structure. On 41447836SJohn.Forte@Sun.COM * success, it contains the list of target groups. 41457836SJohn.Forte@Sun.COM */ 41467836SJohn.Forte@Sun.COM int 41477836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList) 41487836SJohn.Forte@Sun.COM { 41497836SJohn.Forte@Sun.COM int ret; 41507836SJohn.Forte@Sun.COM 41517836SJohn.Forte@Sun.COM if (targetGroupList == NULL) { 41527836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41537836SJohn.Forte@Sun.COM } 41547836SJohn.Forte@Sun.COM 41559585STim.Szeto@Sun.COM ret = groupListIoctl(targetGroupList, TARGET_GROUP); 41567836SJohn.Forte@Sun.COM return (ret); 41577836SJohn.Forte@Sun.COM } 41587836SJohn.Forte@Sun.COM 41597836SJohn.Forte@Sun.COM /* 41607836SJohn.Forte@Sun.COM * stmfGetTargetGroupMembers 41617836SJohn.Forte@Sun.COM * 41627836SJohn.Forte@Sun.COM * Purpose: Retrieves the group members for a target group 41637836SJohn.Forte@Sun.COM * 41647836SJohn.Forte@Sun.COM * groupName - name of target group for which to retrieve members. 41657836SJohn.Forte@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 41667836SJohn.Forte@Sun.COM * on success, this contains the list of group members. 41677836SJohn.Forte@Sun.COM */ 41687836SJohn.Forte@Sun.COM int 41697836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName, 41707836SJohn.Forte@Sun.COM stmfGroupProperties **groupProp) 41717836SJohn.Forte@Sun.COM { 41727836SJohn.Forte@Sun.COM int ret; 41737836SJohn.Forte@Sun.COM 41747836SJohn.Forte@Sun.COM if (groupName == NULL || groupProp == NULL) { 41757836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41767836SJohn.Forte@Sun.COM } 41777836SJohn.Forte@Sun.COM 41789585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP); 41797836SJohn.Forte@Sun.COM 41807836SJohn.Forte@Sun.COM return (ret); 41817836SJohn.Forte@Sun.COM } 41827836SJohn.Forte@Sun.COM 41837836SJohn.Forte@Sun.COM /* 41847836SJohn.Forte@Sun.COM * stmfGetTargetList 41857836SJohn.Forte@Sun.COM * 41867836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target ports 41877836SJohn.Forte@Sun.COM * 41887836SJohn.Forte@Sun.COM * targetList - pointer to a pointer to an stmfDevidList structure. 41897836SJohn.Forte@Sun.COM * On success, it contains the list of local ports (target). 41907836SJohn.Forte@Sun.COM */ 41917836SJohn.Forte@Sun.COM int 41927836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList) 41937836SJohn.Forte@Sun.COM { 41947836SJohn.Forte@Sun.COM int ret; 41957836SJohn.Forte@Sun.COM int fd; 41967836SJohn.Forte@Sun.COM int ioctlRet; 41977836SJohn.Forte@Sun.COM int i; 41987836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 41997836SJohn.Forte@Sun.COM /* framework target port list */ 42009585STim.Szeto@Sun.COM slist_target_port_t *fTargetList, *fTargetListP = NULL; 42017836SJohn.Forte@Sun.COM uint32_t fTargetListSize; 42027836SJohn.Forte@Sun.COM 42037836SJohn.Forte@Sun.COM if (targetList == NULL) { 42047836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 42057836SJohn.Forte@Sun.COM } 42067836SJohn.Forte@Sun.COM 42077836SJohn.Forte@Sun.COM /* call init */ 42087836SJohn.Forte@Sun.COM ret = initializeConfig(); 42097836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42107836SJohn.Forte@Sun.COM return (ret); 42117836SJohn.Forte@Sun.COM } 42127836SJohn.Forte@Sun.COM 42137836SJohn.Forte@Sun.COM /* 42147836SJohn.Forte@Sun.COM * Open control node for stmf 42157836SJohn.Forte@Sun.COM */ 42167836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 42177836SJohn.Forte@Sun.COM return (ret); 42187836SJohn.Forte@Sun.COM 42197836SJohn.Forte@Sun.COM /* 42207836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 42217836SJohn.Forte@Sun.COM */ 42229585STim.Szeto@Sun.COM fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t); 42238252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 42248252SJohn.Forte@Sun.COM (slist_target_port_t *)calloc(1, fTargetListSize); 42257836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 42269585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42277836SJohn.Forte@Sun.COM goto done; 42287836SJohn.Forte@Sun.COM } 42297836SJohn.Forte@Sun.COM 42307836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 42317836SJohn.Forte@Sun.COM /* 42328252SJohn.Forte@Sun.COM * Issue ioctl to retrieve target list 42337836SJohn.Forte@Sun.COM */ 42347836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 42357836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 42367836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 42377836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl); 42387836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 42397836SJohn.Forte@Sun.COM switch (errno) { 42407836SJohn.Forte@Sun.COM case EBUSY: 42417836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 42427836SJohn.Forte@Sun.COM break; 42439585STim.Szeto@Sun.COM case EPERM: 42447836SJohn.Forte@Sun.COM case EACCES: 42457836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 42467836SJohn.Forte@Sun.COM break; 42477836SJohn.Forte@Sun.COM default: 42487836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 42497836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", errno); 42507836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 42517836SJohn.Forte@Sun.COM break; 42527836SJohn.Forte@Sun.COM } 42537836SJohn.Forte@Sun.COM goto done; 42547836SJohn.Forte@Sun.COM } 42557836SJohn.Forte@Sun.COM /* 42567836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 42577836SJohn.Forte@Sun.COM */ 42589585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) { 42597836SJohn.Forte@Sun.COM fTargetListSize = stmfIoctl.stmf_obuf_max_nentries * 42608116SJohn.Forte@Sun.COM sizeof (slist_target_port_t); 42618252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 42628252SJohn.Forte@Sun.COM realloc(fTargetList, fTargetListSize); 42637836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 42649585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42659585STim.Szeto@Sun.COM goto done; 42667836SJohn.Forte@Sun.COM } 42677836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 42687836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 42697836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, 42707836SJohn.Forte@Sun.COM &stmfIoctl); 42717836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 42727836SJohn.Forte@Sun.COM switch (errno) { 42737836SJohn.Forte@Sun.COM case EBUSY: 42747836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 42757836SJohn.Forte@Sun.COM break; 42769585STim.Szeto@Sun.COM case EPERM: 42777836SJohn.Forte@Sun.COM case EACCES: 42787836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 42797836SJohn.Forte@Sun.COM break; 42807836SJohn.Forte@Sun.COM default: 42817836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 42827836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", 42837836SJohn.Forte@Sun.COM errno); 42847836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 42857836SJohn.Forte@Sun.COM break; 42867836SJohn.Forte@Sun.COM } 42877836SJohn.Forte@Sun.COM goto done; 42887836SJohn.Forte@Sun.COM } 42897836SJohn.Forte@Sun.COM } 42907836SJohn.Forte@Sun.COM 42917836SJohn.Forte@Sun.COM *targetList = (stmfDevidList *)calloc(1, 42927836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) + 42937836SJohn.Forte@Sun.COM sizeof (stmfDevidList)); 42949585STim.Szeto@Sun.COM if (*targetList == NULL) { 42959585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42969585STim.Szeto@Sun.COM goto done; 42979585STim.Szeto@Sun.COM } 42987836SJohn.Forte@Sun.COM 42997836SJohn.Forte@Sun.COM (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 43007836SJohn.Forte@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) { 43017836SJohn.Forte@Sun.COM (*targetList)->devid[i].identLength = 43027836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]; 43037836SJohn.Forte@Sun.COM bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1], 43047836SJohn.Forte@Sun.COM &(*targetList)->devid[i].ident, 43057836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]); 43067836SJohn.Forte@Sun.COM } 43077836SJohn.Forte@Sun.COM 43087836SJohn.Forte@Sun.COM done: 43097836SJohn.Forte@Sun.COM (void) close(fd); 43108252SJohn.Forte@Sun.COM free(fTargetListP); 43117836SJohn.Forte@Sun.COM return (ret); 43127836SJohn.Forte@Sun.COM } 43137836SJohn.Forte@Sun.COM 43147836SJohn.Forte@Sun.COM /* 43157836SJohn.Forte@Sun.COM * stmfGetTargetProperties 43167836SJohn.Forte@Sun.COM * 43177836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 43187836SJohn.Forte@Sun.COM * 43197836SJohn.Forte@Sun.COM * devid - devid of the target for which to retrieve properties 43207836SJohn.Forte@Sun.COM * targetProps - pointer to an stmfTargetProperties structure. 43217836SJohn.Forte@Sun.COM * On success, it contains the target properties for 43227836SJohn.Forte@Sun.COM * the specified devid. 43237836SJohn.Forte@Sun.COM */ 43247836SJohn.Forte@Sun.COM int 43257836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps) 43267836SJohn.Forte@Sun.COM { 43277836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 43287836SJohn.Forte@Sun.COM int fd; 43297836SJohn.Forte@Sun.COM int ioctlRet; 43307836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 43317836SJohn.Forte@Sun.COM sioc_target_port_props_t targetProperties; 433210725SJohn.Forte@Sun.COM scsi_devid_desc_t *scsiDevid; 43337836SJohn.Forte@Sun.COM 43347836SJohn.Forte@Sun.COM if (devid == NULL || targetProps == NULL) { 43357836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 43367836SJohn.Forte@Sun.COM } 43377836SJohn.Forte@Sun.COM 43387836SJohn.Forte@Sun.COM /* call init */ 43397836SJohn.Forte@Sun.COM ret = initializeConfig(); 43407836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 43417836SJohn.Forte@Sun.COM return (ret); 43427836SJohn.Forte@Sun.COM } 43437836SJohn.Forte@Sun.COM 43447836SJohn.Forte@Sun.COM /* 43457836SJohn.Forte@Sun.COM * Open control node for stmf 43467836SJohn.Forte@Sun.COM */ 43477836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 43487836SJohn.Forte@Sun.COM return (ret); 43497836SJohn.Forte@Sun.COM 43507836SJohn.Forte@Sun.COM targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength; 43517836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1], 43527836SJohn.Forte@Sun.COM devid->identLength); 43537836SJohn.Forte@Sun.COM 43547836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 43557836SJohn.Forte@Sun.COM /* 43567836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 43577836SJohn.Forte@Sun.COM */ 43587836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 43597836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id); 43607836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id; 43617836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties; 43627836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (targetProperties); 43637836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES, 43647836SJohn.Forte@Sun.COM &stmfIoctl); 43657836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 43667836SJohn.Forte@Sun.COM switch (errno) { 43677836SJohn.Forte@Sun.COM case EBUSY: 43687836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 43697836SJohn.Forte@Sun.COM break; 43709585STim.Szeto@Sun.COM case EPERM: 43717836SJohn.Forte@Sun.COM case EACCES: 43727836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 43737836SJohn.Forte@Sun.COM break; 43747836SJohn.Forte@Sun.COM case ENOENT: 43757836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 43767836SJohn.Forte@Sun.COM break; 43777836SJohn.Forte@Sun.COM default: 43787836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 43797836SJohn.Forte@Sun.COM "stmfGetTargetProperties:ioctl errno(%d)", 43807836SJohn.Forte@Sun.COM errno); 43817836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 43827836SJohn.Forte@Sun.COM break; 43837836SJohn.Forte@Sun.COM } 43847836SJohn.Forte@Sun.COM goto done; 43857836SJohn.Forte@Sun.COM } 43867836SJohn.Forte@Sun.COM 43877836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_provider_name, targetProps->providerName, 43887836SJohn.Forte@Sun.COM sizeof (targetProperties.tgt_provider_name)); 43897836SJohn.Forte@Sun.COM if (targetProperties.tgt_state == STMF_STATE_ONLINE) { 43907836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINE; 43917836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) { 43927836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINE; 43937836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) { 43947836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINING; 43957836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) { 43967836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINING; 43977836SJohn.Forte@Sun.COM } 43987836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_alias, targetProps->alias, 43997836SJohn.Forte@Sun.COM sizeof (targetProps->alias)); 440010725SJohn.Forte@Sun.COM 440110725SJohn.Forte@Sun.COM scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id; 440210725SJohn.Forte@Sun.COM targetProps->protocol = scsiDevid->protocol_id; 440310725SJohn.Forte@Sun.COM 44047836SJohn.Forte@Sun.COM done: 44057836SJohn.Forte@Sun.COM (void) close(fd); 44067836SJohn.Forte@Sun.COM return (ret); 44077836SJohn.Forte@Sun.COM } 44087836SJohn.Forte@Sun.COM 44097836SJohn.Forte@Sun.COM /* 44107836SJohn.Forte@Sun.COM * stmfGetLogicalUnitList 44117836SJohn.Forte@Sun.COM * 44127836SJohn.Forte@Sun.COM * Purpose: Retrieves list of logical unit Object IDs 44137836SJohn.Forte@Sun.COM * 44147836SJohn.Forte@Sun.COM * luList - pointer to a pointer to a stmfGuidList structure. On success, 44157836SJohn.Forte@Sun.COM * it contains the list of logical unit guids. 44167836SJohn.Forte@Sun.COM * 44177836SJohn.Forte@Sun.COM */ 44187836SJohn.Forte@Sun.COM int 44197836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList) 44207836SJohn.Forte@Sun.COM { 44217836SJohn.Forte@Sun.COM int ret; 44227836SJohn.Forte@Sun.COM int fd; 44237836SJohn.Forte@Sun.COM int ioctlRet; 44247836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_LU_LIST; 44259585STim.Szeto@Sun.COM int i; 44267836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 44277836SJohn.Forte@Sun.COM slist_lu_t *fLuList; 44287836SJohn.Forte@Sun.COM uint32_t fLuListSize; 44299585STim.Szeto@Sun.COM uint32_t listCnt; 44307836SJohn.Forte@Sun.COM 44317836SJohn.Forte@Sun.COM if (luList == NULL) { 44327836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 44337836SJohn.Forte@Sun.COM } 44347836SJohn.Forte@Sun.COM 44357836SJohn.Forte@Sun.COM /* call init */ 44367836SJohn.Forte@Sun.COM ret = initializeConfig(); 44377836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44387836SJohn.Forte@Sun.COM return (ret); 44397836SJohn.Forte@Sun.COM } 44407836SJohn.Forte@Sun.COM 44417836SJohn.Forte@Sun.COM /* 44427836SJohn.Forte@Sun.COM * Open control node for stmf 44437836SJohn.Forte@Sun.COM */ 44447836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 44457836SJohn.Forte@Sun.COM return (ret); 44467836SJohn.Forte@Sun.COM 44477836SJohn.Forte@Sun.COM /* 44487836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 44497836SJohn.Forte@Sun.COM */ 44509585STim.Szeto@Sun.COM fLuListSize = ALLOC_LU; 44517836SJohn.Forte@Sun.COM fLuListSize = fLuListSize * (sizeof (slist_lu_t)); 44527836SJohn.Forte@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 44537836SJohn.Forte@Sun.COM if (fLuList == NULL) { 44549585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 44559585STim.Szeto@Sun.COM goto done; 44567836SJohn.Forte@Sun.COM } 44577836SJohn.Forte@Sun.COM 44587836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 44597836SJohn.Forte@Sun.COM /* 44607836SJohn.Forte@Sun.COM * Issue ioctl to get the LU list 44617836SJohn.Forte@Sun.COM */ 44627836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 44637836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 44647836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 44657836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 44667836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 44677836SJohn.Forte@Sun.COM switch (errno) { 44687836SJohn.Forte@Sun.COM case EBUSY: 44697836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 44707836SJohn.Forte@Sun.COM break; 44719585STim.Szeto@Sun.COM case EPERM: 44727836SJohn.Forte@Sun.COM case EACCES: 44737836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 44747836SJohn.Forte@Sun.COM break; 44757836SJohn.Forte@Sun.COM default: 44767836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 44777836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:ioctl errno(%d)", 44787836SJohn.Forte@Sun.COM errno); 44797836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 44807836SJohn.Forte@Sun.COM break; 44817836SJohn.Forte@Sun.COM } 44827836SJohn.Forte@Sun.COM goto done; 44837836SJohn.Forte@Sun.COM } 44847836SJohn.Forte@Sun.COM /* 44857836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 44867836SJohn.Forte@Sun.COM */ 44879585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) { 44887836SJohn.Forte@Sun.COM fLuListSize = stmfIoctl.stmf_obuf_max_nentries * 44897836SJohn.Forte@Sun.COM sizeof (slist_lu_t); 44909585STim.Szeto@Sun.COM free(fLuList); 44919585STim.Szeto@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 44927836SJohn.Forte@Sun.COM if (fLuList == NULL) { 44939585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 44949585STim.Szeto@Sun.COM goto done; 44957836SJohn.Forte@Sun.COM } 44967836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 44977836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 44987836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 44997836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 45007836SJohn.Forte@Sun.COM switch (errno) { 45017836SJohn.Forte@Sun.COM case EBUSY: 45027836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45037836SJohn.Forte@Sun.COM break; 45049585STim.Szeto@Sun.COM case EPERM: 45057836SJohn.Forte@Sun.COM case EACCES: 45067836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 45077836SJohn.Forte@Sun.COM break; 45087836SJohn.Forte@Sun.COM default: 45097836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 45107836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:" 45117836SJohn.Forte@Sun.COM "ioctl errno(%d)", errno); 45127836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45137836SJohn.Forte@Sun.COM break; 45147836SJohn.Forte@Sun.COM } 45157836SJohn.Forte@Sun.COM goto done; 45167836SJohn.Forte@Sun.COM } 45177836SJohn.Forte@Sun.COM } 45187836SJohn.Forte@Sun.COM 45197836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45207836SJohn.Forte@Sun.COM goto done; 45217836SJohn.Forte@Sun.COM } 45227836SJohn.Forte@Sun.COM 45239585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 45247836SJohn.Forte@Sun.COM 45257836SJohn.Forte@Sun.COM /* 45267836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 45277836SJohn.Forte@Sun.COM */ 45287836SJohn.Forte@Sun.COM *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) + 45299585STim.Szeto@Sun.COM listCnt * sizeof (stmfGuid)); 45307836SJohn.Forte@Sun.COM if (*luList == NULL) { 45317836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 45327836SJohn.Forte@Sun.COM goto done; 45337836SJohn.Forte@Sun.COM } 45347836SJohn.Forte@Sun.COM 45359585STim.Szeto@Sun.COM (*luList)->cnt = listCnt; 45369585STim.Szeto@Sun.COM 45379585STim.Szeto@Sun.COM /* copy to caller's buffer */ 45389585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 45399585STim.Szeto@Sun.COM bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid, 45409585STim.Szeto@Sun.COM sizeof (stmfGuid)); 45419585STim.Szeto@Sun.COM } 45429585STim.Szeto@Sun.COM 45437836SJohn.Forte@Sun.COM /* 45449585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 45457836SJohn.Forte@Sun.COM */ 45469585STim.Szeto@Sun.COM qsort((void *)&((*luList)->guid[0]), (*luList)->cnt, 45479585STim.Szeto@Sun.COM sizeof (stmfGuid), guidCompare); 45487836SJohn.Forte@Sun.COM 45497836SJohn.Forte@Sun.COM done: 45507836SJohn.Forte@Sun.COM (void) close(fd); 45517836SJohn.Forte@Sun.COM /* 45527836SJohn.Forte@Sun.COM * free internal buffers 45537836SJohn.Forte@Sun.COM */ 45547836SJohn.Forte@Sun.COM free(fLuList); 45557836SJohn.Forte@Sun.COM return (ret); 45567836SJohn.Forte@Sun.COM } 45577836SJohn.Forte@Sun.COM 45587836SJohn.Forte@Sun.COM /* 45597836SJohn.Forte@Sun.COM * stmfGetLogicalUnitProperties 45607836SJohn.Forte@Sun.COM * 45617836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 45627836SJohn.Forte@Sun.COM * 45637836SJohn.Forte@Sun.COM * lu - guid of the logical unit for which to retrieve properties 45647836SJohn.Forte@Sun.COM * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success, 45657836SJohn.Forte@Sun.COM * it contains the logical unit properties for the specified guid. 45667836SJohn.Forte@Sun.COM */ 45677836SJohn.Forte@Sun.COM int 45687836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps) 45697836SJohn.Forte@Sun.COM { 45707836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 45717836SJohn.Forte@Sun.COM int stmfRet; 45727836SJohn.Forte@Sun.COM int fd; 45737836SJohn.Forte@Sun.COM int ioctlRet; 45747836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_GET_LU_PROPERTIES; 45757836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 45767836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 45777836SJohn.Forte@Sun.COM sioc_lu_props_t fLuProps; 45787836SJohn.Forte@Sun.COM 45799585STim.Szeto@Sun.COM if (lu == NULL || luProps == NULL) { 45809585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 45817836SJohn.Forte@Sun.COM } 45827836SJohn.Forte@Sun.COM 45837836SJohn.Forte@Sun.COM bzero(luProps, sizeof (stmfLogicalUnitProperties)); 45847836SJohn.Forte@Sun.COM 45857836SJohn.Forte@Sun.COM /* call init */ 45867836SJohn.Forte@Sun.COM ret = initializeConfig(); 45877836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45887836SJohn.Forte@Sun.COM return (ret); 45897836SJohn.Forte@Sun.COM } 45907836SJohn.Forte@Sun.COM 45917836SJohn.Forte@Sun.COM /* 45927836SJohn.Forte@Sun.COM * Open control node for stmf 45937836SJohn.Forte@Sun.COM */ 45947836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 45957836SJohn.Forte@Sun.COM return (ret); 45967836SJohn.Forte@Sun.COM 45977836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 45987836SJohn.Forte@Sun.COM /* 45997836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 46007836SJohn.Forte@Sun.COM */ 46017836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 46027836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 46037836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 46047836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps; 46057836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (fLuProps); 46067836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 46077836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 46087836SJohn.Forte@Sun.COM switch (errno) { 46097836SJohn.Forte@Sun.COM case EBUSY: 46107836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46117836SJohn.Forte@Sun.COM break; 46129585STim.Szeto@Sun.COM case EPERM: 46137836SJohn.Forte@Sun.COM case EACCES: 46147836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 46157836SJohn.Forte@Sun.COM break; 46167836SJohn.Forte@Sun.COM case ENOENT: 46177836SJohn.Forte@Sun.COM stmfRet = stmfGetViewEntryList(lu, 46187836SJohn.Forte@Sun.COM &viewEntryList); 46197836SJohn.Forte@Sun.COM if (stmfRet == STMF_STATUS_SUCCESS) { 46207836SJohn.Forte@Sun.COM luProps->status = 46217836SJohn.Forte@Sun.COM STMF_LOGICAL_UNIT_UNREGISTERED; 46227836SJohn.Forte@Sun.COM if (viewEntryList->cnt > 0) { 46237836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46247836SJohn.Forte@Sun.COM } else { 46257836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46267836SJohn.Forte@Sun.COM } 46277836SJohn.Forte@Sun.COM } else { 46287836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46297836SJohn.Forte@Sun.COM } 46307836SJohn.Forte@Sun.COM stmfFreeMemory(viewEntryList); 46317836SJohn.Forte@Sun.COM break; 46327836SJohn.Forte@Sun.COM default: 46337836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 46347836SJohn.Forte@Sun.COM "stmfGetLogicalUnit:ioctl errno(%d)", 46357836SJohn.Forte@Sun.COM errno); 46367836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46377836SJohn.Forte@Sun.COM break; 46387836SJohn.Forte@Sun.COM } 46397836SJohn.Forte@Sun.COM goto done; 46407836SJohn.Forte@Sun.COM } 46417836SJohn.Forte@Sun.COM 46427836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_provider_name, luProps->providerName, 46437836SJohn.Forte@Sun.COM sizeof (fLuProps.lu_provider_name)); 46447836SJohn.Forte@Sun.COM if (fLuProps.lu_state == STMF_STATE_ONLINE) { 46457836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINE; 46467836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) { 46477836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINE; 46487836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_ONLINING) { 46497836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINING; 46507836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) { 46517836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINING; 46527836SJohn.Forte@Sun.COM } 46537836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias)); 46547836SJohn.Forte@Sun.COM done: 46557836SJohn.Forte@Sun.COM (void) close(fd); 46567836SJohn.Forte@Sun.COM return (ret); 46577836SJohn.Forte@Sun.COM } 46587836SJohn.Forte@Sun.COM 46597836SJohn.Forte@Sun.COM /* 46607836SJohn.Forte@Sun.COM * stmfGetState 46617836SJohn.Forte@Sun.COM * 46627836SJohn.Forte@Sun.COM * Purpose: retrieve the current state of the stmf module 46637836SJohn.Forte@Sun.COM * 46647836SJohn.Forte@Sun.COM * state - pointer to stmfState structure allocated by the caller 46657836SJohn.Forte@Sun.COM * On success, contains the state of stmf 46667836SJohn.Forte@Sun.COM */ 46677836SJohn.Forte@Sun.COM int 46687836SJohn.Forte@Sun.COM stmfGetState(stmfState *state) 46697836SJohn.Forte@Sun.COM { 46707836SJohn.Forte@Sun.COM int ret; 46717836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 46727836SJohn.Forte@Sun.COM 46737836SJohn.Forte@Sun.COM if (state == NULL) { 46747836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 46757836SJohn.Forte@Sun.COM } 46767836SJohn.Forte@Sun.COM 46777836SJohn.Forte@Sun.COM ret = getStmfState(&iState); 46787836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46797836SJohn.Forte@Sun.COM return (ret); 46807836SJohn.Forte@Sun.COM } 46817836SJohn.Forte@Sun.COM switch (iState.state) { 46827836SJohn.Forte@Sun.COM case STMF_STATE_ONLINE: 46837836SJohn.Forte@Sun.COM state->operationalState = 46847836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINE; 46857836SJohn.Forte@Sun.COM break; 46867836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINE: 46877836SJohn.Forte@Sun.COM state->operationalState = 46887836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINE; 46897836SJohn.Forte@Sun.COM break; 46907836SJohn.Forte@Sun.COM case STMF_STATE_ONLINING: 46917836SJohn.Forte@Sun.COM state->operationalState = 46927836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINING; 46937836SJohn.Forte@Sun.COM break; 46947836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINING: 46957836SJohn.Forte@Sun.COM state->operationalState = 46967836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINING; 46977836SJohn.Forte@Sun.COM break; 46987836SJohn.Forte@Sun.COM default: 46997836SJohn.Forte@Sun.COM state->operationalState = 47007836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_UNKNOWN; 47017836SJohn.Forte@Sun.COM break; 47027836SJohn.Forte@Sun.COM } 47037836SJohn.Forte@Sun.COM switch (iState.config_state) { 47047836SJohn.Forte@Sun.COM case STMF_CONFIG_NONE: 47057836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_NONE; 47067836SJohn.Forte@Sun.COM break; 47077836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT: 47087836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_INIT; 47097836SJohn.Forte@Sun.COM break; 47107836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT_DONE: 47117836SJohn.Forte@Sun.COM state->configState = 47127836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_INIT_DONE; 47137836SJohn.Forte@Sun.COM break; 47147836SJohn.Forte@Sun.COM default: 47157836SJohn.Forte@Sun.COM state->configState = 47167836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_UNKNOWN; 47177836SJohn.Forte@Sun.COM break; 47187836SJohn.Forte@Sun.COM } 47197836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 47207836SJohn.Forte@Sun.COM } 47217836SJohn.Forte@Sun.COM 47227836SJohn.Forte@Sun.COM /* 47237836SJohn.Forte@Sun.COM * stmfGetViewEntryList 47247836SJohn.Forte@Sun.COM * 47257836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of view entries for the specified 47267836SJohn.Forte@Sun.COM * logical unit. 47277836SJohn.Forte@Sun.COM * 47287836SJohn.Forte@Sun.COM * lu - the guid of the logical unit for which to retrieve the view entry list 47297836SJohn.Forte@Sun.COM * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On 47307836SJohn.Forte@Sun.COM * success, contains the list of view entries. 47317836SJohn.Forte@Sun.COM */ 47327836SJohn.Forte@Sun.COM int 47337836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList) 47347836SJohn.Forte@Sun.COM { 47357836SJohn.Forte@Sun.COM int ret; 47369585STim.Szeto@Sun.COM int fd; 47379585STim.Szeto@Sun.COM int ioctlRet; 47389585STim.Szeto@Sun.COM int cmd = STMF_IOCTL_LU_VE_LIST; 47399585STim.Szeto@Sun.COM int i; 47409585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 47419585STim.Szeto@Sun.COM stmf_view_op_entry_t *fVeList; 47429585STim.Szeto@Sun.COM uint32_t fVeListSize; 47439585STim.Szeto@Sun.COM uint32_t listCnt; 47447836SJohn.Forte@Sun.COM 47457836SJohn.Forte@Sun.COM if (lu == NULL || viewEntryList == NULL) { 47467836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 47477836SJohn.Forte@Sun.COM } 47487836SJohn.Forte@Sun.COM 47499585STim.Szeto@Sun.COM /* call init */ 47509585STim.Szeto@Sun.COM ret = initializeConfig(); 47519585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47529585STim.Szeto@Sun.COM return (ret); 47539585STim.Szeto@Sun.COM } 47549585STim.Szeto@Sun.COM 47559585STim.Szeto@Sun.COM /* 47569585STim.Szeto@Sun.COM * Open control node for stmf 47579585STim.Szeto@Sun.COM */ 47589585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 47599585STim.Szeto@Sun.COM return (ret); 47609585STim.Szeto@Sun.COM 47619585STim.Szeto@Sun.COM /* 47629585STim.Szeto@Sun.COM * Allocate ioctl input buffer 47639585STim.Szeto@Sun.COM */ 47649585STim.Szeto@Sun.COM fVeListSize = ALLOC_VE; 47659585STim.Szeto@Sun.COM fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t)); 47669585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 47679585STim.Szeto@Sun.COM if (fVeList == NULL) { 47689585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 47699585STim.Szeto@Sun.COM goto done; 47709585STim.Szeto@Sun.COM } 47719585STim.Szeto@Sun.COM 47729585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 47739585STim.Szeto@Sun.COM /* 47749585STim.Szeto@Sun.COM * Issue ioctl to get the LU list 47759585STim.Szeto@Sun.COM */ 47769585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 47779585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 47789585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 47799585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 47809585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 47819585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 47829585STim.Szeto@Sun.COM if (ioctlRet != 0) { 47839585STim.Szeto@Sun.COM switch (errno) { 47849585STim.Szeto@Sun.COM case EBUSY: 47859585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 47869585STim.Szeto@Sun.COM break; 47879585STim.Szeto@Sun.COM case EPERM: 47889585STim.Szeto@Sun.COM case EACCES: 47899585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 47909585STim.Szeto@Sun.COM break; 47919585STim.Szeto@Sun.COM default: 47929585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 47939585STim.Szeto@Sun.COM "stmfGetViewEntryList:ioctl errno(%d)", 47949585STim.Szeto@Sun.COM errno); 47959585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 47969585STim.Szeto@Sun.COM break; 47979585STim.Szeto@Sun.COM } 47989585STim.Szeto@Sun.COM goto done; 47999585STim.Szeto@Sun.COM } 48009585STim.Szeto@Sun.COM /* 48019585STim.Szeto@Sun.COM * Check whether input buffer was large enough 48029585STim.Szeto@Sun.COM */ 48039585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) { 48049585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 48059585STim.Szeto@Sun.COM fVeListSize = stmfIoctl.stmf_obuf_max_nentries * 48069585STim.Szeto@Sun.COM sizeof (stmf_view_op_entry_t); 48079585STim.Szeto@Sun.COM free(fVeList); 48089585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 48099585STim.Szeto@Sun.COM if (fVeList == NULL) { 48109585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 48119585STim.Szeto@Sun.COM } 48129585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 48139585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 48149585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 48159585STim.Szeto@Sun.COM if (ioctlRet != 0) { 48169585STim.Szeto@Sun.COM switch (errno) { 48179585STim.Szeto@Sun.COM case EBUSY: 48189585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 48199585STim.Szeto@Sun.COM break; 48209585STim.Szeto@Sun.COM case EPERM: 48219585STim.Szeto@Sun.COM case EACCES: 48229585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 48239585STim.Szeto@Sun.COM break; 48249585STim.Szeto@Sun.COM default: 48259585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 48269585STim.Szeto@Sun.COM "stmfGetLogicalUnitList:" 48279585STim.Szeto@Sun.COM "ioctl errno(%d)", errno); 48289585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 48299585STim.Szeto@Sun.COM break; 48309585STim.Szeto@Sun.COM } 48319585STim.Szeto@Sun.COM goto done; 48329585STim.Szeto@Sun.COM } 48339585STim.Szeto@Sun.COM } 48349585STim.Szeto@Sun.COM 48359585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 48369585STim.Szeto@Sun.COM goto done; 48379585STim.Szeto@Sun.COM } 48389585STim.Szeto@Sun.COM 48399585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 48409585STim.Szeto@Sun.COM 48419585STim.Szeto@Sun.COM /* 48429585STim.Szeto@Sun.COM * allocate caller's buffer with the final size 48439585STim.Szeto@Sun.COM */ 48449585STim.Szeto@Sun.COM *viewEntryList = (stmfViewEntryList *)calloc(1, 48459585STim.Szeto@Sun.COM sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry)); 48469585STim.Szeto@Sun.COM if (*viewEntryList == NULL) { 48479585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 48489585STim.Szeto@Sun.COM goto done; 48499585STim.Szeto@Sun.COM } 48509585STim.Szeto@Sun.COM 48519585STim.Szeto@Sun.COM (*viewEntryList)->cnt = listCnt; 48529585STim.Szeto@Sun.COM 48539585STim.Szeto@Sun.COM /* copy to caller's buffer */ 48549585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 48559585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndexValid = B_TRUE; 48569585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx; 48579585STim.Szeto@Sun.COM if (fVeList[i].ve_all_hosts == 1) { 48589585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allHosts = B_TRUE; 48599585STim.Szeto@Sun.COM } else { 48609585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_host_group.name, 48619585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].hostGroup, 48629585STim.Szeto@Sun.COM fVeList[i].ve_host_group.name_size); 48639585STim.Szeto@Sun.COM } 48649585STim.Szeto@Sun.COM if (fVeList[i].ve_all_targets == 1) { 48659585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allTargets = B_TRUE; 48669585STim.Szeto@Sun.COM } else { 48679585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_target_group.name, 48689585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].targetGroup, 48699585STim.Szeto@Sun.COM fVeList[i].ve_target_group.name_size); 48709585STim.Szeto@Sun.COM } 48719585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr, 48729585STim.Szeto@Sun.COM sizeof ((*viewEntryList)->ve[i].luNbr)); 48739585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].luNbrValid = B_TRUE; 48749585STim.Szeto@Sun.COM } 48759585STim.Szeto@Sun.COM 48769585STim.Szeto@Sun.COM /* 48779585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 48789585STim.Szeto@Sun.COM */ 48799585STim.Szeto@Sun.COM qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt, 48809585STim.Szeto@Sun.COM sizeof (stmfViewEntry), viewEntryCompare); 48819585STim.Szeto@Sun.COM 48829585STim.Szeto@Sun.COM done: 48839585STim.Szeto@Sun.COM (void) close(fd); 48849585STim.Szeto@Sun.COM /* 48859585STim.Szeto@Sun.COM * free internal buffers 48869585STim.Szeto@Sun.COM */ 48879585STim.Szeto@Sun.COM free(fVeList); 48887836SJohn.Forte@Sun.COM return (ret); 48897836SJohn.Forte@Sun.COM } 48907836SJohn.Forte@Sun.COM 48919585STim.Szeto@Sun.COM 48927836SJohn.Forte@Sun.COM /* 48937836SJohn.Forte@Sun.COM * loadHostGroups 48947836SJohn.Forte@Sun.COM * 48957836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the host groups into stmf 48967836SJohn.Forte@Sun.COM * 48977836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 48987836SJohn.Forte@Sun.COM * groupList - populated host group list 48997836SJohn.Forte@Sun.COM */ 49007836SJohn.Forte@Sun.COM static int 49017836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList) 49027836SJohn.Forte@Sun.COM { 49037836SJohn.Forte@Sun.COM int i, j; 49047836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49057836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 49067836SJohn.Forte@Sun.COM 49077836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 49087836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 49097836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 49107836SJohn.Forte@Sun.COM goto out; 49117836SJohn.Forte@Sun.COM } 49129585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 49139585STim.Szeto@Sun.COM &groupProps, HOST_GROUP); 49147836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 49157836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, 49167836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 49177836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 49187836SJohn.Forte@Sun.COM goto out; 49197836SJohn.Forte@Sun.COM } 49207836SJohn.Forte@Sun.COM } 49217836SJohn.Forte@Sun.COM } 49227836SJohn.Forte@Sun.COM 49237836SJohn.Forte@Sun.COM 49247836SJohn.Forte@Sun.COM out: 49257836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 49267836SJohn.Forte@Sun.COM return (ret); 49277836SJohn.Forte@Sun.COM } 49287836SJohn.Forte@Sun.COM 49297836SJohn.Forte@Sun.COM /* 49307836SJohn.Forte@Sun.COM * loadTargetGroups 49317836SJohn.Forte@Sun.COM * 49327836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the target groups into stmf 49337836SJohn.Forte@Sun.COM * 49347836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 49357836SJohn.Forte@Sun.COM * groupList - populated target group list. 49367836SJohn.Forte@Sun.COM */ 49377836SJohn.Forte@Sun.COM static int 49387836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList) 49397836SJohn.Forte@Sun.COM { 49407836SJohn.Forte@Sun.COM int i, j; 49417836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49427836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 49437836SJohn.Forte@Sun.COM 49447836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 49457836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 49467836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 49477836SJohn.Forte@Sun.COM goto out; 49487836SJohn.Forte@Sun.COM } 49499585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 49509585STim.Szeto@Sun.COM &groupProps, TARGET_GROUP); 49517836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 49527836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 49537836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 49547836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 49557836SJohn.Forte@Sun.COM goto out; 49567836SJohn.Forte@Sun.COM } 49577836SJohn.Forte@Sun.COM } 49587836SJohn.Forte@Sun.COM } 49597836SJohn.Forte@Sun.COM 49607836SJohn.Forte@Sun.COM 49617836SJohn.Forte@Sun.COM out: 49627836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 49637836SJohn.Forte@Sun.COM return (ret); 49647836SJohn.Forte@Sun.COM } 49657836SJohn.Forte@Sun.COM 49667836SJohn.Forte@Sun.COM 49677836SJohn.Forte@Sun.COM /* 49687836SJohn.Forte@Sun.COM * loadStore 49697836SJohn.Forte@Sun.COM * 49707836SJohn.Forte@Sun.COM * Purpose: Load the configuration data from the store 49717836SJohn.Forte@Sun.COM * 49727836SJohn.Forte@Sun.COM * First load the host groups and target groups, then the view entries 49737836SJohn.Forte@Sun.COM * and finally the provider data 49747836SJohn.Forte@Sun.COM * 49757836SJohn.Forte@Sun.COM * fd - file descriptor of control node for stmf. 49767836SJohn.Forte@Sun.COM */ 49777836SJohn.Forte@Sun.COM static int 49787836SJohn.Forte@Sun.COM loadStore(int fd) 49797836SJohn.Forte@Sun.COM { 49807836SJohn.Forte@Sun.COM int ret; 49817836SJohn.Forte@Sun.COM int i, j; 49827836SJohn.Forte@Sun.COM stmfGroupList *groupList = NULL; 49837836SJohn.Forte@Sun.COM stmfGuidList *guidList = NULL; 49847836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 49857836SJohn.Forte@Sun.COM stmfProviderList *providerList = NULL; 49867836SJohn.Forte@Sun.COM int providerType; 49877836SJohn.Forte@Sun.COM nvlist_t *nvl = NULL; 49887836SJohn.Forte@Sun.COM 49897836SJohn.Forte@Sun.COM 49907836SJohn.Forte@Sun.COM 49917836SJohn.Forte@Sun.COM /* load host groups */ 49929585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, HOST_GROUP); 49937836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 49947836SJohn.Forte@Sun.COM return (ret); 49957836SJohn.Forte@Sun.COM } 49967836SJohn.Forte@Sun.COM ret = loadHostGroups(fd, groupList); 49977836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 49987836SJohn.Forte@Sun.COM goto out; 49997836SJohn.Forte@Sun.COM } 50007836SJohn.Forte@Sun.COM 50017836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 50027836SJohn.Forte@Sun.COM groupList = NULL; 50037836SJohn.Forte@Sun.COM 50047836SJohn.Forte@Sun.COM /* load target groups */ 50059585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, TARGET_GROUP); 50067836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50077836SJohn.Forte@Sun.COM goto out; 50087836SJohn.Forte@Sun.COM } 50097836SJohn.Forte@Sun.COM ret = loadTargetGroups(fd, groupList); 50107836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50117836SJohn.Forte@Sun.COM goto out; 50127836SJohn.Forte@Sun.COM } 50137836SJohn.Forte@Sun.COM 50147836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 50157836SJohn.Forte@Sun.COM groupList = NULL; 50167836SJohn.Forte@Sun.COM 50177836SJohn.Forte@Sun.COM /* Get the guid list */ 50187836SJohn.Forte@Sun.COM ret = psGetLogicalUnitList(&guidList); 50197836SJohn.Forte@Sun.COM switch (ret) { 50207836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 50217836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 50227836SJohn.Forte@Sun.COM break; 50237836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 50247836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 50257836SJohn.Forte@Sun.COM break; 50267836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 50277836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 50287836SJohn.Forte@Sun.COM break; 50297836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 50307836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 50317836SJohn.Forte@Sun.COM break; 50327836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 50337836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 50347836SJohn.Forte@Sun.COM break; 50357836SJohn.Forte@Sun.COM default: 50367836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 50377836SJohn.Forte@Sun.COM break; 50387836SJohn.Forte@Sun.COM } 50397836SJohn.Forte@Sun.COM 50407836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50417836SJohn.Forte@Sun.COM goto out; 50427836SJohn.Forte@Sun.COM } 50437836SJohn.Forte@Sun.COM 50447836SJohn.Forte@Sun.COM /* 50457836SJohn.Forte@Sun.COM * We have the guid list, now get the corresponding 50467836SJohn.Forte@Sun.COM * view entries for each guid 50477836SJohn.Forte@Sun.COM */ 50487836SJohn.Forte@Sun.COM for (i = 0; i < guidList->cnt; i++) { 50497836SJohn.Forte@Sun.COM ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList); 50507836SJohn.Forte@Sun.COM switch (ret) { 50517836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 50527836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 50537836SJohn.Forte@Sun.COM break; 50547836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 50557836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 50567836SJohn.Forte@Sun.COM break; 50577836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 50587836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 50597836SJohn.Forte@Sun.COM break; 50607836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 50617836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 50627836SJohn.Forte@Sun.COM break; 50637836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 50647836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 50657836SJohn.Forte@Sun.COM break; 50667836SJohn.Forte@Sun.COM default: 50677836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 50687836SJohn.Forte@Sun.COM break; 50697836SJohn.Forte@Sun.COM } 50707836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50717836SJohn.Forte@Sun.COM goto out; 50727836SJohn.Forte@Sun.COM } 50737836SJohn.Forte@Sun.COM for (j = 0; j < viewEntryList->cnt; j++) { 50747836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, &guidList->guid[i], 50757836SJohn.Forte@Sun.COM &viewEntryList->ve[j]); 50767836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50777836SJohn.Forte@Sun.COM goto out; 50787836SJohn.Forte@Sun.COM } 50797836SJohn.Forte@Sun.COM } 50807836SJohn.Forte@Sun.COM } 50817836SJohn.Forte@Sun.COM 50827836SJohn.Forte@Sun.COM /* get the list of providers that have data */ 50837836SJohn.Forte@Sun.COM ret = psGetProviderDataList(&providerList); 50847836SJohn.Forte@Sun.COM switch (ret) { 50857836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 50867836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 50877836SJohn.Forte@Sun.COM break; 50887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 50897836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 50907836SJohn.Forte@Sun.COM break; 50917836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 50927836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 50937836SJohn.Forte@Sun.COM break; 50947836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 50957836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 50967836SJohn.Forte@Sun.COM break; 50977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 50987836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 50997836SJohn.Forte@Sun.COM break; 51007836SJohn.Forte@Sun.COM default: 51017836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51027836SJohn.Forte@Sun.COM break; 51037836SJohn.Forte@Sun.COM } 51047836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51057836SJohn.Forte@Sun.COM goto out; 51067836SJohn.Forte@Sun.COM } 51077836SJohn.Forte@Sun.COM 51087836SJohn.Forte@Sun.COM for (i = 0; i < providerList->cnt; i++) { 51097836SJohn.Forte@Sun.COM providerType = providerList->provider[i].providerType; 51107836SJohn.Forte@Sun.COM ret = psGetProviderData(providerList->provider[i].name, 51117836SJohn.Forte@Sun.COM &nvl, providerType, NULL); 51127836SJohn.Forte@Sun.COM switch (ret) { 51137836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51147836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51157836SJohn.Forte@Sun.COM break; 51167836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 51177836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 51187836SJohn.Forte@Sun.COM break; 51197836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51207836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51217836SJohn.Forte@Sun.COM break; 51227836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51237836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51247836SJohn.Forte@Sun.COM break; 51257836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51267836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51277836SJohn.Forte@Sun.COM break; 51287836SJohn.Forte@Sun.COM default: 51297836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51307836SJohn.Forte@Sun.COM break; 51317836SJohn.Forte@Sun.COM } 51327836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51337836SJohn.Forte@Sun.COM goto out; 51347836SJohn.Forte@Sun.COM } 51357836SJohn.Forte@Sun.COM 51367836SJohn.Forte@Sun.COM /* call setProviderData */ 51377836SJohn.Forte@Sun.COM ret = setProviderData(fd, providerList->provider[i].name, nvl, 51389585STim.Szeto@Sun.COM providerType, NULL); 51397836SJohn.Forte@Sun.COM switch (ret) { 51407836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51417836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51427836SJohn.Forte@Sun.COM break; 51437836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 51447836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 51457836SJohn.Forte@Sun.COM break; 51467836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51477836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51487836SJohn.Forte@Sun.COM break; 51497836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51507836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51517836SJohn.Forte@Sun.COM break; 51527836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51537836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51547836SJohn.Forte@Sun.COM break; 51557836SJohn.Forte@Sun.COM default: 51567836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51577836SJohn.Forte@Sun.COM break; 51587836SJohn.Forte@Sun.COM } 51597836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51607836SJohn.Forte@Sun.COM goto out; 51617836SJohn.Forte@Sun.COM } 51627836SJohn.Forte@Sun.COM 51637836SJohn.Forte@Sun.COM nvlist_free(nvl); 51647836SJohn.Forte@Sun.COM nvl = NULL; 51657836SJohn.Forte@Sun.COM } 51667836SJohn.Forte@Sun.COM out: 51677836SJohn.Forte@Sun.COM if (groupList != NULL) { 51687836SJohn.Forte@Sun.COM free(groupList); 51697836SJohn.Forte@Sun.COM } 51707836SJohn.Forte@Sun.COM if (guidList != NULL) { 51717836SJohn.Forte@Sun.COM free(guidList); 51727836SJohn.Forte@Sun.COM } 51737836SJohn.Forte@Sun.COM if (viewEntryList != NULL) { 51747836SJohn.Forte@Sun.COM free(viewEntryList); 51757836SJohn.Forte@Sun.COM } 51767836SJohn.Forte@Sun.COM if (nvl != NULL) { 51777836SJohn.Forte@Sun.COM nvlist_free(nvl); 51787836SJohn.Forte@Sun.COM } 51797836SJohn.Forte@Sun.COM return (ret); 51807836SJohn.Forte@Sun.COM } 51817836SJohn.Forte@Sun.COM 51827836SJohn.Forte@Sun.COM /* 518310725SJohn.Forte@Sun.COM * stmfGetAluaState 518410725SJohn.Forte@Sun.COM * 518510725SJohn.Forte@Sun.COM * Purpose - Get the alua state 518610725SJohn.Forte@Sun.COM * 518710725SJohn.Forte@Sun.COM */ 518810725SJohn.Forte@Sun.COM int 518910725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node) 519010725SJohn.Forte@Sun.COM { 519110725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 519210725SJohn.Forte@Sun.COM int fd; 519310725SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl = {0}; 519410725SJohn.Forte@Sun.COM stmf_alua_state_desc_t alua_state = {0}; 519510725SJohn.Forte@Sun.COM int ioctlRet; 519610725SJohn.Forte@Sun.COM 519710725SJohn.Forte@Sun.COM if (enabled == NULL || node == NULL) { 519810725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 519910725SJohn.Forte@Sun.COM } 520010725SJohn.Forte@Sun.COM 520110725SJohn.Forte@Sun.COM /* 520210725SJohn.Forte@Sun.COM * Open control node for stmf 520310725SJohn.Forte@Sun.COM */ 520410725SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 520510725SJohn.Forte@Sun.COM return (ret); 520610725SJohn.Forte@Sun.COM 520710725SJohn.Forte@Sun.COM /* 520810725SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 520910725SJohn.Forte@Sun.COM */ 521010725SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 521110725SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (alua_state); 521210725SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state; 521310725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl); 521410725SJohn.Forte@Sun.COM 521510725SJohn.Forte@Sun.COM (void) close(fd); 521610725SJohn.Forte@Sun.COM 521710725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 521810725SJohn.Forte@Sun.COM switch (errno) { 521910725SJohn.Forte@Sun.COM case EBUSY: 522010725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 522110725SJohn.Forte@Sun.COM break; 522210725SJohn.Forte@Sun.COM case EPERM: 522310725SJohn.Forte@Sun.COM case EACCES: 522410725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 522510725SJohn.Forte@Sun.COM break; 522610725SJohn.Forte@Sun.COM default: 522710725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 522810725SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 522910725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 523010725SJohn.Forte@Sun.COM break; 523110725SJohn.Forte@Sun.COM } 523210725SJohn.Forte@Sun.COM } else { 523310725SJohn.Forte@Sun.COM if (alua_state.alua_state == 1) { 523410725SJohn.Forte@Sun.COM *enabled = B_TRUE; 523510725SJohn.Forte@Sun.COM } else { 523610725SJohn.Forte@Sun.COM *enabled = B_FALSE; 523710725SJohn.Forte@Sun.COM } 523810725SJohn.Forte@Sun.COM *node = alua_state.alua_node; 523910725SJohn.Forte@Sun.COM } 524010725SJohn.Forte@Sun.COM 524110725SJohn.Forte@Sun.COM return (ret); 524210725SJohn.Forte@Sun.COM } 524310725SJohn.Forte@Sun.COM 524410725SJohn.Forte@Sun.COM /* 524510725SJohn.Forte@Sun.COM * stmfSetAluaState 524610725SJohn.Forte@Sun.COM * 524710725SJohn.Forte@Sun.COM * Purpose - set the alua state to enabled/disabled 524810725SJohn.Forte@Sun.COM * 524910725SJohn.Forte@Sun.COM */ 525010725SJohn.Forte@Sun.COM int 525110725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node) 525210725SJohn.Forte@Sun.COM { 525310725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 525410725SJohn.Forte@Sun.COM int fd; 525510725SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl = {0}; 525610725SJohn.Forte@Sun.COM stmf_alua_state_desc_t alua_state = {0}; 525710725SJohn.Forte@Sun.COM int ioctlRet; 525810725SJohn.Forte@Sun.COM 525910725SJohn.Forte@Sun.COM if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) { 526010725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 526110725SJohn.Forte@Sun.COM } 526210725SJohn.Forte@Sun.COM 526310725SJohn.Forte@Sun.COM if (enabled) { 526410725SJohn.Forte@Sun.COM alua_state.alua_state = 1; 526510725SJohn.Forte@Sun.COM } 526610725SJohn.Forte@Sun.COM 526710725SJohn.Forte@Sun.COM alua_state.alua_node = node; 526810725SJohn.Forte@Sun.COM 526910725SJohn.Forte@Sun.COM /* 527010725SJohn.Forte@Sun.COM * Open control node for stmf 527110725SJohn.Forte@Sun.COM */ 527210725SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 527310725SJohn.Forte@Sun.COM return (ret); 527410725SJohn.Forte@Sun.COM 527510725SJohn.Forte@Sun.COM /* 527610725SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 527710725SJohn.Forte@Sun.COM */ 527810725SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 527910725SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (alua_state); 528010725SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state; 528110725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl); 528210725SJohn.Forte@Sun.COM 528310725SJohn.Forte@Sun.COM (void) close(fd); 528410725SJohn.Forte@Sun.COM 528510725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 528610725SJohn.Forte@Sun.COM switch (errno) { 528710725SJohn.Forte@Sun.COM case EBUSY: 528810725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 528910725SJohn.Forte@Sun.COM break; 529010725SJohn.Forte@Sun.COM case EPERM: 529110725SJohn.Forte@Sun.COM case EACCES: 529210725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 529310725SJohn.Forte@Sun.COM break; 529410725SJohn.Forte@Sun.COM default: 529510725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 529610725SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 529710725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 529810725SJohn.Forte@Sun.COM break; 529910725SJohn.Forte@Sun.COM } 530010725SJohn.Forte@Sun.COM } 530111116SJohn.Forte@Sun.COM if (!enabled && ret == STMF_STATUS_SUCCESS) { 530210725SJohn.Forte@Sun.COM deleteNonActiveLus(); 530310725SJohn.Forte@Sun.COM } 530410725SJohn.Forte@Sun.COM 530510725SJohn.Forte@Sun.COM return (ret); 530610725SJohn.Forte@Sun.COM } 530710725SJohn.Forte@Sun.COM 530810725SJohn.Forte@Sun.COM static void 530910725SJohn.Forte@Sun.COM deleteNonActiveLus() 531010725SJohn.Forte@Sun.COM { 531110725SJohn.Forte@Sun.COM int stmfRet; 531210725SJohn.Forte@Sun.COM int i; 531310725SJohn.Forte@Sun.COM stmfGuidList *luList; 531410725SJohn.Forte@Sun.COM luResource hdl = NULL; 531510725SJohn.Forte@Sun.COM char propVal[10]; 531610725SJohn.Forte@Sun.COM size_t propValSize = sizeof (propVal); 531710725SJohn.Forte@Sun.COM 531810725SJohn.Forte@Sun.COM stmfRet = stmfGetLogicalUnitList(&luList); 531910725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 532010725SJohn.Forte@Sun.COM return; 532110725SJohn.Forte@Sun.COM } 532210725SJohn.Forte@Sun.COM 532310725SJohn.Forte@Sun.COM for (i = 0; i < luList->cnt; i++) { 532410725SJohn.Forte@Sun.COM stmfRet = stmfGetLuResource(&luList->guid[i], &hdl); 532510725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 532610725SJohn.Forte@Sun.COM goto err; 532710725SJohn.Forte@Sun.COM } 532810725SJohn.Forte@Sun.COM stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal, 532910725SJohn.Forte@Sun.COM &propValSize); 533010725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 533110725SJohn.Forte@Sun.COM goto err; 533210725SJohn.Forte@Sun.COM } 533310725SJohn.Forte@Sun.COM if (propVal[0] == '0') { 533410725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 533510725SJohn.Forte@Sun.COM hdl = NULL; 533610725SJohn.Forte@Sun.COM continue; 533710725SJohn.Forte@Sun.COM } 533810725SJohn.Forte@Sun.COM (void) stmfDeleteLu(&luList->guid[i]); 533910725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 534010725SJohn.Forte@Sun.COM hdl = NULL; 534110725SJohn.Forte@Sun.COM } 534210725SJohn.Forte@Sun.COM 534310725SJohn.Forte@Sun.COM err: 534410725SJohn.Forte@Sun.COM stmfFreeMemory(luList); 534510725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 534610725SJohn.Forte@Sun.COM } 534710725SJohn.Forte@Sun.COM 534810725SJohn.Forte@Sun.COM /* 53497836SJohn.Forte@Sun.COM * stmfLoadConfig 53507836SJohn.Forte@Sun.COM * 53517836SJohn.Forte@Sun.COM * Purpose - load the configuration data from smf into stmf 53527836SJohn.Forte@Sun.COM * 53537836SJohn.Forte@Sun.COM */ 53547836SJohn.Forte@Sun.COM int 53557836SJohn.Forte@Sun.COM stmfLoadConfig(void) 53567836SJohn.Forte@Sun.COM { 53579585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 53587836SJohn.Forte@Sun.COM int fd; 53597836SJohn.Forte@Sun.COM stmf_state_desc_t stmfStateSet; 53607836SJohn.Forte@Sun.COM stmfState state; 53617836SJohn.Forte@Sun.COM 53629585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 53639585STim.Szeto@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 536410560SSusan.Gleeson@Sun.COM 53659585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) 53669585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 53679585STim.Szeto@Sun.COM return (ret); 53689585STim.Szeto@Sun.COM } 536910560SSusan.Gleeson@Sun.COM /* 537010560SSusan.Gleeson@Sun.COM * Configuration not stored persistently; nothing to 537110560SSusan.Gleeson@Sun.COM * initialize so do not set to STMF_CONFIG_INIT. 537210560SSusan.Gleeson@Sun.COM */ 53739585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 53749585STim.Szeto@Sun.COM goto done; 53759585STim.Szeto@Sun.COM } 53767836SJohn.Forte@Sun.COM 53777836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 53787836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 53797836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 53807836SJohn.Forte@Sun.COM } 53817836SJohn.Forte@Sun.COM 53827836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 53837836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 53847836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 53857836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 53867836SJohn.Forte@Sun.COM } 53877836SJohn.Forte@Sun.COM } else { 53887836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 53897836SJohn.Forte@Sun.COM } 53907836SJohn.Forte@Sun.COM 53917836SJohn.Forte@Sun.COM 53927836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 53937836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 53947836SJohn.Forte@Sun.COM 53957836SJohn.Forte@Sun.COM /* 53967836SJohn.Forte@Sun.COM * Open control node for stmf 53977836SJohn.Forte@Sun.COM */ 53987836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 53997836SJohn.Forte@Sun.COM return (ret); 54007836SJohn.Forte@Sun.COM 54017836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 54027836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 54037836SJohn.Forte@Sun.COM goto done; 54047836SJohn.Forte@Sun.COM } 54057836SJohn.Forte@Sun.COM 54067836SJohn.Forte@Sun.COM /* Load the persistent configuration data */ 54077836SJohn.Forte@Sun.COM ret = loadStore(fd); 54087836SJohn.Forte@Sun.COM if (ret != 0) { 54097836SJohn.Forte@Sun.COM goto done; 54107836SJohn.Forte@Sun.COM } 54117836SJohn.Forte@Sun.COM 54127836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 54137836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 54147836SJohn.Forte@Sun.COM 54157836SJohn.Forte@Sun.COM done: 54167836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 54177836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 54187836SJohn.Forte@Sun.COM } 54197836SJohn.Forte@Sun.COM (void) close(fd); 54207836SJohn.Forte@Sun.COM return (ret); 54217836SJohn.Forte@Sun.COM } 54227836SJohn.Forte@Sun.COM 54239585STim.Szeto@Sun.COM 54247836SJohn.Forte@Sun.COM /* 54257836SJohn.Forte@Sun.COM * getStmfState 54267836SJohn.Forte@Sun.COM * 54277836SJohn.Forte@Sun.COM * stmfState - pointer to stmf_state_desc_t structure. Will contain the state 54287836SJohn.Forte@Sun.COM * information of the stmf service on success. 54297836SJohn.Forte@Sun.COM */ 54307836SJohn.Forte@Sun.COM static int 54317836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState) 54327836SJohn.Forte@Sun.COM { 54337836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 54347836SJohn.Forte@Sun.COM int fd; 54357836SJohn.Forte@Sun.COM int ioctlRet; 54367836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 54377836SJohn.Forte@Sun.COM 54387836SJohn.Forte@Sun.COM /* 54397836SJohn.Forte@Sun.COM * Open control node for stmf 54407836SJohn.Forte@Sun.COM */ 54417836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 54427836SJohn.Forte@Sun.COM return (ret); 54437836SJohn.Forte@Sun.COM 54447836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 54457836SJohn.Forte@Sun.COM /* 54467836SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 54477836SJohn.Forte@Sun.COM */ 54487836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 54497836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 54507836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 54517836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t); 54527836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState; 54537836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl); 54547836SJohn.Forte@Sun.COM 54557836SJohn.Forte@Sun.COM (void) close(fd); 54567836SJohn.Forte@Sun.COM 54577836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 54587836SJohn.Forte@Sun.COM switch (errno) { 54597836SJohn.Forte@Sun.COM case EBUSY: 54607836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 54617836SJohn.Forte@Sun.COM break; 54627836SJohn.Forte@Sun.COM case EPERM: 54637836SJohn.Forte@Sun.COM case EACCES: 54647836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 54657836SJohn.Forte@Sun.COM break; 54667836SJohn.Forte@Sun.COM default: 54677836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 54687836SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 54697836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 54707836SJohn.Forte@Sun.COM break; 54717836SJohn.Forte@Sun.COM } 54727836SJohn.Forte@Sun.COM } 54737836SJohn.Forte@Sun.COM return (ret); 54747836SJohn.Forte@Sun.COM } 54757836SJohn.Forte@Sun.COM 54767836SJohn.Forte@Sun.COM 54777836SJohn.Forte@Sun.COM /* 54787836SJohn.Forte@Sun.COM * setStmfState 54797836SJohn.Forte@Sun.COM * 54807836SJohn.Forte@Sun.COM * stmfState - pointer to caller set state structure 54817836SJohn.Forte@Sun.COM * objectType - one of: 54827836SJohn.Forte@Sun.COM * LOGICAL_UNIT_TYPE 54837836SJohn.Forte@Sun.COM * TARGET_TYPE 54847836SJohn.Forte@Sun.COM * STMF_SERVICE_TYPE 54857836SJohn.Forte@Sun.COM */ 54867836SJohn.Forte@Sun.COM static int 54877836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType) 54887836SJohn.Forte@Sun.COM { 54897836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 54907836SJohn.Forte@Sun.COM int ioctlRet; 54917836SJohn.Forte@Sun.COM int cmd; 54927836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 54937836SJohn.Forte@Sun.COM 54947836SJohn.Forte@Sun.COM switch (objectType) { 54957836SJohn.Forte@Sun.COM case LOGICAL_UNIT_TYPE: 54967836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_LU_STATE; 54977836SJohn.Forte@Sun.COM break; 54987836SJohn.Forte@Sun.COM case TARGET_TYPE: 54997836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_TARGET_PORT_STATE; 55007836SJohn.Forte@Sun.COM break; 55017836SJohn.Forte@Sun.COM case STMF_SERVICE_TYPE: 55027836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_STMF_STATE; 55037836SJohn.Forte@Sun.COM break; 55047836SJohn.Forte@Sun.COM default: 55057836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 55067836SJohn.Forte@Sun.COM goto done; 55077836SJohn.Forte@Sun.COM } 55087836SJohn.Forte@Sun.COM 55097836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 55107836SJohn.Forte@Sun.COM /* 55117836SJohn.Forte@Sun.COM * Issue ioctl to set the stmf state 55127836SJohn.Forte@Sun.COM */ 55137836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 55147836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 55157836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 55167836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 55177836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 55187836SJohn.Forte@Sun.COM switch (errno) { 55197836SJohn.Forte@Sun.COM case EBUSY: 55207836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 55217836SJohn.Forte@Sun.COM break; 55229585STim.Szeto@Sun.COM case EPERM: 55237836SJohn.Forte@Sun.COM case EACCES: 55247836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 55257836SJohn.Forte@Sun.COM break; 55267836SJohn.Forte@Sun.COM case ENOENT: 55277836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 55287836SJohn.Forte@Sun.COM break; 55297836SJohn.Forte@Sun.COM default: 55307836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 55317836SJohn.Forte@Sun.COM "setStmfState:ioctl errno(%d)", errno); 55327836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 55337836SJohn.Forte@Sun.COM break; 55347836SJohn.Forte@Sun.COM } 55357836SJohn.Forte@Sun.COM } 55367836SJohn.Forte@Sun.COM done: 55377836SJohn.Forte@Sun.COM return (ret); 55387836SJohn.Forte@Sun.COM } 55397836SJohn.Forte@Sun.COM 55407836SJohn.Forte@Sun.COM /* 55417836SJohn.Forte@Sun.COM * stmfOnline 55427836SJohn.Forte@Sun.COM * 55437836SJohn.Forte@Sun.COM * Purpose: Online stmf service 55447836SJohn.Forte@Sun.COM * 55457836SJohn.Forte@Sun.COM */ 55467836SJohn.Forte@Sun.COM int 55477836SJohn.Forte@Sun.COM stmfOnline(void) 55487836SJohn.Forte@Sun.COM { 55497836SJohn.Forte@Sun.COM int ret; 55507836SJohn.Forte@Sun.COM int fd; 55517836SJohn.Forte@Sun.COM stmfState state; 55527836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 55537836SJohn.Forte@Sun.COM 55547836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 55557836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 55567836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 55577836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 55587836SJohn.Forte@Sun.COM } 55597836SJohn.Forte@Sun.COM } else { 55607836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 55617836SJohn.Forte@Sun.COM } 55627836SJohn.Forte@Sun.COM iState.state = STMF_STATE_ONLINE; 55637836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 55647836SJohn.Forte@Sun.COM /* 55657836SJohn.Forte@Sun.COM * Open control node for stmf 55667836SJohn.Forte@Sun.COM * to make call to setStmfState() 55677836SJohn.Forte@Sun.COM */ 55687836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 55697836SJohn.Forte@Sun.COM return (ret); 55707836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 55717836SJohn.Forte@Sun.COM (void) close(fd); 55727836SJohn.Forte@Sun.COM return (ret); 55737836SJohn.Forte@Sun.COM } 55747836SJohn.Forte@Sun.COM 55757836SJohn.Forte@Sun.COM /* 55767836SJohn.Forte@Sun.COM * stmfOffline 55777836SJohn.Forte@Sun.COM * 55787836SJohn.Forte@Sun.COM * Purpose: Offline stmf service 55797836SJohn.Forte@Sun.COM * 55807836SJohn.Forte@Sun.COM */ 55817836SJohn.Forte@Sun.COM int 55827836SJohn.Forte@Sun.COM stmfOffline(void) 55837836SJohn.Forte@Sun.COM { 55847836SJohn.Forte@Sun.COM int ret; 55857836SJohn.Forte@Sun.COM int fd; 55867836SJohn.Forte@Sun.COM stmfState state; 55877836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 55887836SJohn.Forte@Sun.COM 55897836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 55907836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 55917836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 55927836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_OFFLINE); 55937836SJohn.Forte@Sun.COM } 55947836SJohn.Forte@Sun.COM } else { 55957836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 55967836SJohn.Forte@Sun.COM } 55977836SJohn.Forte@Sun.COM iState.state = STMF_STATE_OFFLINE; 55987836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 55997836SJohn.Forte@Sun.COM 56007836SJohn.Forte@Sun.COM /* 56017836SJohn.Forte@Sun.COM * Open control node for stmf 56027836SJohn.Forte@Sun.COM * to make call to setStmfState() 56037836SJohn.Forte@Sun.COM */ 56047836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 56057836SJohn.Forte@Sun.COM return (ret); 56067836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 56077836SJohn.Forte@Sun.COM (void) close(fd); 56087836SJohn.Forte@Sun.COM return (ret); 56097836SJohn.Forte@Sun.COM } 56107836SJohn.Forte@Sun.COM 56117836SJohn.Forte@Sun.COM 56127836SJohn.Forte@Sun.COM /* 56137836SJohn.Forte@Sun.COM * stmfOfflineTarget 56147836SJohn.Forte@Sun.COM * 56157836SJohn.Forte@Sun.COM * Purpose: Change state of target to offline 56167836SJohn.Forte@Sun.COM * 56177836SJohn.Forte@Sun.COM * devid - devid of the target to offline 56187836SJohn.Forte@Sun.COM */ 56197836SJohn.Forte@Sun.COM int 56207836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid) 56217836SJohn.Forte@Sun.COM { 56227836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 56237836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56247836SJohn.Forte@Sun.COM int fd; 56257836SJohn.Forte@Sun.COM 56267836SJohn.Forte@Sun.COM if (devid == NULL) { 56277836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56287836SJohn.Forte@Sun.COM } 56297836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 56307836SJohn.Forte@Sun.COM 56317836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_OFFLINE; 56327836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 56337836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 56347836SJohn.Forte@Sun.COM devid->identLength); 56357836SJohn.Forte@Sun.COM /* 56367836SJohn.Forte@Sun.COM * Open control node for stmf 56377836SJohn.Forte@Sun.COM * to make call to setStmfState() 56387836SJohn.Forte@Sun.COM */ 56397836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 56407836SJohn.Forte@Sun.COM return (ret); 56417836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 56427836SJohn.Forte@Sun.COM (void) close(fd); 56437836SJohn.Forte@Sun.COM return (ret); 56447836SJohn.Forte@Sun.COM } 56457836SJohn.Forte@Sun.COM 56467836SJohn.Forte@Sun.COM /* 56477836SJohn.Forte@Sun.COM * stmfOfflineLogicalUnit 56487836SJohn.Forte@Sun.COM * 56497836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to offline 56507836SJohn.Forte@Sun.COM * 56517836SJohn.Forte@Sun.COM * lu - guid of the logical unit to offline 56527836SJohn.Forte@Sun.COM */ 56537836SJohn.Forte@Sun.COM int 56547836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu) 56557836SJohn.Forte@Sun.COM { 56567836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 56577836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56587836SJohn.Forte@Sun.COM int fd; 56597836SJohn.Forte@Sun.COM 56607836SJohn.Forte@Sun.COM if (lu == NULL) { 56617836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56627836SJohn.Forte@Sun.COM } 56637836SJohn.Forte@Sun.COM 56647836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 56657836SJohn.Forte@Sun.COM 56667836SJohn.Forte@Sun.COM luState.state = STMF_STATE_OFFLINE; 56677836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 56687836SJohn.Forte@Sun.COM /* 56697836SJohn.Forte@Sun.COM * Open control node for stmf 56707836SJohn.Forte@Sun.COM * to make call to setStmfState() 56717836SJohn.Forte@Sun.COM */ 56727836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 56737836SJohn.Forte@Sun.COM return (ret); 56747836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 56757836SJohn.Forte@Sun.COM (void) close(fd); 56767836SJohn.Forte@Sun.COM return (ret); 56777836SJohn.Forte@Sun.COM } 56787836SJohn.Forte@Sun.COM 56797836SJohn.Forte@Sun.COM /* 56807836SJohn.Forte@Sun.COM * stmfOnlineTarget 56817836SJohn.Forte@Sun.COM * 56827836SJohn.Forte@Sun.COM * Purpose: Change state of target to online 56837836SJohn.Forte@Sun.COM * 56847836SJohn.Forte@Sun.COM * devid - devid of the target to online 56857836SJohn.Forte@Sun.COM */ 56867836SJohn.Forte@Sun.COM int 56877836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid) 56887836SJohn.Forte@Sun.COM { 56897836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 56907836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56917836SJohn.Forte@Sun.COM int fd; 56927836SJohn.Forte@Sun.COM 56937836SJohn.Forte@Sun.COM if (devid == NULL) { 56947836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56957836SJohn.Forte@Sun.COM } 56967836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 56977836SJohn.Forte@Sun.COM 56987836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_ONLINE; 56997836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 57007836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 57017836SJohn.Forte@Sun.COM devid->identLength); 57027836SJohn.Forte@Sun.COM /* 57037836SJohn.Forte@Sun.COM * Open control node for stmf 57047836SJohn.Forte@Sun.COM * to make call to setStmfState() 57057836SJohn.Forte@Sun.COM */ 57067836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 57077836SJohn.Forte@Sun.COM return (ret); 57087836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 57097836SJohn.Forte@Sun.COM (void) close(fd); 57107836SJohn.Forte@Sun.COM return (ret); 57117836SJohn.Forte@Sun.COM } 57127836SJohn.Forte@Sun.COM 57137836SJohn.Forte@Sun.COM /* 57147836SJohn.Forte@Sun.COM * stmfOnlineLogicalUnit 57157836SJohn.Forte@Sun.COM * 57167836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to online 57177836SJohn.Forte@Sun.COM * 57187836SJohn.Forte@Sun.COM * lu - guid of the logical unit to online 57197836SJohn.Forte@Sun.COM */ 57207836SJohn.Forte@Sun.COM int 57217836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu) 57227836SJohn.Forte@Sun.COM { 57237836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 57247836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 57257836SJohn.Forte@Sun.COM int fd; 57267836SJohn.Forte@Sun.COM 57277836SJohn.Forte@Sun.COM if (lu == NULL) { 57287836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 57297836SJohn.Forte@Sun.COM } 57307836SJohn.Forte@Sun.COM 57317836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 57327836SJohn.Forte@Sun.COM 57337836SJohn.Forte@Sun.COM luState.state = STMF_STATE_ONLINE; 57347836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 57357836SJohn.Forte@Sun.COM /* 57367836SJohn.Forte@Sun.COM * Open control node for stmf 57377836SJohn.Forte@Sun.COM * to make call to setStmfState() 57387836SJohn.Forte@Sun.COM */ 57397836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 57407836SJohn.Forte@Sun.COM return (ret); 57417836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 57427836SJohn.Forte@Sun.COM (void) close(fd); 57437836SJohn.Forte@Sun.COM return (ret); 57447836SJohn.Forte@Sun.COM } 57457836SJohn.Forte@Sun.COM 57467836SJohn.Forte@Sun.COM /* 57477836SJohn.Forte@Sun.COM * stmfRemoveFromHostGroup 57487836SJohn.Forte@Sun.COM * 57497836SJohn.Forte@Sun.COM * Purpose: Removes an initiator from an initiator group 57507836SJohn.Forte@Sun.COM * 57517836SJohn.Forte@Sun.COM * hostGroupName - name of an initiator group 57527836SJohn.Forte@Sun.COM * hostName - name of host group member to remove 57537836SJohn.Forte@Sun.COM */ 57547836SJohn.Forte@Sun.COM int 57557836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 57567836SJohn.Forte@Sun.COM { 57577836SJohn.Forte@Sun.COM int ret; 57587836SJohn.Forte@Sun.COM int fd; 57597836SJohn.Forte@Sun.COM 57607836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 57617836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 57627836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 57637836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 57647836SJohn.Forte@Sun.COM } 57657836SJohn.Forte@Sun.COM 57667836SJohn.Forte@Sun.COM /* call init */ 57677836SJohn.Forte@Sun.COM ret = initializeConfig(); 57687836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 57697836SJohn.Forte@Sun.COM return (ret); 57707836SJohn.Forte@Sun.COM } 57717836SJohn.Forte@Sun.COM 57727836SJohn.Forte@Sun.COM /* 57737836SJohn.Forte@Sun.COM * Open control node for stmf 57747836SJohn.Forte@Sun.COM */ 57757836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 57767836SJohn.Forte@Sun.COM return (ret); 57777836SJohn.Forte@Sun.COM 57787836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY, 57797836SJohn.Forte@Sun.COM hostGroupName, hostName)) != STMF_STATUS_SUCCESS) { 57807836SJohn.Forte@Sun.COM goto done; 57817836SJohn.Forte@Sun.COM } 57827836SJohn.Forte@Sun.COM 57839585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 57849585STim.Szeto@Sun.COM goto done; 57859585STim.Szeto@Sun.COM } 57869585STim.Szeto@Sun.COM 57877836SJohn.Forte@Sun.COM ret = psRemoveHostGroupMember((char *)hostGroupName, 57887836SJohn.Forte@Sun.COM (char *)hostName->ident); 57897836SJohn.Forte@Sun.COM switch (ret) { 57907836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 57917836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 57927836SJohn.Forte@Sun.COM break; 57937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 57947836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 57957836SJohn.Forte@Sun.COM break; 57967836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 57977836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 57987836SJohn.Forte@Sun.COM break; 57997836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 58007836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 58017836SJohn.Forte@Sun.COM break; 58027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 58037836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 58047836SJohn.Forte@Sun.COM break; 58057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 58067836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 58077836SJohn.Forte@Sun.COM break; 58087836SJohn.Forte@Sun.COM default: 58097836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 58107836SJohn.Forte@Sun.COM "stmfRemoveFromHostGroup" 58117836SJohn.Forte@Sun.COM "psRemoveHostGroupMember:error(%d)", ret); 58127836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 58137836SJohn.Forte@Sun.COM break; 58147836SJohn.Forte@Sun.COM } 58157836SJohn.Forte@Sun.COM 58167836SJohn.Forte@Sun.COM done: 58177836SJohn.Forte@Sun.COM (void) close(fd); 58187836SJohn.Forte@Sun.COM return (ret); 58197836SJohn.Forte@Sun.COM } 58207836SJohn.Forte@Sun.COM 58217836SJohn.Forte@Sun.COM /* 58227836SJohn.Forte@Sun.COM * stmfRemoveFromTargetGroup 58237836SJohn.Forte@Sun.COM * 58247836SJohn.Forte@Sun.COM * Purpose: Removes a local port from a local port group 58257836SJohn.Forte@Sun.COM * 58267836SJohn.Forte@Sun.COM * targetGroupName - name of a target group 58277836SJohn.Forte@Sun.COM * targetName - name of target to remove 58287836SJohn.Forte@Sun.COM */ 58297836SJohn.Forte@Sun.COM int 58307836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 58317836SJohn.Forte@Sun.COM { 58327836SJohn.Forte@Sun.COM int ret; 58337836SJohn.Forte@Sun.COM int fd; 58347836SJohn.Forte@Sun.COM 58357836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 58367836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 58377836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 58387836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 58397836SJohn.Forte@Sun.COM } 58407836SJohn.Forte@Sun.COM 58417836SJohn.Forte@Sun.COM /* call init */ 58427836SJohn.Forte@Sun.COM ret = initializeConfig(); 58437836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 58447836SJohn.Forte@Sun.COM return (ret); 58457836SJohn.Forte@Sun.COM } 58467836SJohn.Forte@Sun.COM 58477836SJohn.Forte@Sun.COM /* 58487836SJohn.Forte@Sun.COM * Open control node for stmf 58497836SJohn.Forte@Sun.COM */ 58507836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 58517836SJohn.Forte@Sun.COM return (ret); 58527836SJohn.Forte@Sun.COM 58537836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY, 58547836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 58557836SJohn.Forte@Sun.COM goto done; 58567836SJohn.Forte@Sun.COM } 58577836SJohn.Forte@Sun.COM 58589585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 58599585STim.Szeto@Sun.COM goto done; 58609585STim.Szeto@Sun.COM } 58619585STim.Szeto@Sun.COM 58627836SJohn.Forte@Sun.COM ret = psRemoveTargetGroupMember((char *)targetGroupName, 58637836SJohn.Forte@Sun.COM (char *)targetName->ident); 58647836SJohn.Forte@Sun.COM switch (ret) { 58657836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 58667836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 58677836SJohn.Forte@Sun.COM break; 58687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 58697836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 58707836SJohn.Forte@Sun.COM break; 58717836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 58727836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 58737836SJohn.Forte@Sun.COM break; 58747836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 58757836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 58767836SJohn.Forte@Sun.COM break; 58777836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 58787836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 58797836SJohn.Forte@Sun.COM break; 58807836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 58817836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 58827836SJohn.Forte@Sun.COM break; 58837836SJohn.Forte@Sun.COM default: 58847836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 58857836SJohn.Forte@Sun.COM "stmfRemoveFromTargetGroup" 58867836SJohn.Forte@Sun.COM "psRemoveTargetGroupMember:error(%d)", ret); 58877836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 58887836SJohn.Forte@Sun.COM break; 58897836SJohn.Forte@Sun.COM } 58907836SJohn.Forte@Sun.COM 58917836SJohn.Forte@Sun.COM done: 58927836SJohn.Forte@Sun.COM (void) close(fd); 58937836SJohn.Forte@Sun.COM return (ret); 58947836SJohn.Forte@Sun.COM } 58957836SJohn.Forte@Sun.COM 58967836SJohn.Forte@Sun.COM /* 58977836SJohn.Forte@Sun.COM * stmfRemoveViewEntry 58987836SJohn.Forte@Sun.COM * 58997836SJohn.Forte@Sun.COM * Purpose: Removes a view entry from a logical unit 59007836SJohn.Forte@Sun.COM * 59017836SJohn.Forte@Sun.COM * lu - guid of lu for which view entry is being removed 59027836SJohn.Forte@Sun.COM * viewEntryIndex - index of view entry to remove 59037836SJohn.Forte@Sun.COM * 59047836SJohn.Forte@Sun.COM */ 59057836SJohn.Forte@Sun.COM int 59067836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex) 59077836SJohn.Forte@Sun.COM { 59087836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 59097836SJohn.Forte@Sun.COM int fd; 59107836SJohn.Forte@Sun.COM int ioctlRet; 59117836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 59127836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 59137836SJohn.Forte@Sun.COM 59147836SJohn.Forte@Sun.COM if (lu == NULL) { 59157836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 59167836SJohn.Forte@Sun.COM } 59177836SJohn.Forte@Sun.COM 59187836SJohn.Forte@Sun.COM /* call init */ 59197836SJohn.Forte@Sun.COM ret = initializeConfig(); 59207836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 59217836SJohn.Forte@Sun.COM return (ret); 59227836SJohn.Forte@Sun.COM } 59237836SJohn.Forte@Sun.COM 59247836SJohn.Forte@Sun.COM /* 59257836SJohn.Forte@Sun.COM * Open control node for stmf 59267836SJohn.Forte@Sun.COM */ 59277836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 59287836SJohn.Forte@Sun.COM return (ret); 59297836SJohn.Forte@Sun.COM 59307836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 59317836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx_valid = B_TRUE; 59327836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx = viewEntryIndex; 59337836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 59347836SJohn.Forte@Sun.COM 59357836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 59367836SJohn.Forte@Sun.COM /* 59377836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 59387836SJohn.Forte@Sun.COM */ 59397836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 59407836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 59417836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 59427836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl); 59437836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 59447836SJohn.Forte@Sun.COM switch (errno) { 59457836SJohn.Forte@Sun.COM case EBUSY: 59467836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 59477836SJohn.Forte@Sun.COM break; 59489585STim.Szeto@Sun.COM case EPERM: 59499585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 59509585STim.Szeto@Sun.COM break; 59517836SJohn.Forte@Sun.COM case EACCES: 59527836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 59537836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 59547836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 59557836SJohn.Forte@Sun.COM break; 59567836SJohn.Forte@Sun.COM default: 59577836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 59587836SJohn.Forte@Sun.COM break; 59597836SJohn.Forte@Sun.COM } 59607836SJohn.Forte@Sun.COM break; 59617836SJohn.Forte@Sun.COM case ENODEV: 59627836SJohn.Forte@Sun.COM case ENOENT: 59637836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 59647836SJohn.Forte@Sun.COM break; 59657836SJohn.Forte@Sun.COM default: 59667836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 59677836SJohn.Forte@Sun.COM "stmfRemoveViewEntry:ioctl errno(%d)", 59687836SJohn.Forte@Sun.COM errno); 59697836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 59707836SJohn.Forte@Sun.COM break; 59717836SJohn.Forte@Sun.COM } 59727836SJohn.Forte@Sun.COM goto done; 59737836SJohn.Forte@Sun.COM } 59747836SJohn.Forte@Sun.COM 59759585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 59769585STim.Szeto@Sun.COM goto done; 59779585STim.Szeto@Sun.COM } 59789585STim.Szeto@Sun.COM 59797836SJohn.Forte@Sun.COM ret = psRemoveViewEntry(lu, viewEntryIndex); 59807836SJohn.Forte@Sun.COM switch (ret) { 59817836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 59827836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 59837836SJohn.Forte@Sun.COM break; 59847836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 59857836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 59867836SJohn.Forte@Sun.COM break; 59877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 59887836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 59897836SJohn.Forte@Sun.COM break; 59907836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 59917836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 59927836SJohn.Forte@Sun.COM break; 59937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 59947836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 59957836SJohn.Forte@Sun.COM break; 59967836SJohn.Forte@Sun.COM default: 59977836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 59987836SJohn.Forte@Sun.COM "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)", 59997836SJohn.Forte@Sun.COM ret); 60007836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 60017836SJohn.Forte@Sun.COM break; 60027836SJohn.Forte@Sun.COM } 60037836SJohn.Forte@Sun.COM 60047836SJohn.Forte@Sun.COM done: 60057836SJohn.Forte@Sun.COM (void) close(fd); 60067836SJohn.Forte@Sun.COM return (ret); 60077836SJohn.Forte@Sun.COM } 60087836SJohn.Forte@Sun.COM 60097836SJohn.Forte@Sun.COM /* 60107836SJohn.Forte@Sun.COM * stmfSetProviderData 60117836SJohn.Forte@Sun.COM * 60127836SJohn.Forte@Sun.COM * Purpose: set the provider data 60137836SJohn.Forte@Sun.COM * 60147836SJohn.Forte@Sun.COM * providerName - unique name of provider 60157836SJohn.Forte@Sun.COM * nvl - nvlist to set 60167836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 60177836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 60187836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 60197836SJohn.Forte@Sun.COM */ 60207836SJohn.Forte@Sun.COM int 60217836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType) 60227836SJohn.Forte@Sun.COM { 60237836SJohn.Forte@Sun.COM return (stmfSetProviderDataProt(providerName, nvl, providerType, 60247836SJohn.Forte@Sun.COM NULL)); 60257836SJohn.Forte@Sun.COM } 60267836SJohn.Forte@Sun.COM 60277836SJohn.Forte@Sun.COM /* 60287836SJohn.Forte@Sun.COM * stmfSetProviderDataProt 60297836SJohn.Forte@Sun.COM * 60307836SJohn.Forte@Sun.COM * Purpose: set the provider data 60317836SJohn.Forte@Sun.COM * 60327836SJohn.Forte@Sun.COM * providerName - unique name of provider 60337836SJohn.Forte@Sun.COM * nvl - nvlist to set 60347836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 60357836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 60367836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 60377836SJohn.Forte@Sun.COM * setToken - Stale data token returned in the stmfGetProviderDataProt() 60387836SJohn.Forte@Sun.COM * call or NULL. 60397836SJohn.Forte@Sun.COM */ 60407836SJohn.Forte@Sun.COM int 60417836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, 60427836SJohn.Forte@Sun.COM uint64_t *setToken) 60437836SJohn.Forte@Sun.COM { 60447836SJohn.Forte@Sun.COM int ret; 60457836SJohn.Forte@Sun.COM int fd; 60467836SJohn.Forte@Sun.COM 60477836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 60487836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 60497836SJohn.Forte@Sun.COM } 60507836SJohn.Forte@Sun.COM 60517836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 60527836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 60537836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 60547836SJohn.Forte@Sun.COM } 60557836SJohn.Forte@Sun.COM 60567836SJohn.Forte@Sun.COM /* call init */ 60577836SJohn.Forte@Sun.COM ret = initializeConfig(); 60587836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 60597836SJohn.Forte@Sun.COM return (ret); 60607836SJohn.Forte@Sun.COM } 60617836SJohn.Forte@Sun.COM 60627836SJohn.Forte@Sun.COM /* 60637836SJohn.Forte@Sun.COM * Open control node for stmf 60647836SJohn.Forte@Sun.COM */ 60657836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 60667836SJohn.Forte@Sun.COM return (ret); 60677836SJohn.Forte@Sun.COM 60689585STim.Szeto@Sun.COM ret = setProviderData(fd, providerName, nvl, providerType, setToken); 60697836SJohn.Forte@Sun.COM 60707836SJohn.Forte@Sun.COM (void) close(fd); 60717836SJohn.Forte@Sun.COM 60727836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 60737836SJohn.Forte@Sun.COM goto done; 60747836SJohn.Forte@Sun.COM } 60757836SJohn.Forte@Sun.COM 60769585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 60779585STim.Szeto@Sun.COM goto done; 60789585STim.Szeto@Sun.COM } 60799585STim.Szeto@Sun.COM 60807836SJohn.Forte@Sun.COM /* setting driver provider data successful. Now persist it */ 60819585STim.Szeto@Sun.COM ret = psSetProviderData(providerName, nvl, providerType, NULL); 60827836SJohn.Forte@Sun.COM switch (ret) { 60837836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 60847836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 60857836SJohn.Forte@Sun.COM break; 60867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 60877836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 60887836SJohn.Forte@Sun.COM break; 60897836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 60907836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 60917836SJohn.Forte@Sun.COM break; 60927836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 60937836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 60947836SJohn.Forte@Sun.COM break; 60957836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 60967836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 60977836SJohn.Forte@Sun.COM break; 60987836SJohn.Forte@Sun.COM case STMF_PS_ERROR_PROV_DATA_STALE: 60997836SJohn.Forte@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 61007836SJohn.Forte@Sun.COM break; 61017836SJohn.Forte@Sun.COM default: 61027836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 61037836SJohn.Forte@Sun.COM "stmfSetProviderData" 61047836SJohn.Forte@Sun.COM "psSetProviderData:error(%d)", ret); 61057836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 61067836SJohn.Forte@Sun.COM break; 61077836SJohn.Forte@Sun.COM } 61087836SJohn.Forte@Sun.COM 61097836SJohn.Forte@Sun.COM done: 61107836SJohn.Forte@Sun.COM return (ret); 61117836SJohn.Forte@Sun.COM } 61127836SJohn.Forte@Sun.COM 61137836SJohn.Forte@Sun.COM /* 61149585STim.Szeto@Sun.COM * getProviderData 61159585STim.Szeto@Sun.COM * 61169585STim.Szeto@Sun.COM * Purpose: set the provider data from stmf 61179585STim.Szeto@Sun.COM * 61189585STim.Szeto@Sun.COM * providerName - unique name of provider 61199585STim.Szeto@Sun.COM * nvl - nvlist to load/retrieve 61209585STim.Szeto@Sun.COM * providerType - logical unit or port provider 61219585STim.Szeto@Sun.COM * setToken - returned stale data token 61229585STim.Szeto@Sun.COM */ 61239585STim.Szeto@Sun.COM int 61249585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType, 61259585STim.Szeto@Sun.COM uint64_t *setToken) 61269585STim.Szeto@Sun.COM { 61279585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 61289585STim.Szeto@Sun.COM int fd; 61299585STim.Szeto@Sun.COM int ioctlRet; 61309585STim.Szeto@Sun.COM size_t nvlistSize = ALLOC_PP_DATA_SIZE; 61319585STim.Szeto@Sun.COM int retryCnt = 0; 61329585STim.Szeto@Sun.COM int retryCntMax = MAX_PROVIDER_RETRY; 61339585STim.Szeto@Sun.COM stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL; 61349585STim.Szeto@Sun.COM boolean_t retry = B_TRUE; 61359585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 61369585STim.Szeto@Sun.COM 61379585STim.Szeto@Sun.COM if (providerName == NULL) { 61389585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 61399585STim.Szeto@Sun.COM } 61409585STim.Szeto@Sun.COM 61419585STim.Szeto@Sun.COM /* 61429585STim.Szeto@Sun.COM * Open control node for stmf 61439585STim.Szeto@Sun.COM */ 61449585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 61459585STim.Szeto@Sun.COM return (ret); 61469585STim.Szeto@Sun.COM 61479585STim.Szeto@Sun.COM /* set provider name and provider type */ 61489585STim.Szeto@Sun.COM if (strlcpy(ppi.ppi_name, providerName, 61499585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) >= 61509585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) { 61519585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 61529585STim.Szeto@Sun.COM goto done; 61539585STim.Szeto@Sun.COM } 61549585STim.Szeto@Sun.COM switch (providerType) { 61559585STim.Szeto@Sun.COM case STMF_LU_PROVIDER_TYPE: 61569585STim.Szeto@Sun.COM ppi.ppi_lu_provider = 1; 61579585STim.Szeto@Sun.COM break; 61589585STim.Szeto@Sun.COM case STMF_PORT_PROVIDER_TYPE: 61599585STim.Szeto@Sun.COM ppi.ppi_port_provider = 1; 61609585STim.Szeto@Sun.COM break; 61619585STim.Szeto@Sun.COM default: 61629585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 61639585STim.Szeto@Sun.COM goto done; 61649585STim.Szeto@Sun.COM } 61659585STim.Szeto@Sun.COM 61669585STim.Szeto@Sun.COM do { 61679585STim.Szeto@Sun.COM /* allocate memory for ioctl */ 61689585STim.Szeto@Sun.COM ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize + 61699585STim.Szeto@Sun.COM sizeof (stmf_ppioctl_data_t)); 61709585STim.Szeto@Sun.COM if (ppi_out == NULL) { 61719585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 61729585STim.Szeto@Sun.COM goto done; 61739585STim.Szeto@Sun.COM 61749585STim.Szeto@Sun.COM } 61759585STim.Szeto@Sun.COM 61769585STim.Szeto@Sun.COM /* set the size of the ioctl data to allocated buffer */ 61779585STim.Szeto@Sun.COM ppi.ppi_data_size = nvlistSize; 61789585STim.Szeto@Sun.COM 61799585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 61809585STim.Szeto@Sun.COM 61819585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 61829585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 61839585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 61849585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) + 61859585STim.Szeto@Sun.COM nvlistSize; 61869585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out; 61879585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl); 61889585STim.Szeto@Sun.COM if (ioctlRet != 0) { 61899585STim.Szeto@Sun.COM switch (errno) { 61909585STim.Szeto@Sun.COM case EBUSY: 61919585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 61929585STim.Szeto@Sun.COM break; 61939585STim.Szeto@Sun.COM case EPERM: 61949585STim.Szeto@Sun.COM case EACCES: 61959585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 61969585STim.Szeto@Sun.COM break; 61979585STim.Szeto@Sun.COM case EINVAL: 61989585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 61999585STim.Szeto@Sun.COM STMF_IOCERR_INSUFFICIENT_BUF) { 62009585STim.Szeto@Sun.COM nvlistSize = 62019585STim.Szeto@Sun.COM ppi_out->ppi_data_size; 62029585STim.Szeto@Sun.COM free(ppi_out); 62039585STim.Szeto@Sun.COM ppi_out = NULL; 62049585STim.Szeto@Sun.COM if (retryCnt++ > retryCntMax) { 62059585STim.Szeto@Sun.COM retry = B_FALSE; 62069585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 62079585STim.Szeto@Sun.COM } else { 62089585STim.Szeto@Sun.COM ret = 62099585STim.Szeto@Sun.COM STMF_STATUS_SUCCESS; 62109585STim.Szeto@Sun.COM } 62119585STim.Szeto@Sun.COM } else { 62129585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 62139585STim.Szeto@Sun.COM "getProviderData:ioctl" 62149585STim.Szeto@Sun.COM "unable to retrieve " 62159585STim.Szeto@Sun.COM "nvlist"); 62169585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 62179585STim.Szeto@Sun.COM } 62189585STim.Szeto@Sun.COM break; 62199585STim.Szeto@Sun.COM case ENOENT: 62209585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 62219585STim.Szeto@Sun.COM break; 62229585STim.Szeto@Sun.COM default: 62239585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 62249585STim.Szeto@Sun.COM "getProviderData:ioctl errno(%d)", 62259585STim.Szeto@Sun.COM errno); 62269585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 62279585STim.Szeto@Sun.COM break; 62289585STim.Szeto@Sun.COM } 62299585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) 62309585STim.Szeto@Sun.COM goto done; 62319585STim.Szeto@Sun.COM } 62329585STim.Szeto@Sun.COM } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF); 62339585STim.Szeto@Sun.COM 62349585STim.Szeto@Sun.COM if ((ret = nvlist_unpack((char *)ppi_out->ppi_data, 62359585STim.Szeto@Sun.COM ppi_out->ppi_data_size, nvl, 0)) != 0) { 62369585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 62379585STim.Szeto@Sun.COM goto done; 62389585STim.Szeto@Sun.COM } 62399585STim.Szeto@Sun.COM 62409585STim.Szeto@Sun.COM /* caller has asked for new token */ 62419585STim.Szeto@Sun.COM if (setToken) { 62429585STim.Szeto@Sun.COM *setToken = ppi_out->ppi_token; 62439585STim.Szeto@Sun.COM } 62449585STim.Szeto@Sun.COM done: 62459585STim.Szeto@Sun.COM free(ppi_out); 62469585STim.Szeto@Sun.COM (void) close(fd); 62479585STim.Szeto@Sun.COM return (ret); 62489585STim.Szeto@Sun.COM } 62499585STim.Szeto@Sun.COM 62509585STim.Szeto@Sun.COM /* 62517836SJohn.Forte@Sun.COM * setProviderData 62527836SJohn.Forte@Sun.COM * 62539585STim.Szeto@Sun.COM * Purpose: set the provider data in stmf 62547836SJohn.Forte@Sun.COM * 62557836SJohn.Forte@Sun.COM * providerName - unique name of provider 62567836SJohn.Forte@Sun.COM * nvl - nvlist to set 62577836SJohn.Forte@Sun.COM * providerType - logical unit or port provider 62589585STim.Szeto@Sun.COM * setToken - stale data token to check if not NULL 62597836SJohn.Forte@Sun.COM */ 62607836SJohn.Forte@Sun.COM static int 62619585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType, 62629585STim.Szeto@Sun.COM uint64_t *setToken) 62637836SJohn.Forte@Sun.COM { 62647836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 62657836SJohn.Forte@Sun.COM int ioctlRet; 62667836SJohn.Forte@Sun.COM size_t nvlistEncodedSize; 62677836SJohn.Forte@Sun.COM stmf_ppioctl_data_t *ppi = NULL; 62689585STim.Szeto@Sun.COM uint64_t outToken; 62697836SJohn.Forte@Sun.COM char *allocatedNvBuffer; 62707836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 62717836SJohn.Forte@Sun.COM 62727836SJohn.Forte@Sun.COM if (providerName == NULL) { 62737836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 62747836SJohn.Forte@Sun.COM } 62757836SJohn.Forte@Sun.COM 62767836SJohn.Forte@Sun.COM /* get size of encoded nvlist */ 62777836SJohn.Forte@Sun.COM if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) { 62787836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 62797836SJohn.Forte@Sun.COM } 62807836SJohn.Forte@Sun.COM 62817836SJohn.Forte@Sun.COM /* allocate memory for ioctl */ 62827836SJohn.Forte@Sun.COM ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize + 62837836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t)); 62847836SJohn.Forte@Sun.COM if (ppi == NULL) { 62857836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 62867836SJohn.Forte@Sun.COM } 62877836SJohn.Forte@Sun.COM 62889585STim.Szeto@Sun.COM if (setToken) { 62899585STim.Szeto@Sun.COM ppi->ppi_token_valid = 1; 62909585STim.Szeto@Sun.COM ppi->ppi_token = *setToken; 62919585STim.Szeto@Sun.COM } 62929585STim.Szeto@Sun.COM 62937836SJohn.Forte@Sun.COM allocatedNvBuffer = (char *)&ppi->ppi_data; 62947836SJohn.Forte@Sun.COM if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize, 62957836SJohn.Forte@Sun.COM NV_ENCODE_XDR, 0) != 0) { 62967836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 62977836SJohn.Forte@Sun.COM } 62987836SJohn.Forte@Sun.COM 62997836SJohn.Forte@Sun.COM /* set provider name and provider type */ 63007836SJohn.Forte@Sun.COM (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name)); 63017836SJohn.Forte@Sun.COM switch (providerType) { 63027836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 63037836SJohn.Forte@Sun.COM ppi->ppi_lu_provider = 1; 63047836SJohn.Forte@Sun.COM break; 63057836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 63067836SJohn.Forte@Sun.COM ppi->ppi_port_provider = 1; 63077836SJohn.Forte@Sun.COM break; 63087836SJohn.Forte@Sun.COM default: 63097836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 63107836SJohn.Forte@Sun.COM } 63117836SJohn.Forte@Sun.COM 63127836SJohn.Forte@Sun.COM /* set the size of the ioctl data to packed data size */ 63137836SJohn.Forte@Sun.COM ppi->ppi_data_size = nvlistEncodedSize; 63147836SJohn.Forte@Sun.COM 63157836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 63167836SJohn.Forte@Sun.COM 63177836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 63187836SJohn.Forte@Sun.COM /* 63197836SJohn.Forte@Sun.COM * Subtracting 8 from the size as that is the size of the last member 63207836SJohn.Forte@Sun.COM * of the structure where the packed data resides 63217836SJohn.Forte@Sun.COM */ 63227836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = nvlistEncodedSize + 63237836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t) - 8; 63247836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi; 63259585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (uint64_t); 63269585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken; 63277836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl); 63287836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 63297836SJohn.Forte@Sun.COM switch (errno) { 63307836SJohn.Forte@Sun.COM case EBUSY: 63317836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 63327836SJohn.Forte@Sun.COM break; 63339585STim.Szeto@Sun.COM case EPERM: 63347836SJohn.Forte@Sun.COM case EACCES: 63357836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 63367836SJohn.Forte@Sun.COM break; 63379585STim.Szeto@Sun.COM case EINVAL: 63389585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 63399585STim.Szeto@Sun.COM STMF_IOCERR_PPD_UPDATED) { 63409585STim.Szeto@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 63419585STim.Szeto@Sun.COM } else { 63429585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 63439585STim.Szeto@Sun.COM } 63449585STim.Szeto@Sun.COM break; 63457836SJohn.Forte@Sun.COM default: 63467836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 63477836SJohn.Forte@Sun.COM "setProviderData:ioctl errno(%d)", errno); 63487836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 63497836SJohn.Forte@Sun.COM break; 63507836SJohn.Forte@Sun.COM } 63517836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) 63527836SJohn.Forte@Sun.COM goto done; 63537836SJohn.Forte@Sun.COM } 63547836SJohn.Forte@Sun.COM 63559585STim.Szeto@Sun.COM /* caller has asked for new token */ 63569585STim.Szeto@Sun.COM if (setToken) { 63579585STim.Szeto@Sun.COM *setToken = outToken; 63589585STim.Szeto@Sun.COM } 63597836SJohn.Forte@Sun.COM done: 63607836SJohn.Forte@Sun.COM free(ppi); 63617836SJohn.Forte@Sun.COM return (ret); 63627836SJohn.Forte@Sun.COM } 63639585STim.Szeto@Sun.COM 63649585STim.Szeto@Sun.COM /* 63659585STim.Szeto@Sun.COM * set the persistence method in the library only or library and service 63669585STim.Szeto@Sun.COM */ 63679585STim.Szeto@Sun.COM int 63689585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet) 63699585STim.Szeto@Sun.COM { 63709585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 63719585STim.Szeto@Sun.COM int oldPersist; 63729585STim.Szeto@Sun.COM 63739585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 63749585STim.Szeto@Sun.COM oldPersist = iPersistType; 63759585STim.Szeto@Sun.COM if (persistType == STMF_PERSIST_NONE || 63769585STim.Szeto@Sun.COM persistType == STMF_PERSIST_SMF) { 63779585STim.Szeto@Sun.COM iLibSetPersist = B_TRUE; 63789585STim.Szeto@Sun.COM iPersistType = persistType; 63799585STim.Szeto@Sun.COM } else { 63809585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 63819585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 63829585STim.Szeto@Sun.COM } 63839585STim.Szeto@Sun.COM /* Is this for this library open or in SMF */ 63849585STim.Szeto@Sun.COM if (serviceSet == B_TRUE) { 63859585STim.Szeto@Sun.COM ret = psSetServicePersist(persistType); 63869585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 63879585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 63889585STim.Szeto@Sun.COM /* Set to old value */ 63899585STim.Szeto@Sun.COM iPersistType = oldPersist; 63909585STim.Szeto@Sun.COM } 63919585STim.Szeto@Sun.COM } 63929585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 63939585STim.Szeto@Sun.COM 63949585STim.Szeto@Sun.COM return (ret); 63959585STim.Szeto@Sun.COM } 63969585STim.Szeto@Sun.COM 63979585STim.Szeto@Sun.COM /* 63989585STim.Szeto@Sun.COM * Only returns internal state for persist. If unset, goes to ps. If that 63999585STim.Szeto@Sun.COM * fails, returns default setting 64009585STim.Szeto@Sun.COM */ 64019585STim.Szeto@Sun.COM static uint8_t 64029585STim.Szeto@Sun.COM iGetPersistMethod() 64039585STim.Szeto@Sun.COM { 64049585STim.Szeto@Sun.COM 64059585STim.Szeto@Sun.COM uint8_t persistType = 0; 64069585STim.Szeto@Sun.COM 64079585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 64089585STim.Szeto@Sun.COM if (iLibSetPersist) { 64099585STim.Szeto@Sun.COM persistType = iPersistType; 64109585STim.Szeto@Sun.COM } else { 64119585STim.Szeto@Sun.COM int ret; 64129585STim.Szeto@Sun.COM ret = psGetServicePersist(&persistType); 64139585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 64149585STim.Szeto@Sun.COM /* set to default */ 64159585STim.Szeto@Sun.COM persistType = STMF_DEFAULT_PERSIST; 64169585STim.Szeto@Sun.COM } 64179585STim.Szeto@Sun.COM } 64189585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 64199585STim.Szeto@Sun.COM return (persistType); 64209585STim.Szeto@Sun.COM } 64219585STim.Szeto@Sun.COM 64229585STim.Szeto@Sun.COM /* 64239585STim.Szeto@Sun.COM * Returns either library state or persistent config state depending on 64249585STim.Szeto@Sun.COM * serviceState 64259585STim.Szeto@Sun.COM */ 64269585STim.Szeto@Sun.COM int 64279585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState) 64289585STim.Szeto@Sun.COM { 64299585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 64309585STim.Szeto@Sun.COM 64319585STim.Szeto@Sun.COM if (persistType == NULL) { 64329585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 64339585STim.Szeto@Sun.COM } 64349585STim.Szeto@Sun.COM if (serviceState) { 64359585STim.Szeto@Sun.COM ret = psGetServicePersist(persistType); 64369585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 64379585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 64389585STim.Szeto@Sun.COM } 64399585STim.Szeto@Sun.COM } else { 64409585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 64419585STim.Szeto@Sun.COM if (iLibSetPersist) { 64429585STim.Szeto@Sun.COM *persistType = iPersistType; 64439585STim.Szeto@Sun.COM } else { 64449585STim.Szeto@Sun.COM *persistType = STMF_DEFAULT_PERSIST; 64459585STim.Szeto@Sun.COM } 64469585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 64479585STim.Szeto@Sun.COM } 64489585STim.Szeto@Sun.COM 64499585STim.Szeto@Sun.COM return (ret); 64509585STim.Szeto@Sun.COM } 645110691STim.Szeto@Sun.COM 645210691STim.Szeto@Sun.COM /* 645310725SJohn.Forte@Sun.COM * stmfPostProxyMsg 645410725SJohn.Forte@Sun.COM * 645510725SJohn.Forte@Sun.COM * Purpose: Post a message to the proxy port provider 645610725SJohn.Forte@Sun.COM * 645710725SJohn.Forte@Sun.COM * buf - buffer containing message to post 645810725SJohn.Forte@Sun.COM * buflen - buffer length 645910725SJohn.Forte@Sun.COM */ 646010725SJohn.Forte@Sun.COM int 646110725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen) 646210725SJohn.Forte@Sun.COM { 646310725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 646410725SJohn.Forte@Sun.COM int ioctlRet; 646510725SJohn.Forte@Sun.COM pppt_iocdata_t ppptIoctl = {0}; 646610725SJohn.Forte@Sun.COM 646710725SJohn.Forte@Sun.COM if (buf == NULL) { 646810725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 646910725SJohn.Forte@Sun.COM } 647010725SJohn.Forte@Sun.COM 647110725SJohn.Forte@Sun.COM /* 647210725SJohn.Forte@Sun.COM * Issue ioctl to post the message 647310725SJohn.Forte@Sun.COM */ 647410725SJohn.Forte@Sun.COM ppptIoctl.pppt_version = PPPT_VERSION_1; 647510725SJohn.Forte@Sun.COM ppptIoctl.pppt_buf_size = buflen; 647610725SJohn.Forte@Sun.COM ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf; 647710725SJohn.Forte@Sun.COM ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl); 647810725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 647910725SJohn.Forte@Sun.COM switch (errno) { 648010725SJohn.Forte@Sun.COM case EPERM: 648110725SJohn.Forte@Sun.COM case EACCES: 648210725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 648310725SJohn.Forte@Sun.COM break; 648410725SJohn.Forte@Sun.COM default: 648510725SJohn.Forte@Sun.COM ret = STMF_ERROR_POST_MSG_FAILED; 648610725SJohn.Forte@Sun.COM break; 648710725SJohn.Forte@Sun.COM } 648810725SJohn.Forte@Sun.COM } 648910725SJohn.Forte@Sun.COM 649010725SJohn.Forte@Sun.COM return (ret); 649110725SJohn.Forte@Sun.COM } 649210725SJohn.Forte@Sun.COM 649310725SJohn.Forte@Sun.COM /* 649410725SJohn.Forte@Sun.COM * stmfInitProxyDoor 649510725SJohn.Forte@Sun.COM * 649610725SJohn.Forte@Sun.COM * Purpose: Install door in proxy 649710725SJohn.Forte@Sun.COM * 649810725SJohn.Forte@Sun.COM * hdl - pointer to returned handle 649910725SJohn.Forte@Sun.COM * fd - door from door_create() 650010725SJohn.Forte@Sun.COM */ 650110725SJohn.Forte@Sun.COM int 650210725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door) 650310725SJohn.Forte@Sun.COM { 650410725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 650510725SJohn.Forte@Sun.COM int ioctlRet; 650610725SJohn.Forte@Sun.COM int fd; 650710725SJohn.Forte@Sun.COM pppt_iocdata_t ppptIoctl = {0}; 650810725SJohn.Forte@Sun.COM 650910725SJohn.Forte@Sun.COM if (hdl == NULL) { 651010725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 651110725SJohn.Forte@Sun.COM } 651210725SJohn.Forte@Sun.COM 651310725SJohn.Forte@Sun.COM /* 651410725SJohn.Forte@Sun.COM * Open control node for pppt 651510725SJohn.Forte@Sun.COM */ 651610725SJohn.Forte@Sun.COM if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) { 651710725SJohn.Forte@Sun.COM return (ret); 651810725SJohn.Forte@Sun.COM } 651910725SJohn.Forte@Sun.COM 652010725SJohn.Forte@Sun.COM /* 652110725SJohn.Forte@Sun.COM * Issue ioctl to install the door 652210725SJohn.Forte@Sun.COM */ 652310725SJohn.Forte@Sun.COM ppptIoctl.pppt_version = PPPT_VERSION_1; 652410725SJohn.Forte@Sun.COM ppptIoctl.pppt_door_fd = (uint32_t)door; 652510725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl); 652610725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 652710725SJohn.Forte@Sun.COM switch (errno) { 652810725SJohn.Forte@Sun.COM case EPERM: 652910725SJohn.Forte@Sun.COM case EACCES: 653010725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 653110725SJohn.Forte@Sun.COM break; 653210725SJohn.Forte@Sun.COM case EINVAL: 653310725SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 653410725SJohn.Forte@Sun.COM break; 653510725SJohn.Forte@Sun.COM case EBUSY: 653610725SJohn.Forte@Sun.COM ret = STMF_ERROR_DOOR_INSTALLED; 653710725SJohn.Forte@Sun.COM break; 653810725SJohn.Forte@Sun.COM default: 653910725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 654010725SJohn.Forte@Sun.COM break; 654110725SJohn.Forte@Sun.COM } 654210725SJohn.Forte@Sun.COM } 654310725SJohn.Forte@Sun.COM 654410725SJohn.Forte@Sun.COM /* return driver fd to caller */ 654510725SJohn.Forte@Sun.COM *hdl = fd; 654610725SJohn.Forte@Sun.COM return (ret); 654710725SJohn.Forte@Sun.COM } 654810725SJohn.Forte@Sun.COM 654910725SJohn.Forte@Sun.COM void 655010725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl) 655110725SJohn.Forte@Sun.COM { 655210725SJohn.Forte@Sun.COM (void) close(hdl); 655310725SJohn.Forte@Sun.COM } 655410725SJohn.Forte@Sun.COM 655510725SJohn.Forte@Sun.COM /* 655610691STim.Szeto@Sun.COM * validateLunNumIoctl 655710691STim.Szeto@Sun.COM * 655810691STim.Szeto@Sun.COM * Purpose: Issues ioctl to check and get available lun# in view entry 655910691STim.Szeto@Sun.COM * 656010691STim.Szeto@Sun.COM * viewEntry - view entry to use 656110691STim.Szeto@Sun.COM */ 656210691STim.Szeto@Sun.COM static int 656310691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry) 656410691STim.Szeto@Sun.COM { 656510691STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 656610691STim.Szeto@Sun.COM int ioctlRet; 656710691STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 656810691STim.Szeto@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 656910691STim.Szeto@Sun.COM 657010691STim.Szeto@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 657110691STim.Szeto@Sun.COM /* 657210691STim.Szeto@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 657310691STim.Szeto@Sun.COM * false on input 657410691STim.Szeto@Sun.COM */ 657510691STim.Szeto@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 657610691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 657710691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 657810691STim.Szeto@Sun.COM 657910691STim.Szeto@Sun.COM if (viewEntry->allHosts == B_FALSE) { 658010691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 658110691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 658210691STim.Szeto@Sun.COM ioctlViewEntry.ve_host_group.name_size = 658310691STim.Szeto@Sun.COM strlen((char *)viewEntry->hostGroup); 658410691STim.Szeto@Sun.COM } 658510691STim.Szeto@Sun.COM if (viewEntry->allTargets == B_FALSE) { 658610691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, 658710691STim.Szeto@Sun.COM &ioctlViewEntry.ve_target_group.name, 658810691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 658910691STim.Szeto@Sun.COM ioctlViewEntry.ve_target_group.name_size = 659010691STim.Szeto@Sun.COM strlen((char *)viewEntry->targetGroup); 659110691STim.Szeto@Sun.COM } 659210691STim.Szeto@Sun.COM /* Validating the lun number */ 659310691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 659410691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 659510691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 659610691STim.Szeto@Sun.COM } 659710691STim.Szeto@Sun.COM 659810691STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 659910691STim.Szeto@Sun.COM /* 660010691STim.Szeto@Sun.COM * Issue ioctl to validate lun# in the view entry 660110691STim.Szeto@Sun.COM */ 660210691STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 660310691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 660410691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 660510691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 660610691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 660710691STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl); 660810691STim.Szeto@Sun.COM 660910691STim.Szeto@Sun.COM /* save available lun number */ 661010691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 661110691STim.Szeto@Sun.COM bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 661210691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 661310691STim.Szeto@Sun.COM } 661410691STim.Szeto@Sun.COM if (ioctlRet != 0) { 661510691STim.Szeto@Sun.COM switch (errno) { 661610691STim.Szeto@Sun.COM case EBUSY: 661710691STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 661810691STim.Szeto@Sun.COM break; 661910691STim.Szeto@Sun.COM case EPERM: 662010691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 662110691STim.Szeto@Sun.COM break; 662210691STim.Szeto@Sun.COM case EACCES: 662310691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 662410691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 662510691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 662610691STim.Szeto@Sun.COM break; 662710691STim.Szeto@Sun.COM default: 662810691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 662910691STim.Szeto@Sun.COM break; 663010691STim.Szeto@Sun.COM } 663110691STim.Szeto@Sun.COM break; 663210691STim.Szeto@Sun.COM default: 663310691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 663410691STim.Szeto@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 663510691STim.Szeto@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 663610691STim.Szeto@Sun.COM break; 663710691STim.Szeto@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 663810691STim.Szeto@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 663910691STim.Szeto@Sun.COM break; 664010691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 664110691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 664210691STim.Szeto@Sun.COM break; 664310691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_HG: 664410691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_HG; 664510691STim.Szeto@Sun.COM break; 664610691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_TG: 664710691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_TG; 664810691STim.Szeto@Sun.COM break; 664910691STim.Szeto@Sun.COM default: 665010691STim.Szeto@Sun.COM syslog(LOG_DEBUG, 665110691STim.Szeto@Sun.COM "addViewEntryIoctl" 665210691STim.Szeto@Sun.COM ":error(%d)", 665310691STim.Szeto@Sun.COM stmfIoctl.stmf_error); 665410691STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 665510691STim.Szeto@Sun.COM break; 665610691STim.Szeto@Sun.COM } 665710691STim.Szeto@Sun.COM break; 665810691STim.Szeto@Sun.COM } 665910691STim.Szeto@Sun.COM } 666010691STim.Szeto@Sun.COM return (ret); 666110691STim.Szeto@Sun.COM } 666210691STim.Szeto@Sun.COM 666310691STim.Szeto@Sun.COM /* 666410691STim.Szeto@Sun.COM * stmfValidateView 666510691STim.Szeto@Sun.COM * 666610691STim.Szeto@Sun.COM * Purpose: Validate or get lun # base on TG, HG of view entry 666710691STim.Szeto@Sun.COM * 666810691STim.Szeto@Sun.COM * viewEntry - view entry structure to use 666910691STim.Szeto@Sun.COM */ 667010691STim.Szeto@Sun.COM int 667110691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry) 667210691STim.Szeto@Sun.COM { 667310691STim.Szeto@Sun.COM int ret; 667410691STim.Szeto@Sun.COM int fd; 667510691STim.Szeto@Sun.COM stmfViewEntry iViewEntry; 667610691STim.Szeto@Sun.COM 667710691STim.Szeto@Sun.COM if (viewEntry == NULL) { 667810691STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 667910691STim.Szeto@Sun.COM } 668010691STim.Szeto@Sun.COM 668110691STim.Szeto@Sun.COM /* initialize and set internal view entry */ 668210691STim.Szeto@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 668310691STim.Szeto@Sun.COM 668410691STim.Szeto@Sun.COM if (!viewEntry->allHosts) { 668510691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 668610691STim.Szeto@Sun.COM sizeof (iViewEntry.hostGroup)); 668710691STim.Szeto@Sun.COM } else { 668810691STim.Szeto@Sun.COM iViewEntry.allHosts = B_TRUE; 668910691STim.Szeto@Sun.COM } 669010691STim.Szeto@Sun.COM 669110691STim.Szeto@Sun.COM if (!viewEntry->allTargets) { 669210691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 669310691STim.Szeto@Sun.COM sizeof (iViewEntry.targetGroup)); 669410691STim.Szeto@Sun.COM } else { 669510691STim.Szeto@Sun.COM iViewEntry.allTargets = B_TRUE; 669610691STim.Szeto@Sun.COM } 669710691STim.Szeto@Sun.COM 669810691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 669910691STim.Szeto@Sun.COM iViewEntry.luNbrValid = B_TRUE; 670010691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 670110691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 670210691STim.Szeto@Sun.COM } 670310691STim.Szeto@Sun.COM 670410691STim.Szeto@Sun.COM /* 670510691STim.Szeto@Sun.COM * set users return view entry index valid flag to false 670610691STim.Szeto@Sun.COM * in case of failure 670710691STim.Szeto@Sun.COM */ 670810691STim.Szeto@Sun.COM viewEntry->veIndexValid = B_FALSE; 670910691STim.Szeto@Sun.COM 671010691STim.Szeto@Sun.COM /* Check to ensure service exists */ 671110691STim.Szeto@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 671210691STim.Szeto@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 671310691STim.Szeto@Sun.COM } 671410691STim.Szeto@Sun.COM 671510691STim.Szeto@Sun.COM /* call init */ 671610691STim.Szeto@Sun.COM ret = initializeConfig(); 671710691STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 671810691STim.Szeto@Sun.COM return (ret); 671910691STim.Szeto@Sun.COM } 672010691STim.Szeto@Sun.COM 672110691STim.Szeto@Sun.COM /* 672210691STim.Szeto@Sun.COM * Open control node for stmf 672310691STim.Szeto@Sun.COM */ 672410691STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 672510691STim.Szeto@Sun.COM return (ret); 672610691STim.Szeto@Sun.COM 672710691STim.Szeto@Sun.COM /* 672810691STim.Szeto@Sun.COM * Validate lun# in the view entry from the driver 672910691STim.Szeto@Sun.COM */ 673010691STim.Szeto@Sun.COM ret = validateLunNumIoctl(fd, &iViewEntry); 673110691STim.Szeto@Sun.COM (void) close(fd); 673210691STim.Szeto@Sun.COM 673310691STim.Szeto@Sun.COM /* save available lun number */ 673410691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 673510691STim.Szeto@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 673610691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 673710691STim.Szeto@Sun.COM } 673810691STim.Szeto@Sun.COM 673910691STim.Szeto@Sun.COM return (ret); 674010691STim.Szeto@Sun.COM } 6741