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 /* 229585STim.Szeto@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237836SJohn.Forte@Sun.COM * Use is subject to license terms. 247836SJohn.Forte@Sun.COM */ 257836SJohn.Forte@Sun.COM 267836SJohn.Forte@Sun.COM #include <stdlib.h> 277836SJohn.Forte@Sun.COM #include <stdio.h> 287836SJohn.Forte@Sun.COM #include <wchar.h> 297836SJohn.Forte@Sun.COM #include <strings.h> 307836SJohn.Forte@Sun.COM #include <sys/types.h> 317836SJohn.Forte@Sun.COM #include <sys/stat.h> 327836SJohn.Forte@Sun.COM #include <fcntl.h> 337836SJohn.Forte@Sun.COM #include <unistd.h> 347836SJohn.Forte@Sun.COM #include <libintl.h> 357836SJohn.Forte@Sun.COM #include <errno.h> 367836SJohn.Forte@Sun.COM #include <string.h> 377836SJohn.Forte@Sun.COM #include <assert.h> 387836SJohn.Forte@Sun.COM #include <libnvpair.h> 397836SJohn.Forte@Sun.COM #include <pthread.h> 407836SJohn.Forte@Sun.COM #include <syslog.h> 417836SJohn.Forte@Sun.COM #include <libstmf.h> 427836SJohn.Forte@Sun.COM #include <netinet/in.h> 437836SJohn.Forte@Sun.COM #include <inttypes.h> 447836SJohn.Forte@Sun.COM #include <store.h> 457836SJohn.Forte@Sun.COM #include <locale.h> 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 21449585STim.Szeto@Sun.COM 21459585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 21469585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 21479585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 21489585STim.Szeto@Sun.COM return (ret); 21499585STim.Szeto@Sun.COM } else { 21509585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 21519585STim.Szeto@Sun.COM ret = getDiskAllProps(luGuid, hdl); 21529585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 21539585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 21549585STim.Szeto@Sun.COM } else { 21559585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21569585STim.Szeto@Sun.COM } 21579585STim.Szeto@Sun.COM } 21589585STim.Szeto@Sun.COM 21599585STim.Szeto@Sun.COM return (ret); 21609585STim.Szeto@Sun.COM } 21619585STim.Szeto@Sun.COM 21629585STim.Szeto@Sun.COM /* 21639585STim.Szeto@Sun.COM * getDiskAllProps 21649585STim.Szeto@Sun.COM * 21659585STim.Szeto@Sun.COM * Purpose: load all disk properties from sbd driver 21669585STim.Szeto@Sun.COM * 21679585STim.Szeto@Sun.COM * luGuid - guid of disk device for which properties are to be retrieved 21689585STim.Szeto@Sun.COM * hdl - allocated luResource into which properties are to be copied 21699585STim.Szeto@Sun.COM * 21709585STim.Szeto@Sun.COM */ 21719585STim.Szeto@Sun.COM static int 21729585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl) 21739585STim.Szeto@Sun.COM { 21749585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21759585STim.Szeto@Sun.COM int fd; 21769585STim.Szeto@Sun.COM sbd_lu_props_t *sbdProps; 21779585STim.Szeto@Sun.COM int ioctlRet; 21789585STim.Szeto@Sun.COM int savedErrno; 21799585STim.Szeto@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 21809585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 21819585STim.Szeto@Sun.COM 21829585STim.Szeto@Sun.COM /* 21839585STim.Szeto@Sun.COM * Open control node for sbd 21849585STim.Szeto@Sun.COM */ 21859585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 21869585STim.Szeto@Sun.COM return (ret); 21879585STim.Szeto@Sun.COM 21889585STim.Szeto@Sun.COM 21899585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 21909585STim.Szeto@Sun.COM if (*hdl == NULL) { 21919585STim.Szeto@Sun.COM (void) close(fd); 21929585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 21939585STim.Szeto@Sun.COM } 21949585STim.Szeto@Sun.COM 21959585STim.Szeto@Sun.COM sbdProps = calloc(1, sbdPropsSize); 21969585STim.Szeto@Sun.COM if (sbdProps == NULL) { 21979585STim.Szeto@Sun.COM free(*hdl); 21989585STim.Szeto@Sun.COM (void) close(fd); 21999585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 22009585STim.Szeto@Sun.COM } 22019585STim.Szeto@Sun.COM 22029585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 22039585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 22049585STim.Szeto@Sun.COM free(*hdl); 220510725SJohn.Forte@Sun.COM free(sbdProps); 22069585STim.Szeto@Sun.COM (void) close(fd); 22079585STim.Szeto@Sun.COM return (ret); 22089585STim.Szeto@Sun.COM } 22099585STim.Szeto@Sun.COM 22109585STim.Szeto@Sun.COM sbdProps->slp_input_guid = 1; 22119585STim.Szeto@Sun.COM bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid)); 22129585STim.Szeto@Sun.COM 22139585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 22149585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdPropsSize; 22159585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps; 22169585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 22179585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 22189585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl); 22199585STim.Szeto@Sun.COM if (ioctlRet != 0) { 22209585STim.Szeto@Sun.COM savedErrno = errno; 22219585STim.Szeto@Sun.COM switch (savedErrno) { 22229585STim.Szeto@Sun.COM case EBUSY: 22239585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 22249585STim.Szeto@Sun.COM break; 22259585STim.Szeto@Sun.COM case EPERM: 22269585STim.Szeto@Sun.COM case EACCES: 22279585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 22289585STim.Szeto@Sun.COM break; 22299585STim.Szeto@Sun.COM case ENOENT: 22309585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 22319585STim.Szeto@Sun.COM break; 22329585STim.Szeto@Sun.COM default: 22339585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 22349585STim.Szeto@Sun.COM "getDiskAllProps:ioctl error(%d) (%d) (%d)", 22359585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 22369585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 22379585STim.Szeto@Sun.COM break; 22389585STim.Szeto@Sun.COM } 22399585STim.Szeto@Sun.COM } 22409585STim.Szeto@Sun.COM 22419585STim.Szeto@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 22429585STim.Szeto@Sun.COM ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps); 22439585STim.Szeto@Sun.COM } 22449585STim.Szeto@Sun.COM 224510725SJohn.Forte@Sun.COM free(sbdProps); 22469585STim.Szeto@Sun.COM (void) close(fd); 22479585STim.Szeto@Sun.COM return (ret); 22489585STim.Szeto@Sun.COM } 22499585STim.Szeto@Sun.COM 22509585STim.Szeto@Sun.COM /* 22519585STim.Szeto@Sun.COM * loadDiskPropsFromDriver 22529585STim.Szeto@Sun.COM * 22539585STim.Szeto@Sun.COM * Purpose: Retrieve all disk type properties from sbd driver 22549585STim.Szeto@Sun.COM * 22559585STim.Szeto@Sun.COM * hdl - Allocated luResourceImpl 22569585STim.Szeto@Sun.COM * sbdProps - sbd_lu_props_t structure returned from sbd driver 22579585STim.Szeto@Sun.COM * 22589585STim.Szeto@Sun.COM */ 22599585STim.Szeto@Sun.COM static int 22609585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps) 22619585STim.Szeto@Sun.COM { 22629585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 22639585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 22649585STim.Szeto@Sun.COM /* copy guid */ 22659585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 22669585STim.Szeto@Sun.COM bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid)); 22679585STim.Szeto@Sun.COM 22689585STim.Szeto@Sun.COM if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) { 22699585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 22709585STim.Szeto@Sun.COM if (strlcpy(diskLu->luMetaFileName, 22719585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]), 22729585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) >= 22739585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 22749585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 22759585STim.Szeto@Sun.COM } 22769585STim.Szeto@Sun.COM } 22779585STim.Szeto@Sun.COM 22789585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 22799585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 22809585STim.Szeto@Sun.COM if (strlcpy(diskLu->luDataFileName, 22819585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]), 22829585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) >= 22839585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 22849585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 22859585STim.Szeto@Sun.COM } 22869585STim.Szeto@Sun.COM } 22879585STim.Szeto@Sun.COM 22889585STim.Szeto@Sun.COM if (sbdProps->slp_serial_valid) { 22899585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 22909585STim.Szeto@Sun.COM bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]), 22919585STim.Szeto@Sun.COM diskLu->serialNum, sbdProps->slp_serial_size); 22929585STim.Szeto@Sun.COM } 22939585STim.Szeto@Sun.COM 229410113SNattuvetty.Bhavyan@Sun.COM if (sbdProps->slp_mgmt_url_valid) { 229510113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 229610113SNattuvetty.Bhavyan@Sun.COM if (strlcpy(diskLu->luMgmtUrl, 229710113SNattuvetty.Bhavyan@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]), 229810113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) >= 229910113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 230010113SNattuvetty.Bhavyan@Sun.COM return (STMF_STATUS_ERROR); 230110113SNattuvetty.Bhavyan@Sun.COM } 230210113SNattuvetty.Bhavyan@Sun.COM } 230310113SNattuvetty.Bhavyan@Sun.COM 23049585STim.Szeto@Sun.COM if (sbdProps->slp_alias_valid) { 23059585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 23069585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 23079585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]), 23089585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 23099585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23109585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 23119585STim.Szeto@Sun.COM } 23129585STim.Szeto@Sun.COM } else { /* set alias to data filename if not set */ 23139585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 23149585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 23159585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 23169585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[ 23179585STim.Szeto@Sun.COM sbdProps->slp_data_fname_off]), 23189585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 23199585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23209585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 23219585STim.Szeto@Sun.COM } 23229585STim.Szeto@Sun.COM } 23239585STim.Szeto@Sun.COM } 23249585STim.Szeto@Sun.COM 23259585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 23269585STim.Szeto@Sun.COM bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid)); 23279585STim.Szeto@Sun.COM 23289585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 23299585STim.Szeto@Sun.COM bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid)); 23309585STim.Szeto@Sun.COM 23319585STim.Szeto@Sun.COM diskLu->revValid = B_TRUE; 23329585STim.Szeto@Sun.COM bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev)); 23339585STim.Szeto@Sun.COM 23349585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 23359585STim.Szeto@Sun.COM if (sbdProps->slp_write_protected) { 23369585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 23379585STim.Szeto@Sun.COM } 23389585STim.Szeto@Sun.COM 23399585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 23409585STim.Szeto@Sun.COM if (sbdProps->slp_writeback_cache_disable_cur) { 23419585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 23429585STim.Szeto@Sun.COM } 23439585STim.Szeto@Sun.COM 23449585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 23459585STim.Szeto@Sun.COM diskLu->blkSize = sbdProps->slp_blksize; 23469585STim.Szeto@Sun.COM 23479585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 23489585STim.Szeto@Sun.COM diskLu->luSize = sbdProps->slp_lu_size; 23499585STim.Szeto@Sun.COM 235010725SJohn.Forte@Sun.COM diskLu->accessState = sbdProps->slp_access_state; 235110725SJohn.Forte@Sun.COM 23529585STim.Szeto@Sun.COM return (ret); 23539585STim.Szeto@Sun.COM } 23549585STim.Szeto@Sun.COM 235511103SJohn.Forte@Sun.COM /* 235611103SJohn.Forte@Sun.COM * stmfGetGlobalLuProp 235711103SJohn.Forte@Sun.COM * 235811103SJohn.Forte@Sun.COM * Purpose: get a global property for a device type 235911103SJohn.Forte@Sun.COM * 236011103SJohn.Forte@Sun.COM */ 236111103SJohn.Forte@Sun.COM int 236211103SJohn.Forte@Sun.COM stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal, 236311103SJohn.Forte@Sun.COM size_t *propLen) 236411103SJohn.Forte@Sun.COM { 236511103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 236611103SJohn.Forte@Sun.COM if (dType != STMF_DISK || propVal == NULL) { 236711103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 236811103SJohn.Forte@Sun.COM } 236911103SJohn.Forte@Sun.COM 237011103SJohn.Forte@Sun.COM ret = getDiskGlobalProp(prop, propVal, propLen); 237111103SJohn.Forte@Sun.COM 237211103SJohn.Forte@Sun.COM return (ret); 237311103SJohn.Forte@Sun.COM } 237411103SJohn.Forte@Sun.COM 237511103SJohn.Forte@Sun.COM /* 237611103SJohn.Forte@Sun.COM * getDiskGlobalProp 237711103SJohn.Forte@Sun.COM * 237811103SJohn.Forte@Sun.COM * Purpose: get global property from sbd driver 237911103SJohn.Forte@Sun.COM * 238011103SJohn.Forte@Sun.COM */ 238111103SJohn.Forte@Sun.COM static int 238211103SJohn.Forte@Sun.COM getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen) 238311103SJohn.Forte@Sun.COM { 238411103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 238511103SJohn.Forte@Sun.COM int fd; 238611103SJohn.Forte@Sun.COM sbd_global_props_t *sbdProps; 238711103SJohn.Forte@Sun.COM void *sbd_realloc; 238811103SJohn.Forte@Sun.COM int retryCnt = 0; 238911103SJohn.Forte@Sun.COM boolean_t retry; 239011103SJohn.Forte@Sun.COM int ioctlRet; 239111103SJohn.Forte@Sun.COM int savedErrno; 239211103SJohn.Forte@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 239311103SJohn.Forte@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 239411103SJohn.Forte@Sun.COM size_t reqLen; 239511103SJohn.Forte@Sun.COM 239611103SJohn.Forte@Sun.COM switch (prop) { 239711103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 239811103SJohn.Forte@Sun.COM break; 239911103SJohn.Forte@Sun.COM default: 240011103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_PROP); 240111103SJohn.Forte@Sun.COM } 240211103SJohn.Forte@Sun.COM 240311103SJohn.Forte@Sun.COM /* 240411103SJohn.Forte@Sun.COM * Open control node for sbd 240511103SJohn.Forte@Sun.COM */ 240611103SJohn.Forte@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 240711103SJohn.Forte@Sun.COM return (ret); 240811103SJohn.Forte@Sun.COM 240911103SJohn.Forte@Sun.COM sbdProps = calloc(1, sbdPropsSize); 241011103SJohn.Forte@Sun.COM if (sbdProps == NULL) { 241111103SJohn.Forte@Sun.COM (void) close(fd); 241211103SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 241311103SJohn.Forte@Sun.COM } 241411103SJohn.Forte@Sun.COM 241511103SJohn.Forte@Sun.COM do { 241611103SJohn.Forte@Sun.COM retry = B_FALSE; 241711103SJohn.Forte@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 241811103SJohn.Forte@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 241911103SJohn.Forte@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 242011103SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl); 242111103SJohn.Forte@Sun.COM if (ioctlRet != 0) { 242211103SJohn.Forte@Sun.COM savedErrno = errno; 242311103SJohn.Forte@Sun.COM switch (savedErrno) { 242411103SJohn.Forte@Sun.COM case EBUSY: 242511103SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 242611103SJohn.Forte@Sun.COM break; 242711103SJohn.Forte@Sun.COM case EPERM: 242811103SJohn.Forte@Sun.COM case EACCES: 242911103SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 243011103SJohn.Forte@Sun.COM break; 243111103SJohn.Forte@Sun.COM case ENOMEM: 243211103SJohn.Forte@Sun.COM if (sbdIoctl.stmf_error == 243311103SJohn.Forte@Sun.COM SBD_RET_INSUFFICIENT_BUF_SPACE && 243411103SJohn.Forte@Sun.COM retryCnt++ < 3) { 243511103SJohn.Forte@Sun.COM sbdPropsSize = 243611103SJohn.Forte@Sun.COM sizeof (*sbdProps) + 243711103SJohn.Forte@Sun.COM sbdProps-> 243811103SJohn.Forte@Sun.COM mlu_buf_size_needed; 243911103SJohn.Forte@Sun.COM 244011103SJohn.Forte@Sun.COM sbd_realloc = sbdProps; 244111103SJohn.Forte@Sun.COM sbdProps = realloc(sbdProps, 244211103SJohn.Forte@Sun.COM sbdPropsSize); 244311103SJohn.Forte@Sun.COM if (sbdProps == NULL) { 244411103SJohn.Forte@Sun.COM free(sbd_realloc); 244511103SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 244611103SJohn.Forte@Sun.COM break; 244711103SJohn.Forte@Sun.COM } 244811103SJohn.Forte@Sun.COM retry = B_TRUE; 244911103SJohn.Forte@Sun.COM } else { 245011103SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 245111103SJohn.Forte@Sun.COM } 245211103SJohn.Forte@Sun.COM break; 245311103SJohn.Forte@Sun.COM default: 245411103SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 245511103SJohn.Forte@Sun.COM "getDiskGlobalProp:ioctl error(%d)" 245611103SJohn.Forte@Sun.COM "(%d)(%d)", ioctlRet, 245711103SJohn.Forte@Sun.COM sbdIoctl.stmf_error, savedErrno); 245811103SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 245911103SJohn.Forte@Sun.COM break; 246011103SJohn.Forte@Sun.COM } 246111103SJohn.Forte@Sun.COM 246211103SJohn.Forte@Sun.COM } 246311103SJohn.Forte@Sun.COM } while (retry); 246411103SJohn.Forte@Sun.COM 246511103SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 246611103SJohn.Forte@Sun.COM goto done; 246711103SJohn.Forte@Sun.COM } 246811103SJohn.Forte@Sun.COM 246911103SJohn.Forte@Sun.COM switch (prop) { 247011103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 247111103SJohn.Forte@Sun.COM if (sbdProps->mlu_mgmt_url_valid == 0) { 247211103SJohn.Forte@Sun.COM ret = STMF_ERROR_NO_PROP; 247311103SJohn.Forte@Sun.COM goto done; 247411103SJohn.Forte@Sun.COM } 247511103SJohn.Forte@Sun.COM if ((reqLen = strlcpy(propVal, (char *)&( 247611103SJohn.Forte@Sun.COM sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]), 247711103SJohn.Forte@Sun.COM *propLen)) >= *propLen) { 247811103SJohn.Forte@Sun.COM *propLen = reqLen + 1; 247911103SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 248011103SJohn.Forte@Sun.COM goto done; 248111103SJohn.Forte@Sun.COM } 248211103SJohn.Forte@Sun.COM break; 248311103SJohn.Forte@Sun.COM } 248411103SJohn.Forte@Sun.COM 248511103SJohn.Forte@Sun.COM done: 248611103SJohn.Forte@Sun.COM free(sbdProps); 248711103SJohn.Forte@Sun.COM (void) close(fd); 248811103SJohn.Forte@Sun.COM return (ret); 248911103SJohn.Forte@Sun.COM } 249011103SJohn.Forte@Sun.COM 249111103SJohn.Forte@Sun.COM /* 249211103SJohn.Forte@Sun.COM * stmfSetGlobalLuProp 249311103SJohn.Forte@Sun.COM * 249411103SJohn.Forte@Sun.COM * Purpose: set a global property for a device type 249511103SJohn.Forte@Sun.COM * 249611103SJohn.Forte@Sun.COM */ 249711103SJohn.Forte@Sun.COM int 249811103SJohn.Forte@Sun.COM stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal) 249911103SJohn.Forte@Sun.COM { 250011103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 250111103SJohn.Forte@Sun.COM if (dType != STMF_DISK || propVal == NULL) { 250211103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 250311103SJohn.Forte@Sun.COM } 250411103SJohn.Forte@Sun.COM 250511103SJohn.Forte@Sun.COM ret = setDiskGlobalProp(prop, propVal); 250611103SJohn.Forte@Sun.COM 250711103SJohn.Forte@Sun.COM return (ret); 250811103SJohn.Forte@Sun.COM } 250911103SJohn.Forte@Sun.COM 251011103SJohn.Forte@Sun.COM /* 251111103SJohn.Forte@Sun.COM * setDiskGlobalProp 251211103SJohn.Forte@Sun.COM * 251311103SJohn.Forte@Sun.COM * Purpose: set properties for resource of type disk 251411103SJohn.Forte@Sun.COM * 251511103SJohn.Forte@Sun.COM * resourceProp - valid resource identifier 251611103SJohn.Forte@Sun.COM * propVal - valid resource value 251711103SJohn.Forte@Sun.COM */ 251811103SJohn.Forte@Sun.COM static int 251911103SJohn.Forte@Sun.COM setDiskGlobalProp(uint32_t resourceProp, const char *propVal) 252011103SJohn.Forte@Sun.COM { 252111103SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 252211103SJohn.Forte@Sun.COM sbd_global_props_t *sbdGlobalProps = NULL; 252311103SJohn.Forte@Sun.COM int sbdGlobalPropsSize = 0; 252411103SJohn.Forte@Sun.COM int propLen; 252511103SJohn.Forte@Sun.COM int mluBufSize = 0; 252611103SJohn.Forte@Sun.COM int fd; 252711103SJohn.Forte@Sun.COM int savedErrno; 252811103SJohn.Forte@Sun.COM int ioctlRet; 252911103SJohn.Forte@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 253011103SJohn.Forte@Sun.COM 253111103SJohn.Forte@Sun.COM switch (resourceProp) { 253211103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 253311103SJohn.Forte@Sun.COM break; 253411103SJohn.Forte@Sun.COM default: 253511103SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_PROP); 253611103SJohn.Forte@Sun.COM break; 253711103SJohn.Forte@Sun.COM } 253811103SJohn.Forte@Sun.COM 253911103SJohn.Forte@Sun.COM /* 254011103SJohn.Forte@Sun.COM * Open control node for sbd 254111103SJohn.Forte@Sun.COM */ 254211103SJohn.Forte@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 254311103SJohn.Forte@Sun.COM return (ret); 254411103SJohn.Forte@Sun.COM 254511103SJohn.Forte@Sun.COM propLen = strlen(propVal); 254611103SJohn.Forte@Sun.COM mluBufSize += propLen + 1; 254711103SJohn.Forte@Sun.COM sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 + 254811103SJohn.Forte@Sun.COM max(8, mluBufSize); 254911103SJohn.Forte@Sun.COM /* 255011103SJohn.Forte@Sun.COM * 8 is the size of the buffer set aside for 255111103SJohn.Forte@Sun.COM * concatenation of variable length fields 255211103SJohn.Forte@Sun.COM */ 255311103SJohn.Forte@Sun.COM sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize); 255411103SJohn.Forte@Sun.COM if (sbdGlobalProps == NULL) { 255511103SJohn.Forte@Sun.COM (void) close(fd); 255611103SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 255711103SJohn.Forte@Sun.COM } 255811103SJohn.Forte@Sun.COM 255911103SJohn.Forte@Sun.COM sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize; 256011103SJohn.Forte@Sun.COM 256111103SJohn.Forte@Sun.COM switch (resourceProp) { 256211103SJohn.Forte@Sun.COM case STMF_LU_PROP_MGMT_URL: 256311103SJohn.Forte@Sun.COM sbdGlobalProps->mlu_mgmt_url_valid = 1; 256411103SJohn.Forte@Sun.COM bcopy(propVal, &(sbdGlobalProps->mlu_buf), 256511103SJohn.Forte@Sun.COM propLen + 1); 256611103SJohn.Forte@Sun.COM break; 256711103SJohn.Forte@Sun.COM default: 256811103SJohn.Forte@Sun.COM ret = STMF_ERROR_NO_PROP; 256911103SJohn.Forte@Sun.COM goto done; 257011103SJohn.Forte@Sun.COM } 257111103SJohn.Forte@Sun.COM 257211103SJohn.Forte@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 257311103SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size; 257411103SJohn.Forte@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps; 257511103SJohn.Forte@Sun.COM 257611103SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl); 257711103SJohn.Forte@Sun.COM if (ioctlRet != 0) { 257811103SJohn.Forte@Sun.COM savedErrno = errno; 257911103SJohn.Forte@Sun.COM switch (savedErrno) { 258011103SJohn.Forte@Sun.COM case EBUSY: 258111103SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 258211103SJohn.Forte@Sun.COM break; 258311103SJohn.Forte@Sun.COM case EPERM: 258411103SJohn.Forte@Sun.COM case EACCES: 258511103SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 258611103SJohn.Forte@Sun.COM break; 258711103SJohn.Forte@Sun.COM default: 258811103SJohn.Forte@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 258911103SJohn.Forte@Sun.COM if (ret == STMF_STATUS_ERROR) { 259011103SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 259111103SJohn.Forte@Sun.COM "modifyDiskLu:ioctl " 259211103SJohn.Forte@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 259311103SJohn.Forte@Sun.COM sbdIoctl.stmf_error, savedErrno); 259411103SJohn.Forte@Sun.COM } 259511103SJohn.Forte@Sun.COM break; 259611103SJohn.Forte@Sun.COM } 259711103SJohn.Forte@Sun.COM } 259811103SJohn.Forte@Sun.COM 259911103SJohn.Forte@Sun.COM done: 260011103SJohn.Forte@Sun.COM free(sbdGlobalProps); 260111103SJohn.Forte@Sun.COM (void) close(fd); 260211103SJohn.Forte@Sun.COM return (ret); 260311103SJohn.Forte@Sun.COM } 260411103SJohn.Forte@Sun.COM 26059585STim.Szeto@Sun.COM 26069585STim.Szeto@Sun.COM /* 26079585STim.Szeto@Sun.COM * stmfSetLuProp 26089585STim.Szeto@Sun.COM * 26099585STim.Szeto@Sun.COM * Purpose: set a property on an luResource 26109585STim.Szeto@Sun.COM * 26119585STim.Szeto@Sun.COM * hdl - allocated luResource 26129585STim.Szeto@Sun.COM * prop - property identifier 26139585STim.Szeto@Sun.COM * propVal - property value to be set 26149585STim.Szeto@Sun.COM */ 26159585STim.Szeto@Sun.COM int 26169585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal) 26179585STim.Szeto@Sun.COM { 26189585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 26199585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 26209585STim.Szeto@Sun.COM if (hdl == NULL) { 26219585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26229585STim.Szeto@Sun.COM } 26239585STim.Szeto@Sun.COM 26249585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 26259585STim.Szeto@Sun.COM ret = setDiskProp(luPropsHdl, prop, propVal); 26269585STim.Szeto@Sun.COM } else { 26279585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26289585STim.Szeto@Sun.COM } 26299585STim.Szeto@Sun.COM 26309585STim.Szeto@Sun.COM return (ret); 26319585STim.Szeto@Sun.COM } 26329585STim.Szeto@Sun.COM 26339585STim.Szeto@Sun.COM /* 26349585STim.Szeto@Sun.COM * getDiskProp 26359585STim.Szeto@Sun.COM * 26369585STim.Szeto@Sun.COM * Purpose: retrieve a given property from a logical unit resource of type disk 26379585STim.Szeto@Sun.COM * 26389585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 26399585STim.Szeto@Sun.COM * prop - property identifier 26409585STim.Szeto@Sun.COM * propVal - pointer to character to contain the retrieved property value 26419585STim.Szeto@Sun.COM * propLen - On input this is the length of propVal. On failure, it contains the 26429585STim.Szeto@Sun.COM * number of bytes required for propVal 26439585STim.Szeto@Sun.COM */ 26449585STim.Szeto@Sun.COM static int 26459585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen) 26469585STim.Szeto@Sun.COM { 26479585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 26489585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 264910725SJohn.Forte@Sun.COM char accessState[20]; 26509585STim.Szeto@Sun.COM size_t reqLen; 26519585STim.Szeto@Sun.COM 265210725SJohn.Forte@Sun.COM if (prop == STMF_LU_PROP_ACCESS_STATE) { 265310725SJohn.Forte@Sun.COM if (diskLu->accessState == SBD_LU_ACTIVE) { 265410725SJohn.Forte@Sun.COM (void) strlcpy(accessState, STMF_ACCESS_ACTIVE, 265510725SJohn.Forte@Sun.COM sizeof (accessState)); 265610725SJohn.Forte@Sun.COM } else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) { 265710725SJohn.Forte@Sun.COM (void) strlcpy(accessState, 265810725SJohn.Forte@Sun.COM STMF_ACCESS_STANDBY_TO_ACTIVE, 265910725SJohn.Forte@Sun.COM sizeof (accessState)); 266010725SJohn.Forte@Sun.COM } else if (diskLu->accessState == SBD_LU_STANDBY) { 266110725SJohn.Forte@Sun.COM (void) strlcpy(accessState, STMF_ACCESS_STANDBY, 266210725SJohn.Forte@Sun.COM sizeof (accessState)); 266310725SJohn.Forte@Sun.COM } else if (diskLu->accessState == 266410725SJohn.Forte@Sun.COM SBD_LU_TRANSITION_TO_STANDBY) { 266510725SJohn.Forte@Sun.COM (void) strlcpy(accessState, 266610725SJohn.Forte@Sun.COM STMF_ACCESS_ACTIVE_TO_STANDBY, 266710725SJohn.Forte@Sun.COM sizeof (accessState)); 266810725SJohn.Forte@Sun.COM } 266910725SJohn.Forte@Sun.COM if ((reqLen = strlcpy(propVal, accessState, 267010725SJohn.Forte@Sun.COM *propLen)) >= *propLen) { 267110725SJohn.Forte@Sun.COM *propLen = reqLen + 1; 267210725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 267310725SJohn.Forte@Sun.COM } 267410725SJohn.Forte@Sun.COM return (0); 267510725SJohn.Forte@Sun.COM } 267610725SJohn.Forte@Sun.COM 267710725SJohn.Forte@Sun.COM if (diskLu->accessState != SBD_LU_ACTIVE) { 267810725SJohn.Forte@Sun.COM return (STMF_ERROR_NO_PROP_STANDBY); 267910725SJohn.Forte@Sun.COM } 268010725SJohn.Forte@Sun.COM 26819585STim.Szeto@Sun.COM switch (prop) { 26829585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 26839585STim.Szeto@Sun.COM if (diskLu->blkSizeValid == B_FALSE) { 26849585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 26859585STim.Szeto@Sun.COM } 26869585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, "%llu", 26879585STim.Szeto@Sun.COM (u_longlong_t)diskLu->blkSize); 26889585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 26899585STim.Szeto@Sun.COM *propLen = reqLen + 1; 26909585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26919585STim.Szeto@Sun.COM } 26929585STim.Szeto@Sun.COM break; 26939585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 26949585STim.Szeto@Sun.COM if (diskLu->luDataFileNameValid == B_FALSE) { 26959585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 26969585STim.Szeto@Sun.COM } 26979585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luDataFileName, 26989585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 26999585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27009585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27019585STim.Szeto@Sun.COM } 27029585STim.Szeto@Sun.COM break; 27039585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 27049585STim.Szeto@Sun.COM if (diskLu->luMetaFileNameValid == B_FALSE) { 27059585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27069585STim.Szeto@Sun.COM } 27079585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName, 27089585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27099585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27109585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27119585STim.Szeto@Sun.COM } 27129585STim.Szeto@Sun.COM break; 271310113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 271410113SNattuvetty.Bhavyan@Sun.COM if (diskLu->luMgmtUrlValid == B_FALSE) { 271510113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_NO_PROP); 271610113SNattuvetty.Bhavyan@Sun.COM } 271710113SNattuvetty.Bhavyan@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl, 271810113SNattuvetty.Bhavyan@Sun.COM *propLen)) >= *propLen) { 271910113SNattuvetty.Bhavyan@Sun.COM *propLen = reqLen + 1; 272010113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_ARG); 272110113SNattuvetty.Bhavyan@Sun.COM } 272210113SNattuvetty.Bhavyan@Sun.COM break; 27239585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 27249585STim.Szeto@Sun.COM if (diskLu->luGuidValid == B_FALSE) { 27259585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27269585STim.Szeto@Sun.COM } 27279585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, 27289585STim.Szeto@Sun.COM "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 27299585STim.Szeto@Sun.COM "%02X%02X%02X%02X", 27309585STim.Szeto@Sun.COM diskLu->luGuid[0], diskLu->luGuid[1], 27319585STim.Szeto@Sun.COM diskLu->luGuid[2], diskLu->luGuid[3], 27329585STim.Szeto@Sun.COM diskLu->luGuid[4], diskLu->luGuid[5], 27339585STim.Szeto@Sun.COM diskLu->luGuid[6], diskLu->luGuid[7], 27349585STim.Szeto@Sun.COM diskLu->luGuid[8], diskLu->luGuid[9], 27359585STim.Szeto@Sun.COM diskLu->luGuid[10], diskLu->luGuid[11], 27369585STim.Szeto@Sun.COM diskLu->luGuid[12], diskLu->luGuid[13], 27379585STim.Szeto@Sun.COM diskLu->luGuid[14], diskLu->luGuid[15]); 27389585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 27399585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27409585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27419585STim.Szeto@Sun.COM } 27429585STim.Szeto@Sun.COM break; 27439585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 27449585STim.Szeto@Sun.COM if (diskLu->serialNumValid == B_FALSE) { 27459585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27469585STim.Szeto@Sun.COM } 27479585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->serialNum, 27489585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27499585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27509585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27519585STim.Szeto@Sun.COM } 27529585STim.Szeto@Sun.COM break; 27539585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 27549585STim.Szeto@Sun.COM if (diskLu->luSizeValid == B_FALSE) { 27559585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27569585STim.Szeto@Sun.COM } 27579585STim.Szeto@Sun.COM (void) snprintf(propVal, *propLen, "%llu", 27589585STim.Szeto@Sun.COM (u_longlong_t)diskLu->luSize); 27599585STim.Szeto@Sun.COM break; 27609585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 27619585STim.Szeto@Sun.COM if (diskLu->luAliasValid == B_FALSE) { 27629585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27639585STim.Szeto@Sun.COM } 27649585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luAlias, 27659585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27669585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27679585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27689585STim.Szeto@Sun.COM } 27699585STim.Szeto@Sun.COM break; 27709585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 27719585STim.Szeto@Sun.COM if (diskLu->vidValid == B_FALSE) { 27729585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27739585STim.Szeto@Sun.COM } 27749585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->vid)) { 27759585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27769585STim.Szeto@Sun.COM } 27779585STim.Szeto@Sun.COM bcopy(diskLu->vid, propVal, sizeof (diskLu->vid)); 27789585STim.Szeto@Sun.COM propVal[sizeof (diskLu->vid)] = 0; 27799585STim.Szeto@Sun.COM break; 27809585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 27819585STim.Szeto@Sun.COM if (diskLu->pidValid == B_FALSE) { 27829585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27839585STim.Szeto@Sun.COM } 27849585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->pid)) { 27859585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27869585STim.Szeto@Sun.COM } 27879585STim.Szeto@Sun.COM bcopy(diskLu->pid, propVal, sizeof (diskLu->pid)); 27889585STim.Szeto@Sun.COM propVal[sizeof (diskLu->pid)] = 0; 27899585STim.Szeto@Sun.COM break; 27909585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 27919585STim.Szeto@Sun.COM if (diskLu->writeProtectEnableValid == B_FALSE) { 27929585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 27939585STim.Szeto@Sun.COM } 27949585STim.Szeto@Sun.COM if (diskLu->writeProtectEnable) { 27959585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 27969585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 27979585STim.Szeto@Sun.COM *propLen = reqLen + 1; 27989585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 27999585STim.Szeto@Sun.COM } 28009585STim.Szeto@Sun.COM } else { 28019585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 28029585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28039585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28049585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28059585STim.Szeto@Sun.COM } 28069585STim.Szeto@Sun.COM } 28079585STim.Szeto@Sun.COM break; 28089585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 28099585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisableValid == B_FALSE) { 28109585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 28119585STim.Szeto@Sun.COM } 28129585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisable) { 28139585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 28149585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28159585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28169585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28179585STim.Szeto@Sun.COM } 28189585STim.Szeto@Sun.COM } else { 28199585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 28209585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 28219585STim.Szeto@Sun.COM *propLen = reqLen + 1; 28229585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28239585STim.Szeto@Sun.COM } 28249585STim.Szeto@Sun.COM } 28259585STim.Szeto@Sun.COM break; 28269585STim.Szeto@Sun.COM default: 28279585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 28289585STim.Szeto@Sun.COM break; 28299585STim.Szeto@Sun.COM } 28309585STim.Szeto@Sun.COM 28319585STim.Szeto@Sun.COM return (ret); 28329585STim.Szeto@Sun.COM } 28339585STim.Szeto@Sun.COM 28349585STim.Szeto@Sun.COM /* 28359585STim.Szeto@Sun.COM * setDiskProp 28369585STim.Szeto@Sun.COM * 28379585STim.Szeto@Sun.COM * Purpose: set properties for resource of type disk 28389585STim.Szeto@Sun.COM * 28399585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 28409585STim.Szeto@Sun.COM * resourceProp - valid resource identifier 28419585STim.Szeto@Sun.COM * propVal - valid resource value 28429585STim.Szeto@Sun.COM */ 28439585STim.Szeto@Sun.COM static int 28449585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal) 28459585STim.Szeto@Sun.COM { 28469585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 28479585STim.Szeto@Sun.COM int i; 28489585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 28499585STim.Szeto@Sun.COM unsigned long long numericProp = 0; 28509585STim.Szeto@Sun.COM char guidProp[LU_ASCII_GUID_SIZE + 1]; 28519585STim.Szeto@Sun.COM char ouiProp[OUI_ASCII_SIZE + 1]; 285210765SJohn.Forte@Sun.COM char hostIdProp[HOST_ID_ASCII_SIZE + 1]; 28539585STim.Szeto@Sun.COM unsigned int oui[OUI_SIZE]; 285410765SJohn.Forte@Sun.COM unsigned int hostId[HOST_ID_SIZE]; 28559585STim.Szeto@Sun.COM unsigned int guid[LU_GUID_SIZE]; 28569585STim.Szeto@Sun.COM int propSize; 28579585STim.Szeto@Sun.COM 28589585STim.Szeto@Sun.COM 28599585STim.Szeto@Sun.COM if (propVal == NULL) { 28609585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28619585STim.Szeto@Sun.COM } 28629585STim.Szeto@Sun.COM 28639585STim.Szeto@Sun.COM switch (resourceProp) { 28649585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 28659585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, propVal, 28669585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 28679585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 28689585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 28699585STim.Szeto@Sun.COM } 28709585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 28719585STim.Szeto@Sun.COM break; 28729585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 28739585STim.Szeto@Sun.COM (void) sscanf(propVal, "%llu", &numericProp); 28749585STim.Szeto@Sun.COM if (numericProp > UINT16_MAX) { 28759585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 28769585STim.Szeto@Sun.COM } 28779585STim.Szeto@Sun.COM diskLu->blkSize = numericProp; 28789585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 28799585STim.Szeto@Sun.COM break; 28809585STim.Szeto@Sun.COM case STMF_LU_PROP_COMPANY_ID: 28819585STim.Szeto@Sun.COM if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >= 28829585STim.Szeto@Sun.COM sizeof (ouiProp)) { 28839585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28849585STim.Szeto@Sun.COM } 28859585STim.Szeto@Sun.COM if (checkHexUpper(ouiProp) != 0) { 28869585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 28879585STim.Szeto@Sun.COM } 28889585STim.Szeto@Sun.COM (void) sscanf(ouiProp, "%2X%2X%2X", 28899585STim.Szeto@Sun.COM &oui[0], &oui[1], &oui[2]); 28909585STim.Szeto@Sun.COM 28919585STim.Szeto@Sun.COM diskLu->companyId = 0; 28929585STim.Szeto@Sun.COM diskLu->companyId += oui[0] << 16; 28939585STim.Szeto@Sun.COM diskLu->companyId += oui[1] << 8; 28949585STim.Szeto@Sun.COM diskLu->companyId += oui[2]; 289510765SJohn.Forte@Sun.COM if (diskLu->companyId == 0) { 289610765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 289710765SJohn.Forte@Sun.COM } 28989585STim.Szeto@Sun.COM diskLu->companyIdValid = B_TRUE; 28999585STim.Szeto@Sun.COM break; 290010765SJohn.Forte@Sun.COM case STMF_LU_PROP_HOST_ID: 290110765SJohn.Forte@Sun.COM if ((strlcpy(hostIdProp, propVal, 290210765SJohn.Forte@Sun.COM sizeof (hostIdProp))) >= sizeof (hostIdProp)) { 290310765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 290410765SJohn.Forte@Sun.COM } 290510765SJohn.Forte@Sun.COM if (checkHexUpper(hostIdProp) != 0) { 290610765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 290710765SJohn.Forte@Sun.COM } 290810765SJohn.Forte@Sun.COM (void) sscanf(hostIdProp, "%2X%2X%2X%2X", 290910765SJohn.Forte@Sun.COM &hostId[0], &hostId[1], &hostId[2], &hostId[3]); 291010765SJohn.Forte@Sun.COM 291110765SJohn.Forte@Sun.COM diskLu->hostId = 0; 291210765SJohn.Forte@Sun.COM diskLu->hostId += hostId[0] << 24; 291310765SJohn.Forte@Sun.COM diskLu->hostId += hostId[1] << 16; 291410765SJohn.Forte@Sun.COM diskLu->hostId += hostId[2] << 8; 291510765SJohn.Forte@Sun.COM diskLu->hostId += hostId[3]; 291610765SJohn.Forte@Sun.COM if (diskLu->hostId == 0) { 291710765SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 291810765SJohn.Forte@Sun.COM } 291910765SJohn.Forte@Sun.COM diskLu->hostIdValid = B_TRUE; 292010765SJohn.Forte@Sun.COM break; 29219585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 29229585STim.Szeto@Sun.COM if (strlen(propVal) != LU_ASCII_GUID_SIZE) { 29239585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29249585STim.Szeto@Sun.COM } 29259585STim.Szeto@Sun.COM 29269585STim.Szeto@Sun.COM if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >= 29279585STim.Szeto@Sun.COM sizeof (guidProp)) { 29289585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29299585STim.Szeto@Sun.COM } 29309585STim.Szeto@Sun.COM 29319585STim.Szeto@Sun.COM if (checkHexUpper(guidProp) != 0) { 29329585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29339585STim.Szeto@Sun.COM } 29349585STim.Szeto@Sun.COM 29359585STim.Szeto@Sun.COM (void) sscanf(guidProp, 29369585STim.Szeto@Sun.COM "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X", 29379585STim.Szeto@Sun.COM &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], 29389585STim.Szeto@Sun.COM &guid[5], &guid[6], &guid[7], &guid[8], &guid[9], 29399585STim.Szeto@Sun.COM &guid[10], &guid[11], &guid[12], &guid[13], 29409585STim.Szeto@Sun.COM &guid[14], &guid[15]); 29419585STim.Szeto@Sun.COM for (i = 0; i < sizeof (diskLu->luGuid); i++) { 29429585STim.Szeto@Sun.COM diskLu->luGuid[i] = guid[i]; 29439585STim.Szeto@Sun.COM } 29449585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 29459585STim.Szeto@Sun.COM break; 29469585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 29479585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luDataFileName, propVal, 29489585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName))) >= 29499585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 29509585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29519585STim.Szeto@Sun.COM } 29529585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 29539585STim.Szeto@Sun.COM break; 29549585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 29559585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luMetaFileName, propVal, 29569585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName))) >= 29579585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 29589585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29599585STim.Szeto@Sun.COM } 29609585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 29619585STim.Szeto@Sun.COM break; 296210113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 296310113SNattuvetty.Bhavyan@Sun.COM if ((strlcpy(diskLu->luMgmtUrl, propVal, 296410113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl))) >= 296510113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 296610113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 296710113SNattuvetty.Bhavyan@Sun.COM } 296810113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 296910113SNattuvetty.Bhavyan@Sun.COM break; 29709585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 29719585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 29729585STim.Szeto@Sun.COM sizeof (diskLu->pid)) { 29739585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29749585STim.Szeto@Sun.COM } 29759585STim.Szeto@Sun.COM (void) strncpy(diskLu->pid, propVal, propSize); 29769585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 29779585STim.Szeto@Sun.COM break; 29789585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 29799585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 29809585STim.Szeto@Sun.COM (sizeof (diskLu->serialNum) - 1)) { 29819585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29829585STim.Szeto@Sun.COM } 29839585STim.Szeto@Sun.COM (void) strncpy(diskLu->serialNum, propVal, propSize); 29849585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 29859585STim.Szeto@Sun.COM break; 29869585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 29879585STim.Szeto@Sun.COM if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) { 29889585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29899585STim.Szeto@Sun.COM } 29909585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 29919585STim.Szeto@Sun.COM break; 29929585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 29939585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 29949585STim.Szeto@Sun.COM sizeof (diskLu->vid)) { 29959585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 29969585STim.Szeto@Sun.COM } 29979585STim.Szeto@Sun.COM (void) strncpy(diskLu->vid, propVal, propSize); 29989585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 29999585STim.Szeto@Sun.COM break; 30009585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 30019585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 30029585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 30039585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 30049585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_FALSE; 30059585STim.Szeto@Sun.COM } else { 30069585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30079585STim.Szeto@Sun.COM } 30089585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 30099585STim.Szeto@Sun.COM break; 30109585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 30119585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 30129585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 30139585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 30149585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = 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->writebackCacheDisableValid = B_TRUE; 30199585STim.Szeto@Sun.COM break; 302010725SJohn.Forte@Sun.COM case STMF_LU_PROP_ACCESS_STATE: 302110725SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_PROP; 302210725SJohn.Forte@Sun.COM break; 30239585STim.Szeto@Sun.COM default: 30249585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 30259585STim.Szeto@Sun.COM break; 30269585STim.Szeto@Sun.COM } 30279585STim.Szeto@Sun.COM return (ret); 30289585STim.Szeto@Sun.COM } 30299585STim.Szeto@Sun.COM 30309585STim.Szeto@Sun.COM static int 30319585STim.Szeto@Sun.COM checkHexUpper(char *buf) 30329585STim.Szeto@Sun.COM { 30339585STim.Szeto@Sun.COM int i; 30349585STim.Szeto@Sun.COM 30359585STim.Szeto@Sun.COM for (i = 0; i < strlen(buf); i++) { 30369585STim.Szeto@Sun.COM if (isxdigit(buf[i])) { 30379585STim.Szeto@Sun.COM buf[i] = toupper(buf[i]); 30389585STim.Szeto@Sun.COM continue; 30399585STim.Szeto@Sun.COM } 30409585STim.Szeto@Sun.COM return (-1); 30419585STim.Szeto@Sun.COM } 30429585STim.Szeto@Sun.COM 30439585STim.Szeto@Sun.COM return (0); 30449585STim.Szeto@Sun.COM } 30459585STim.Szeto@Sun.COM 30469585STim.Szeto@Sun.COM /* 30479585STim.Szeto@Sun.COM * Given a numeric suffix, convert the value into a number of bits that the 30489585STim.Szeto@Sun.COM * resulting value must be shifted. 30499585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 30509585STim.Szeto@Sun.COM */ 30519585STim.Szeto@Sun.COM static int 30529585STim.Szeto@Sun.COM strToShift(const char *buf) 30539585STim.Szeto@Sun.COM { 30549585STim.Szeto@Sun.COM const char *ends = "BKMGTPE"; 30559585STim.Szeto@Sun.COM int i; 30569585STim.Szeto@Sun.COM 30579585STim.Szeto@Sun.COM if (buf[0] == '\0') 30589585STim.Szeto@Sun.COM return (0); 30599585STim.Szeto@Sun.COM 30609585STim.Szeto@Sun.COM for (i = 0; i < strlen(ends); i++) { 30619585STim.Szeto@Sun.COM if (toupper(buf[0]) == ends[i]) 30629585STim.Szeto@Sun.COM return (10*i); 30639585STim.Szeto@Sun.COM } 30649585STim.Szeto@Sun.COM 30659585STim.Szeto@Sun.COM return (-1); 30669585STim.Szeto@Sun.COM } 30679585STim.Szeto@Sun.COM 30689585STim.Szeto@Sun.COM int 30699585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl) 30709585STim.Szeto@Sun.COM { 30719585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 30729585STim.Szeto@Sun.COM if (hdl == NULL) { 30739585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30749585STim.Szeto@Sun.COM } 30759585STim.Szeto@Sun.COM 30769585STim.Szeto@Sun.COM luResourceImpl *hdlImpl = hdl; 30779585STim.Szeto@Sun.COM free(hdlImpl->resource); 30789585STim.Szeto@Sun.COM free(hdlImpl); 30799585STim.Szeto@Sun.COM return (ret); 30809585STim.Szeto@Sun.COM } 30819585STim.Szeto@Sun.COM 30829585STim.Szeto@Sun.COM /* 30839585STim.Szeto@Sun.COM * Convert a string of the form '100G' into a real number. Used when setting 30849585STim.Szeto@Sun.COM * the size of a logical unit. 30859585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 30869585STim.Szeto@Sun.COM */ 30879585STim.Szeto@Sun.COM static int 30889585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num) 30899585STim.Szeto@Sun.COM { 30909585STim.Szeto@Sun.COM char *end; 30919585STim.Szeto@Sun.COM int shift; 30929585STim.Szeto@Sun.COM 30939585STim.Szeto@Sun.COM *num = 0; 30949585STim.Szeto@Sun.COM 30959585STim.Szeto@Sun.COM /* Check to see if this looks like a number. */ 30969585STim.Szeto@Sun.COM if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 30979585STim.Szeto@Sun.COM return (-1); 30989585STim.Szeto@Sun.COM } 30999585STim.Szeto@Sun.COM 31009585STim.Szeto@Sun.COM /* Rely on stroull() to process the numeric portion. */ 31019585STim.Szeto@Sun.COM errno = 0; 31029585STim.Szeto@Sun.COM *num = strtoull(value, &end, 10); 31039585STim.Szeto@Sun.COM 31049585STim.Szeto@Sun.COM /* 31059585STim.Szeto@Sun.COM * Check for ERANGE, which indicates that the value is too large to fit 31069585STim.Szeto@Sun.COM * in a 64-bit value. 31079585STim.Szeto@Sun.COM */ 31089585STim.Szeto@Sun.COM if (errno == ERANGE) { 31099585STim.Szeto@Sun.COM return (-1); 31109585STim.Szeto@Sun.COM } 31119585STim.Szeto@Sun.COM 31129585STim.Szeto@Sun.COM /* 31139585STim.Szeto@Sun.COM * If we have a decimal value, then do the computation with floating 31149585STim.Szeto@Sun.COM * point arithmetic. Otherwise, use standard arithmetic. 31159585STim.Szeto@Sun.COM */ 31169585STim.Szeto@Sun.COM if (*end == '.') { 31179585STim.Szeto@Sun.COM double fval = strtod(value, &end); 31189585STim.Szeto@Sun.COM 31199585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 31209585STim.Szeto@Sun.COM return (-1); 31219585STim.Szeto@Sun.COM } 31229585STim.Szeto@Sun.COM 31239585STim.Szeto@Sun.COM fval *= pow(2, shift); 31249585STim.Szeto@Sun.COM 31259585STim.Szeto@Sun.COM if (fval > UINT64_MAX) { 31269585STim.Szeto@Sun.COM return (-1); 31279585STim.Szeto@Sun.COM } 31289585STim.Szeto@Sun.COM 31299585STim.Szeto@Sun.COM *num = (uint64_t)fval; 31309585STim.Szeto@Sun.COM } else { 31319585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 31329585STim.Szeto@Sun.COM return (-1); 31339585STim.Szeto@Sun.COM } 31349585STim.Szeto@Sun.COM 31359585STim.Szeto@Sun.COM /* Check for overflow */ 31369585STim.Szeto@Sun.COM if (shift >= 64 || (*num << shift) >> shift != *num) { 31379585STim.Szeto@Sun.COM return (-1); 31389585STim.Szeto@Sun.COM } 31399585STim.Szeto@Sun.COM 31409585STim.Szeto@Sun.COM *num <<= shift; 31419585STim.Szeto@Sun.COM } 31429585STim.Szeto@Sun.COM 31439585STim.Szeto@Sun.COM return (0); 31449585STim.Szeto@Sun.COM } 31459585STim.Szeto@Sun.COM 31469585STim.Szeto@Sun.COM /* 31477836SJohn.Forte@Sun.COM * stmfCreateTargetGroup 31487836SJohn.Forte@Sun.COM * 31497836SJohn.Forte@Sun.COM * Purpose: Create a local port group 31507836SJohn.Forte@Sun.COM * 31517836SJohn.Forte@Sun.COM * targetGroupName - name of local port group to create 31527836SJohn.Forte@Sun.COM */ 31537836SJohn.Forte@Sun.COM int 31547836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName) 31557836SJohn.Forte@Sun.COM { 31567836SJohn.Forte@Sun.COM int ret; 31577836SJohn.Forte@Sun.COM int fd; 31587836SJohn.Forte@Sun.COM 31597836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 31607836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 31617836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 31627836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31637836SJohn.Forte@Sun.COM } 31647836SJohn.Forte@Sun.COM 31657836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 31667836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 31677836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 31687836SJohn.Forte@Sun.COM } 31697836SJohn.Forte@Sun.COM 31707836SJohn.Forte@Sun.COM /* call init */ 31717836SJohn.Forte@Sun.COM ret = initializeConfig(); 31727836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 31737836SJohn.Forte@Sun.COM return (ret); 31747836SJohn.Forte@Sun.COM } 31757836SJohn.Forte@Sun.COM 31767836SJohn.Forte@Sun.COM /* 31777836SJohn.Forte@Sun.COM * Open control node for stmf 31787836SJohn.Forte@Sun.COM */ 31797836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 31807836SJohn.Forte@Sun.COM return (ret); 31817836SJohn.Forte@Sun.COM 31827836SJohn.Forte@Sun.COM /* 31837836SJohn.Forte@Sun.COM * Add the group to the driver 31847836SJohn.Forte@Sun.COM */ 31857836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 31867836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 31877836SJohn.Forte@Sun.COM goto done; 31887836SJohn.Forte@Sun.COM } 31897836SJohn.Forte@Sun.COM 31909585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 31919585STim.Szeto@Sun.COM goto done; 31929585STim.Szeto@Sun.COM } 31939585STim.Szeto@Sun.COM 31947836SJohn.Forte@Sun.COM /* 31957836SJohn.Forte@Sun.COM * If the add to the driver was successful, add it to the persistent 31967836SJohn.Forte@Sun.COM * store. 31977836SJohn.Forte@Sun.COM */ 31987836SJohn.Forte@Sun.COM ret = psCreateTargetGroup((char *)targetGroupName); 31997836SJohn.Forte@Sun.COM switch (ret) { 32007836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 32017836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 32027836SJohn.Forte@Sun.COM break; 32037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 32047836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 32057836SJohn.Forte@Sun.COM break; 32067836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 32077836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 32087836SJohn.Forte@Sun.COM break; 32097836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 32107836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 32117836SJohn.Forte@Sun.COM break; 32127836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 32137836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 32147836SJohn.Forte@Sun.COM break; 32157836SJohn.Forte@Sun.COM default: 32167836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 32177836SJohn.Forte@Sun.COM "stmfCreateTargetGroup:psCreateTargetGroup" 32187836SJohn.Forte@Sun.COM ":error(%d)", ret); 32197836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 32207836SJohn.Forte@Sun.COM break; 32217836SJohn.Forte@Sun.COM } 32227836SJohn.Forte@Sun.COM 32237836SJohn.Forte@Sun.COM done: 32247836SJohn.Forte@Sun.COM (void) close(fd); 32257836SJohn.Forte@Sun.COM return (ret); 32267836SJohn.Forte@Sun.COM } 32277836SJohn.Forte@Sun.COM 32287836SJohn.Forte@Sun.COM /* 32297836SJohn.Forte@Sun.COM * stmfDeleteHostGroup 32307836SJohn.Forte@Sun.COM * 32317836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 32327836SJohn.Forte@Sun.COM * 32337836SJohn.Forte@Sun.COM * hostGroupName - group to delete 32347836SJohn.Forte@Sun.COM */ 32357836SJohn.Forte@Sun.COM int 32367836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName) 32377836SJohn.Forte@Sun.COM { 32387836SJohn.Forte@Sun.COM int ret; 32397836SJohn.Forte@Sun.COM int fd; 32407836SJohn.Forte@Sun.COM 32417836SJohn.Forte@Sun.COM if (hostGroupName == NULL) { 32427836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 32437836SJohn.Forte@Sun.COM } 32447836SJohn.Forte@Sun.COM 32457836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 32467836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 32477836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 32487836SJohn.Forte@Sun.COM } 32497836SJohn.Forte@Sun.COM 32507836SJohn.Forte@Sun.COM /* call init */ 32517836SJohn.Forte@Sun.COM ret = initializeConfig(); 32527836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 32537836SJohn.Forte@Sun.COM return (ret); 32547836SJohn.Forte@Sun.COM } 32557836SJohn.Forte@Sun.COM 32567836SJohn.Forte@Sun.COM /* 32577836SJohn.Forte@Sun.COM * Open control node for stmf 32587836SJohn.Forte@Sun.COM */ 32597836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 32607836SJohn.Forte@Sun.COM return (ret); 32617836SJohn.Forte@Sun.COM 32627836SJohn.Forte@Sun.COM /* 32637836SJohn.Forte@Sun.COM * Remove the group from the driver 32647836SJohn.Forte@Sun.COM */ 32657836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP, 32667836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 32677836SJohn.Forte@Sun.COM goto done; 32687836SJohn.Forte@Sun.COM } 32697836SJohn.Forte@Sun.COM 32709585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 32719585STim.Szeto@Sun.COM goto done; 32729585STim.Szeto@Sun.COM } 32739585STim.Szeto@Sun.COM 32747836SJohn.Forte@Sun.COM /* 32757836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 32767836SJohn.Forte@Sun.COM * persistent store. 32777836SJohn.Forte@Sun.COM */ 32787836SJohn.Forte@Sun.COM ret = psDeleteHostGroup((char *)hostGroupName); 32797836SJohn.Forte@Sun.COM switch (ret) { 32807836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 32817836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 32827836SJohn.Forte@Sun.COM break; 32837836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 32847836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 32857836SJohn.Forte@Sun.COM break; 32867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 32877836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 32887836SJohn.Forte@Sun.COM break; 32897836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 32907836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 32917836SJohn.Forte@Sun.COM break; 32927836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 32937836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 32947836SJohn.Forte@Sun.COM break; 32957836SJohn.Forte@Sun.COM default: 32967836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 32977836SJohn.Forte@Sun.COM "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)", 32987836SJohn.Forte@Sun.COM ret); 32997836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33007836SJohn.Forte@Sun.COM break; 33017836SJohn.Forte@Sun.COM } 33027836SJohn.Forte@Sun.COM 33037836SJohn.Forte@Sun.COM done: 33047836SJohn.Forte@Sun.COM (void) close(fd); 33057836SJohn.Forte@Sun.COM return (ret); 33067836SJohn.Forte@Sun.COM } 33077836SJohn.Forte@Sun.COM 33087836SJohn.Forte@Sun.COM /* 33097836SJohn.Forte@Sun.COM * stmfDeleteTargetGroup 33107836SJohn.Forte@Sun.COM * 33117836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 33127836SJohn.Forte@Sun.COM * 33137836SJohn.Forte@Sun.COM * targetGroupName - group to delete 33147836SJohn.Forte@Sun.COM */ 33157836SJohn.Forte@Sun.COM int 33167836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName) 33177836SJohn.Forte@Sun.COM { 33187836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 33197836SJohn.Forte@Sun.COM int fd; 33207836SJohn.Forte@Sun.COM 33217836SJohn.Forte@Sun.COM if (targetGroupName == NULL) { 33227836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 33237836SJohn.Forte@Sun.COM } 33247836SJohn.Forte@Sun.COM 33257836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 33267836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 33277836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 33287836SJohn.Forte@Sun.COM } 33297836SJohn.Forte@Sun.COM 33307836SJohn.Forte@Sun.COM /* call init */ 33317836SJohn.Forte@Sun.COM ret = initializeConfig(); 33327836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 33337836SJohn.Forte@Sun.COM return (ret); 33347836SJohn.Forte@Sun.COM } 33357836SJohn.Forte@Sun.COM 33367836SJohn.Forte@Sun.COM /* 33377836SJohn.Forte@Sun.COM * Open control node for stmf 33387836SJohn.Forte@Sun.COM */ 33397836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 33407836SJohn.Forte@Sun.COM return (ret); 33417836SJohn.Forte@Sun.COM 33427836SJohn.Forte@Sun.COM /* 33437836SJohn.Forte@Sun.COM * Remove the group from the driver 33447836SJohn.Forte@Sun.COM */ 33457836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP, 33467836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 33477836SJohn.Forte@Sun.COM goto done; 33487836SJohn.Forte@Sun.COM } 33497836SJohn.Forte@Sun.COM 33509585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 33519585STim.Szeto@Sun.COM goto done; 33529585STim.Szeto@Sun.COM } 33539585STim.Szeto@Sun.COM 33547836SJohn.Forte@Sun.COM /* 33557836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 33567836SJohn.Forte@Sun.COM * persistent store. 33577836SJohn.Forte@Sun.COM */ 33587836SJohn.Forte@Sun.COM ret = psDeleteTargetGroup((char *)targetGroupName); 33597836SJohn.Forte@Sun.COM switch (ret) { 33607836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 33617836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 33627836SJohn.Forte@Sun.COM break; 33637836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 33647836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 33657836SJohn.Forte@Sun.COM break; 33667836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 33677836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 33687836SJohn.Forte@Sun.COM break; 33697836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33707836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33717836SJohn.Forte@Sun.COM break; 33727836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33737836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33747836SJohn.Forte@Sun.COM break; 33757836SJohn.Forte@Sun.COM default: 33767836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 33777836SJohn.Forte@Sun.COM "stmfDeleteTargetGroup:psDeleteTargetGroup" 33787836SJohn.Forte@Sun.COM ":error(%d)", ret); 33797836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33807836SJohn.Forte@Sun.COM break; 33817836SJohn.Forte@Sun.COM } 33827836SJohn.Forte@Sun.COM 33837836SJohn.Forte@Sun.COM done: 33847836SJohn.Forte@Sun.COM (void) close(fd); 33857836SJohn.Forte@Sun.COM return (ret); 33867836SJohn.Forte@Sun.COM } 33877836SJohn.Forte@Sun.COM 33887836SJohn.Forte@Sun.COM /* 33897836SJohn.Forte@Sun.COM * stmfDevidFromIscsiName 33907836SJohn.Forte@Sun.COM * 33917836SJohn.Forte@Sun.COM * Purpose: convert an iSCSI name to an stmf devid 33927836SJohn.Forte@Sun.COM * 33937836SJohn.Forte@Sun.COM * iscsiName - unicode nul terminated utf-8 encoded iSCSI name 33947836SJohn.Forte@Sun.COM * devid - on success, contains the converted iscsi name 33957836SJohn.Forte@Sun.COM */ 33967836SJohn.Forte@Sun.COM int 33977836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid) 33987836SJohn.Forte@Sun.COM { 33997836SJohn.Forte@Sun.COM if (devid == NULL || iscsiName == NULL) 34007836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34017836SJohn.Forte@Sun.COM 34027836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 34037836SJohn.Forte@Sun.COM 34047836SJohn.Forte@Sun.COM /* Validate size of target */ 34057836SJohn.Forte@Sun.COM if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME || 34067836SJohn.Forte@Sun.COM devid->identLength < strlen(EUI) || 34077836SJohn.Forte@Sun.COM devid->identLength < strlen(IQN)) { 34087836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34097836SJohn.Forte@Sun.COM } 34107836SJohn.Forte@Sun.COM 34117836SJohn.Forte@Sun.COM if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) && 34127836SJohn.Forte@Sun.COM strncmp(iscsiName, IQN, strlen(IQN)) != 0) { 34137836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34147836SJohn.Forte@Sun.COM } 34157836SJohn.Forte@Sun.COM 34167836SJohn.Forte@Sun.COM /* copy UTF-8 bytes to ident */ 34177836SJohn.Forte@Sun.COM bcopy(iscsiName, devid->ident, devid->identLength); 34187836SJohn.Forte@Sun.COM 34197836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 34207836SJohn.Forte@Sun.COM } 34217836SJohn.Forte@Sun.COM 34227836SJohn.Forte@Sun.COM /* 34237836SJohn.Forte@Sun.COM * stmfDevidFromWwn 34247836SJohn.Forte@Sun.COM * 34257836SJohn.Forte@Sun.COM * Purpose: convert a WWN to an stmf devid 34267836SJohn.Forte@Sun.COM * 34277836SJohn.Forte@Sun.COM * wwn - 8-byte wwn identifier 34287836SJohn.Forte@Sun.COM * devid - on success, contains the converted wwn 34297836SJohn.Forte@Sun.COM */ 34307836SJohn.Forte@Sun.COM int 34317836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid) 34327836SJohn.Forte@Sun.COM { 34337836SJohn.Forte@Sun.COM if (wwn == NULL || devid == NULL) 34347836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34357836SJohn.Forte@Sun.COM 34367836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 34377836SJohn.Forte@Sun.COM 34387836SJohn.Forte@Sun.COM /* Copy eui prefix */ 34397836SJohn.Forte@Sun.COM (void) bcopy(WWN, devid->ident, strlen(WWN)); 34407836SJohn.Forte@Sun.COM 34417836SJohn.Forte@Sun.COM /* Convert to ASCII uppercase hexadecimal string */ 34427836SJohn.Forte@Sun.COM (void) snprintf((char *)&devid->ident[strlen(WWN)], 34437836SJohn.Forte@Sun.COM sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X", 34447836SJohn.Forte@Sun.COM wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 34457836SJohn.Forte@Sun.COM 34467836SJohn.Forte@Sun.COM devid->identLength = strlen((char *)devid->ident); 34477836SJohn.Forte@Sun.COM 34487836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 34497836SJohn.Forte@Sun.COM } 34507836SJohn.Forte@Sun.COM 34517836SJohn.Forte@Sun.COM /* 34527836SJohn.Forte@Sun.COM * stmfFreeMemory 34537836SJohn.Forte@Sun.COM * 34547836SJohn.Forte@Sun.COM * Purpose: Free memory allocated by this library 34557836SJohn.Forte@Sun.COM * 34567836SJohn.Forte@Sun.COM * memory - previously allocated pointer of memory managed by library 34577836SJohn.Forte@Sun.COM */ 34587836SJohn.Forte@Sun.COM void 34597836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory) 34607836SJohn.Forte@Sun.COM { 34617836SJohn.Forte@Sun.COM free(memory); 34627836SJohn.Forte@Sun.COM } 34637836SJohn.Forte@Sun.COM 34647836SJohn.Forte@Sun.COM /* 34659585STim.Szeto@Sun.COM * get host group, target group list from stmf 34667836SJohn.Forte@Sun.COM * 34679585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 34687836SJohn.Forte@Sun.COM */ 34699585STim.Szeto@Sun.COM static int 34709585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType) 34719585STim.Szeto@Sun.COM { 34729585STim.Szeto@Sun.COM int ret; 34739585STim.Szeto@Sun.COM int fd; 34749585STim.Szeto@Sun.COM int ioctlRet; 34759585STim.Szeto@Sun.COM int i; 34769585STim.Szeto@Sun.COM int cmd; 34779585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 34789585STim.Szeto@Sun.COM /* framework group list */ 34799585STim.Szeto@Sun.COM stmf_group_name_t *iGroupList = NULL; 34809585STim.Szeto@Sun.COM uint32_t groupListSize; 34819585STim.Szeto@Sun.COM 34829585STim.Szeto@Sun.COM if (groupList == NULL) { 34839585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 34849585STim.Szeto@Sun.COM } 34859585STim.Szeto@Sun.COM 34869585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 34879585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_LIST; 34889585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 34899585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_LIST; 34909585STim.Szeto@Sun.COM } else { 34919585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 34929585STim.Szeto@Sun.COM } 34939585STim.Szeto@Sun.COM 34949585STim.Szeto@Sun.COM /* call init */ 34959585STim.Szeto@Sun.COM ret = initializeConfig(); 34969585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 34979585STim.Szeto@Sun.COM return (ret); 34989585STim.Szeto@Sun.COM } 34999585STim.Szeto@Sun.COM 35009585STim.Szeto@Sun.COM /* 35019585STim.Szeto@Sun.COM * Open control node for stmf 35029585STim.Szeto@Sun.COM */ 35039585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 35049585STim.Szeto@Sun.COM return (ret); 35059585STim.Szeto@Sun.COM 35069585STim.Szeto@Sun.COM /* 35079585STim.Szeto@Sun.COM * Allocate ioctl input buffer 35089585STim.Szeto@Sun.COM */ 35099585STim.Szeto@Sun.COM groupListSize = ALLOC_GROUP; 35109585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_group_name_t)); 35119585STim.Szeto@Sun.COM iGroupList = (stmf_group_name_t *)calloc(1, groupListSize); 35129585STim.Szeto@Sun.COM if (iGroupList == NULL) { 35139585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 35149585STim.Szeto@Sun.COM goto done; 35159585STim.Szeto@Sun.COM } 35169585STim.Szeto@Sun.COM 35179585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 35189585STim.Szeto@Sun.COM /* 35199585STim.Szeto@Sun.COM * Issue ioctl to get the group list 35209585STim.Szeto@Sun.COM */ 35219585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 35229585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 35239585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 35249585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35259585STim.Szeto@Sun.COM if (ioctlRet != 0) { 35269585STim.Szeto@Sun.COM switch (errno) { 35279585STim.Szeto@Sun.COM case EBUSY: 35289585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 35299585STim.Szeto@Sun.COM break; 35309585STim.Szeto@Sun.COM case EPERM: 35319585STim.Szeto@Sun.COM case EACCES: 35329585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 35339585STim.Szeto@Sun.COM break; 35349585STim.Szeto@Sun.COM default: 35359585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 35369585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 35379585STim.Szeto@Sun.COM errno); 35389585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 35399585STim.Szeto@Sun.COM break; 35409585STim.Szeto@Sun.COM } 35419585STim.Szeto@Sun.COM goto done; 35429585STim.Szeto@Sun.COM } 35439585STim.Szeto@Sun.COM /* 35449585STim.Szeto@Sun.COM * Check whether input buffer was large enough 35459585STim.Szeto@Sun.COM */ 35469585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) { 35479585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 35489585STim.Szeto@Sun.COM sizeof (stmf_group_name_t); 35499585STim.Szeto@Sun.COM iGroupList = realloc(iGroupList, groupListSize); 35509585STim.Szeto@Sun.COM if (iGroupList == NULL) { 35519585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 35529585STim.Szeto@Sun.COM goto done; 35539585STim.Szeto@Sun.COM } 35549585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 35559585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 35569585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35579585STim.Szeto@Sun.COM if (ioctlRet != 0) { 35589585STim.Szeto@Sun.COM switch (errno) { 35599585STim.Szeto@Sun.COM case EBUSY: 35609585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 35619585STim.Szeto@Sun.COM break; 35629585STim.Szeto@Sun.COM case EPERM: 35639585STim.Szeto@Sun.COM case EACCES: 35649585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 35659585STim.Szeto@Sun.COM break; 35669585STim.Szeto@Sun.COM default: 35679585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 35689585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 35699585STim.Szeto@Sun.COM errno); 35709585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 35719585STim.Szeto@Sun.COM break; 35729585STim.Szeto@Sun.COM } 35739585STim.Szeto@Sun.COM goto done; 35749585STim.Szeto@Sun.COM } 35759585STim.Szeto@Sun.COM } 35769585STim.Szeto@Sun.COM 35779585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 357810236SSrivijitha.Dugganapalli@Sun.COM *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) + 357910236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries); 35809585STim.Szeto@Sun.COM if (*groupList == NULL) { 35819585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 35829585STim.Szeto@Sun.COM goto done; 35839585STim.Szeto@Sun.COM } 35849585STim.Szeto@Sun.COM (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries; 35859585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 358610113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupList[i].name, (*groupList)->name[i], 35879585STim.Szeto@Sun.COM sizeof (stmfGroupName)); 35889585STim.Szeto@Sun.COM } 35899585STim.Szeto@Sun.COM 35909585STim.Szeto@Sun.COM done: 35919585STim.Szeto@Sun.COM free(iGroupList); 35929585STim.Szeto@Sun.COM (void) close(fd); 35939585STim.Szeto@Sun.COM return (ret); 35949585STim.Szeto@Sun.COM } 35959585STim.Szeto@Sun.COM 35969585STim.Szeto@Sun.COM /* 35979585STim.Szeto@Sun.COM * get host group members, target group members from stmf 35989585STim.Szeto@Sun.COM * 35999585STim.Szeto@Sun.COM * groupProps - allocated on success 36009585STim.Szeto@Sun.COM * 36019585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 36029585STim.Szeto@Sun.COM */ 36039585STim.Szeto@Sun.COM static int 36049585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps, 36059585STim.Szeto@Sun.COM int groupType) 36067836SJohn.Forte@Sun.COM { 36077836SJohn.Forte@Sun.COM int ret; 36089585STim.Szeto@Sun.COM int fd; 36099585STim.Szeto@Sun.COM int ioctlRet; 36109585STim.Szeto@Sun.COM int i; 36119585STim.Szeto@Sun.COM int cmd; 36129585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 36139585STim.Szeto@Sun.COM /* framework group list */ 36149585STim.Szeto@Sun.COM stmf_group_name_t iGroupName; 36159585STim.Szeto@Sun.COM stmf_ge_ident_t *iGroupMembers; 36169585STim.Szeto@Sun.COM uint32_t groupListSize; 36179585STim.Szeto@Sun.COM 36189585STim.Szeto@Sun.COM if (groupName == NULL) { 36199585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 36209585STim.Szeto@Sun.COM } 36219585STim.Szeto@Sun.COM 36229585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 36239585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_ENTRIES; 36249585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 36259585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_ENTRIES; 36269585STim.Szeto@Sun.COM } else { 36277836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36287836SJohn.Forte@Sun.COM } 36297836SJohn.Forte@Sun.COM 36309585STim.Szeto@Sun.COM /* call init */ 36319585STim.Szeto@Sun.COM ret = initializeConfig(); 36329585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 36339585STim.Szeto@Sun.COM return (ret); 36349585STim.Szeto@Sun.COM } 36359585STim.Szeto@Sun.COM 36369585STim.Szeto@Sun.COM /* 36379585STim.Szeto@Sun.COM * Open control node for stmf 36389585STim.Szeto@Sun.COM */ 36399585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 36409585STim.Szeto@Sun.COM return (ret); 36419585STim.Szeto@Sun.COM 36429585STim.Szeto@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 36439585STim.Szeto@Sun.COM 36449585STim.Szeto@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 36459585STim.Szeto@Sun.COM 36469585STim.Szeto@Sun.COM iGroupName.name_size = strlen((char *)groupName); 36479585STim.Szeto@Sun.COM 36489585STim.Szeto@Sun.COM /* 36499585STim.Szeto@Sun.COM * Allocate ioctl input buffer 36509585STim.Szeto@Sun.COM */ 36519585STim.Szeto@Sun.COM groupListSize = ALLOC_GRP_MEMBER; 36529585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_ge_ident_t)); 36539585STim.Szeto@Sun.COM iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize); 36549585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 36559585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 36569585STim.Szeto@Sun.COM goto done; 36579585STim.Szeto@Sun.COM } 36589585STim.Szeto@Sun.COM 36599585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 36609585STim.Szeto@Sun.COM /* 36619585STim.Szeto@Sun.COM * Issue ioctl to get the group list 36629585STim.Szeto@Sun.COM */ 36639585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 36649585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 36659585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 36669585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 36679585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 36689585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 36699585STim.Szeto@Sun.COM if (ioctlRet != 0) { 36709585STim.Szeto@Sun.COM switch (errno) { 36719585STim.Szeto@Sun.COM case EBUSY: 36729585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 36739585STim.Szeto@Sun.COM break; 36749585STim.Szeto@Sun.COM case EPERM: 36759585STim.Szeto@Sun.COM case EACCES: 36769585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 36779585STim.Szeto@Sun.COM break; 36789585STim.Szeto@Sun.COM default: 36799585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 36809585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 36819585STim.Szeto@Sun.COM errno); 36829585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 36839585STim.Szeto@Sun.COM break; 36849585STim.Szeto@Sun.COM } 36859585STim.Szeto@Sun.COM goto done; 36869585STim.Szeto@Sun.COM } 36879585STim.Szeto@Sun.COM /* 36889585STim.Szeto@Sun.COM * Check whether input buffer was large enough 36899585STim.Szeto@Sun.COM */ 36909585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) { 36919585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 36929585STim.Szeto@Sun.COM sizeof (stmf_ge_ident_t); 36939585STim.Szeto@Sun.COM iGroupMembers = realloc(iGroupMembers, groupListSize); 36949585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 36959585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 36969585STim.Szeto@Sun.COM goto done; 36979585STim.Szeto@Sun.COM } 36989585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 36999585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 37009585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 37019585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 37029585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 37039585STim.Szeto@Sun.COM if (ioctlRet != 0) { 37049585STim.Szeto@Sun.COM switch (errno) { 37059585STim.Szeto@Sun.COM case EBUSY: 37069585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 37079585STim.Szeto@Sun.COM break; 37089585STim.Szeto@Sun.COM case EPERM: 37099585STim.Szeto@Sun.COM case EACCES: 37109585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 37119585STim.Szeto@Sun.COM break; 37129585STim.Szeto@Sun.COM default: 37139585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 37149585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 37159585STim.Szeto@Sun.COM errno); 37169585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 37179585STim.Szeto@Sun.COM break; 37189585STim.Szeto@Sun.COM } 37199585STim.Szeto@Sun.COM goto done; 37209585STim.Szeto@Sun.COM } 37219585STim.Szeto@Sun.COM } 37229585STim.Szeto@Sun.COM 37239585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 37249585STim.Szeto@Sun.COM *groupProps = (stmfGroupProperties *)calloc(1, 372510236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupProperties) + 372610236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries); 37279585STim.Szeto@Sun.COM if (*groupProps == NULL) { 37289585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37299585STim.Szeto@Sun.COM goto done; 37309585STim.Szeto@Sun.COM } 37319585STim.Szeto@Sun.COM (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries; 37329585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 37339585STim.Szeto@Sun.COM (*groupProps)->name[i].identLength = 373410113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size; 373510113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident, 373610113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size); 37379585STim.Szeto@Sun.COM } 37389585STim.Szeto@Sun.COM 37399585STim.Szeto@Sun.COM done: 37409585STim.Szeto@Sun.COM free(iGroupMembers); 37419585STim.Szeto@Sun.COM (void) close(fd); 37429585STim.Szeto@Sun.COM return (ret); 37439585STim.Szeto@Sun.COM } 37449585STim.Szeto@Sun.COM 37459585STim.Szeto@Sun.COM /* 37469585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 37479585STim.Szeto@Sun.COM */ 37489585STim.Szeto@Sun.COM static int 37499585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type) 37509585STim.Szeto@Sun.COM { 37519585STim.Szeto@Sun.COM int ret; 37529585STim.Szeto@Sun.COM 37539585STim.Szeto@Sun.COM if (groupList == NULL) { 37549585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 37559585STim.Szeto@Sun.COM } 37569585STim.Szeto@Sun.COM 37579585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 37589585STim.Szeto@Sun.COM ret = psGetHostGroupList(groupList); 37599585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 37609585STim.Szeto@Sun.COM ret = psGetTargetGroupList(groupList); 37619585STim.Szeto@Sun.COM } else { 37629585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 37639585STim.Szeto@Sun.COM } 37647836SJohn.Forte@Sun.COM switch (ret) { 37657836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 37667836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 37677836SJohn.Forte@Sun.COM break; 37687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 37697836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 37707836SJohn.Forte@Sun.COM break; 37717836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 37727836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37737836SJohn.Forte@Sun.COM break; 37747836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 37757836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 37767836SJohn.Forte@Sun.COM break; 37777836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 37787836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 37797836SJohn.Forte@Sun.COM break; 37807836SJohn.Forte@Sun.COM default: 37817836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37827836SJohn.Forte@Sun.COM "stmfGetHostGroupList:psGetHostGroupList:error(%d)", 37837836SJohn.Forte@Sun.COM ret); 37847836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37857836SJohn.Forte@Sun.COM break; 37867836SJohn.Forte@Sun.COM } 37877836SJohn.Forte@Sun.COM 37887836SJohn.Forte@Sun.COM return (ret); 37897836SJohn.Forte@Sun.COM } 37907836SJohn.Forte@Sun.COM 37917836SJohn.Forte@Sun.COM /* 37929585STim.Szeto@Sun.COM * stmfGetHostGroupList 37937836SJohn.Forte@Sun.COM * 37949585STim.Szeto@Sun.COM * Purpose: Retrieves the list of initiator group oids 37959585STim.Szeto@Sun.COM * 37969585STim.Szeto@Sun.COM * hostGroupList - pointer to pointer to hostGroupList structure 37979585STim.Szeto@Sun.COM * on success, this contains the host group list. 37987836SJohn.Forte@Sun.COM */ 37997836SJohn.Forte@Sun.COM int 38009585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList) 38019585STim.Szeto@Sun.COM { 38029585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 38039585STim.Szeto@Sun.COM 38049585STim.Szeto@Sun.COM if (hostGroupList == NULL) { 38059585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 38069585STim.Szeto@Sun.COM } 38079585STim.Szeto@Sun.COM 38089585STim.Szeto@Sun.COM ret = groupListIoctl(hostGroupList, HOST_GROUP); 38099585STim.Szeto@Sun.COM return (ret); 38109585STim.Szeto@Sun.COM } 38119585STim.Szeto@Sun.COM 38129585STim.Szeto@Sun.COM 38139585STim.Szeto@Sun.COM /* 38149585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 38159585STim.Szeto@Sun.COM */ 38169585STim.Szeto@Sun.COM static int 38179585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName, 38189585STim.Szeto@Sun.COM stmfGroupProperties **groupProp, int type) 38197836SJohn.Forte@Sun.COM { 38207836SJohn.Forte@Sun.COM int ret; 38217836SJohn.Forte@Sun.COM 38229585STim.Szeto@Sun.COM if (groupName == NULL) { 38237836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38247836SJohn.Forte@Sun.COM } 38257836SJohn.Forte@Sun.COM 38269585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 38279585STim.Szeto@Sun.COM ret = psGetHostGroupMemberList((char *)groupName, groupProp); 38289585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 38299585STim.Szeto@Sun.COM ret = psGetTargetGroupMemberList((char *)groupName, groupProp); 38309585STim.Szeto@Sun.COM } else { 38319585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 38329585STim.Szeto@Sun.COM } 38337836SJohn.Forte@Sun.COM switch (ret) { 38347836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 38357836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 38367836SJohn.Forte@Sun.COM break; 38377836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 38387836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 38397836SJohn.Forte@Sun.COM break; 38407836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 38417836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 38427836SJohn.Forte@Sun.COM break; 38437836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 38447836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 38457836SJohn.Forte@Sun.COM break; 38467836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 38477836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 38487836SJohn.Forte@Sun.COM break; 38497836SJohn.Forte@Sun.COM default: 38507836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 38519585STim.Szeto@Sun.COM "iLoadGroupMembersFromPs:psGetHostGroupList:" 38529585STim.Szeto@Sun.COM "error(%d)", ret); 38537836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 38547836SJohn.Forte@Sun.COM break; 38557836SJohn.Forte@Sun.COM } 38567836SJohn.Forte@Sun.COM 38577836SJohn.Forte@Sun.COM return (ret); 38587836SJohn.Forte@Sun.COM } 38597836SJohn.Forte@Sun.COM 38607836SJohn.Forte@Sun.COM /* 38619585STim.Szeto@Sun.COM * stmfGetHostGroupMembers 38629585STim.Szeto@Sun.COM * 38639585STim.Szeto@Sun.COM * Purpose: Retrieves the group properties for a host group 38649585STim.Szeto@Sun.COM * 38659585STim.Szeto@Sun.COM * groupName - name of group for which to retrieve host group members. 38669585STim.Szeto@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 38679585STim.Szeto@Sun.COM * on success, this contains the list of group members. 38689585STim.Szeto@Sun.COM */ 38699585STim.Szeto@Sun.COM int 38709585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName, 38719585STim.Szeto@Sun.COM stmfGroupProperties **groupProp) 38729585STim.Szeto@Sun.COM { 38739585STim.Szeto@Sun.COM int ret; 38749585STim.Szeto@Sun.COM 38759585STim.Szeto@Sun.COM if (groupName == NULL || groupProp == NULL) { 38769585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 38779585STim.Szeto@Sun.COM } 38789585STim.Szeto@Sun.COM 38799585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP); 38809585STim.Szeto@Sun.COM 38819585STim.Szeto@Sun.COM return (ret); 38829585STim.Szeto@Sun.COM } 38839585STim.Szeto@Sun.COM 38849585STim.Szeto@Sun.COM /* 38857836SJohn.Forte@Sun.COM * stmfGetProviderData 38867836SJohn.Forte@Sun.COM * 38877836SJohn.Forte@Sun.COM * Purpose: Get provider data list 38887836SJohn.Forte@Sun.COM * 38897836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 38907836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 38917836SJohn.Forte@Sun.COM * retrieved. 38927836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 38937836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 38947836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 38957836SJohn.Forte@Sun.COM */ 38967836SJohn.Forte@Sun.COM int 38977836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType) 38987836SJohn.Forte@Sun.COM { 38997836SJohn.Forte@Sun.COM return (stmfGetProviderDataProt(providerName, nvl, providerType, 39007836SJohn.Forte@Sun.COM NULL)); 39017836SJohn.Forte@Sun.COM } 39027836SJohn.Forte@Sun.COM 39037836SJohn.Forte@Sun.COM /* 39047836SJohn.Forte@Sun.COM * stmfGetProviderDataProt 39057836SJohn.Forte@Sun.COM * 39067836SJohn.Forte@Sun.COM * Purpose: Get provider data list with token 39077836SJohn.Forte@Sun.COM * 39087836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 39097836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 39107836SJohn.Forte@Sun.COM * retrieved. 39117836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 39127836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 39137836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 39147836SJohn.Forte@Sun.COM * setToken - Returns the stale data token 39157836SJohn.Forte@Sun.COM */ 39167836SJohn.Forte@Sun.COM int 39177836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType, 39187836SJohn.Forte@Sun.COM uint64_t *setToken) 39197836SJohn.Forte@Sun.COM { 39207836SJohn.Forte@Sun.COM int ret; 39217836SJohn.Forte@Sun.COM 39227836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 39237836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39247836SJohn.Forte@Sun.COM } 39257836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 39267836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 39277836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39287836SJohn.Forte@Sun.COM } 39297836SJohn.Forte@Sun.COM /* call init */ 39307836SJohn.Forte@Sun.COM ret = initializeConfig(); 39317836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39327836SJohn.Forte@Sun.COM return (ret); 39337836SJohn.Forte@Sun.COM } 39349585STim.Szeto@Sun.COM return (getProviderData(providerName, nvl, providerType, setToken)); 39357836SJohn.Forte@Sun.COM } 39367836SJohn.Forte@Sun.COM 39377836SJohn.Forte@Sun.COM /* 39387836SJohn.Forte@Sun.COM * stmfGetProviderDataList 39397836SJohn.Forte@Sun.COM * 39407836SJohn.Forte@Sun.COM * Purpose: Get the list of providers currently persisting data 39417836SJohn.Forte@Sun.COM * 39427836SJohn.Forte@Sun.COM * providerList - pointer to pointer to an stmfProviderList structure allocated 39437836SJohn.Forte@Sun.COM * by the caller. Will contain the list of providers on success. 39447836SJohn.Forte@Sun.COM */ 39457836SJohn.Forte@Sun.COM int 39467836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList) 39477836SJohn.Forte@Sun.COM { 39487836SJohn.Forte@Sun.COM int ret; 39497836SJohn.Forte@Sun.COM 39507836SJohn.Forte@Sun.COM ret = psGetProviderDataList(providerList); 39517836SJohn.Forte@Sun.COM switch (ret) { 39527836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 39537836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 39547836SJohn.Forte@Sun.COM break; 39557836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 39567836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39577836SJohn.Forte@Sun.COM break; 39587836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 39597836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 39607836SJohn.Forte@Sun.COM break; 39617836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 39627836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 39637836SJohn.Forte@Sun.COM break; 39647836SJohn.Forte@Sun.COM default: 39657836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39667836SJohn.Forte@Sun.COM "stmfGetProviderDataList:psGetProviderDataList" 39677836SJohn.Forte@Sun.COM ":error(%d)", ret); 39687836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39697836SJohn.Forte@Sun.COM break; 39707836SJohn.Forte@Sun.COM } 39717836SJohn.Forte@Sun.COM 39727836SJohn.Forte@Sun.COM return (ret); 39737836SJohn.Forte@Sun.COM } 39747836SJohn.Forte@Sun.COM 39757836SJohn.Forte@Sun.COM 39767836SJohn.Forte@Sun.COM /* 39777836SJohn.Forte@Sun.COM * stmfGetSessionList 39787836SJohn.Forte@Sun.COM * 39797836SJohn.Forte@Sun.COM * Purpose: Retrieves the session list for a target (devid) 39807836SJohn.Forte@Sun.COM * 39817836SJohn.Forte@Sun.COM * devid - devid of target for which to retrieve session information. 39827836SJohn.Forte@Sun.COM * sessionList - pointer to pointer to stmfSessionList structure 39837836SJohn.Forte@Sun.COM * on success, this contains the list of initiator sessions. 39847836SJohn.Forte@Sun.COM */ 39857836SJohn.Forte@Sun.COM int 39867836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList) 39877836SJohn.Forte@Sun.COM { 39887836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 39897836SJohn.Forte@Sun.COM int fd; 39907836SJohn.Forte@Sun.COM int ioctlRet; 39917836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_SESSION_LIST; 39927836SJohn.Forte@Sun.COM int i; 39937836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 399410261SCharles.Ting@Sun.COM slist_scsi_session_t *fSessionList, *fSessionListP = NULL; 39957836SJohn.Forte@Sun.COM uint8_t ident[260]; 39967836SJohn.Forte@Sun.COM uint32_t fSessionListSize; 39977836SJohn.Forte@Sun.COM 39987836SJohn.Forte@Sun.COM if (sessionList == NULL || devid == NULL) { 39997836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 40007836SJohn.Forte@Sun.COM } 40017836SJohn.Forte@Sun.COM 40027836SJohn.Forte@Sun.COM /* call init */ 40037836SJohn.Forte@Sun.COM ret = initializeConfig(); 40047836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 40057836SJohn.Forte@Sun.COM return (ret); 40067836SJohn.Forte@Sun.COM } 40077836SJohn.Forte@Sun.COM 40087836SJohn.Forte@Sun.COM /* 40097836SJohn.Forte@Sun.COM * Open control node for stmf 40107836SJohn.Forte@Sun.COM */ 40117836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 40127836SJohn.Forte@Sun.COM return (ret); 40137836SJohn.Forte@Sun.COM 40147836SJohn.Forte@Sun.COM /* 40157836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 40167836SJohn.Forte@Sun.COM */ 40179585STim.Szeto@Sun.COM fSessionListSize = ALLOC_SESSION; 40187836SJohn.Forte@Sun.COM fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t)); 40197836SJohn.Forte@Sun.COM fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize); 402010261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 40217836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 402210261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 402310261SCharles.Ting@Sun.COM goto done; 40247836SJohn.Forte@Sun.COM } 40257836SJohn.Forte@Sun.COM 40267836SJohn.Forte@Sun.COM ident[IDENT_LENGTH_BYTE] = devid->identLength; 40277836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1], 40287836SJohn.Forte@Sun.COM devid->identLength); 40297836SJohn.Forte@Sun.COM 40307836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 40317836SJohn.Forte@Sun.COM /* 40327836SJohn.Forte@Sun.COM * Issue ioctl to get the session list 40337836SJohn.Forte@Sun.COM */ 40347836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 40357836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident; 40367836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ident); 40377836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 40387836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 40397836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40407836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40417836SJohn.Forte@Sun.COM switch (errno) { 40427836SJohn.Forte@Sun.COM case EBUSY: 40437836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40447836SJohn.Forte@Sun.COM break; 40459585STim.Szeto@Sun.COM case EPERM: 40467836SJohn.Forte@Sun.COM case EACCES: 40477836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40487836SJohn.Forte@Sun.COM break; 40497836SJohn.Forte@Sun.COM default: 40507836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40517836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl errno(%d)", 40527836SJohn.Forte@Sun.COM errno); 40537836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40547836SJohn.Forte@Sun.COM break; 40557836SJohn.Forte@Sun.COM } 40567836SJohn.Forte@Sun.COM goto done; 40577836SJohn.Forte@Sun.COM } 40587836SJohn.Forte@Sun.COM /* 40597836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 40607836SJohn.Forte@Sun.COM */ 40619585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) { 40627836SJohn.Forte@Sun.COM fSessionListSize = stmfIoctl.stmf_obuf_max_nentries * 40637836SJohn.Forte@Sun.COM sizeof (slist_scsi_session_t); 40647836SJohn.Forte@Sun.COM fSessionList = realloc(fSessionList, fSessionListSize); 40657836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 406610261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 406710261SCharles.Ting@Sun.COM goto done; 40687836SJohn.Forte@Sun.COM } 406910261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 40707836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 40717836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 40727836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40737836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40747836SJohn.Forte@Sun.COM switch (errno) { 40757836SJohn.Forte@Sun.COM case EBUSY: 40767836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40777836SJohn.Forte@Sun.COM break; 40789585STim.Szeto@Sun.COM case EPERM: 40797836SJohn.Forte@Sun.COM case EACCES: 40807836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40817836SJohn.Forte@Sun.COM break; 40827836SJohn.Forte@Sun.COM default: 40837836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40847836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl " 40857836SJohn.Forte@Sun.COM "errno(%d)", errno); 40867836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40877836SJohn.Forte@Sun.COM break; 40887836SJohn.Forte@Sun.COM } 40897836SJohn.Forte@Sun.COM goto done; 40907836SJohn.Forte@Sun.COM } 40917836SJohn.Forte@Sun.COM } 40927836SJohn.Forte@Sun.COM 40937836SJohn.Forte@Sun.COM /* 40947836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 40957836SJohn.Forte@Sun.COM */ 40967836SJohn.Forte@Sun.COM *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) + 40977836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession)); 40987836SJohn.Forte@Sun.COM if (*sessionList == NULL) { 40997836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 41007836SJohn.Forte@Sun.COM free(sessionList); 41017836SJohn.Forte@Sun.COM goto done; 41027836SJohn.Forte@Sun.COM } 41037836SJohn.Forte@Sun.COM 41047836SJohn.Forte@Sun.COM (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 41057836SJohn.Forte@Sun.COM 41067836SJohn.Forte@Sun.COM /* 41077836SJohn.Forte@Sun.COM * copy session info to caller's buffer 41087836SJohn.Forte@Sun.COM */ 41097836SJohn.Forte@Sun.COM for (i = 0; i < (*sessionList)->cnt; i++) { 41107836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.identLength = 41117836SJohn.Forte@Sun.COM fSessionList->initiator[IDENT_LENGTH_BYTE]; 41127836SJohn.Forte@Sun.COM bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]), 41137836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.ident, 41147836SJohn.Forte@Sun.COM STMF_IDENT_LENGTH); 41157836SJohn.Forte@Sun.COM bcopy(&(fSessionList->alias), 41167836SJohn.Forte@Sun.COM &((*sessionList)->session[i].alias), 41177836SJohn.Forte@Sun.COM sizeof ((*sessionList)->session[i].alias)); 41187836SJohn.Forte@Sun.COM bcopy(&(fSessionList++->creation_time), 41197836SJohn.Forte@Sun.COM &((*sessionList)->session[i].creationTime), 41207836SJohn.Forte@Sun.COM sizeof (time_t)); 41217836SJohn.Forte@Sun.COM } 41227836SJohn.Forte@Sun.COM done: 41237836SJohn.Forte@Sun.COM (void) close(fd); 412410261SCharles.Ting@Sun.COM free(fSessionListP); 41257836SJohn.Forte@Sun.COM return (ret); 41267836SJohn.Forte@Sun.COM } 41277836SJohn.Forte@Sun.COM 41287836SJohn.Forte@Sun.COM /* 41297836SJohn.Forte@Sun.COM * stmfGetTargetGroupList 41307836SJohn.Forte@Sun.COM * 41317836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target groups 41327836SJohn.Forte@Sun.COM * 41337836SJohn.Forte@Sun.COM * targetGroupList - pointer to a pointer to an stmfGroupList structure. On 41347836SJohn.Forte@Sun.COM * success, it contains the list of target groups. 41357836SJohn.Forte@Sun.COM */ 41367836SJohn.Forte@Sun.COM int 41377836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList) 41387836SJohn.Forte@Sun.COM { 41397836SJohn.Forte@Sun.COM int ret; 41407836SJohn.Forte@Sun.COM 41417836SJohn.Forte@Sun.COM if (targetGroupList == NULL) { 41427836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41437836SJohn.Forte@Sun.COM } 41447836SJohn.Forte@Sun.COM 41459585STim.Szeto@Sun.COM ret = groupListIoctl(targetGroupList, TARGET_GROUP); 41467836SJohn.Forte@Sun.COM return (ret); 41477836SJohn.Forte@Sun.COM } 41487836SJohn.Forte@Sun.COM 41497836SJohn.Forte@Sun.COM /* 41507836SJohn.Forte@Sun.COM * stmfGetTargetGroupMembers 41517836SJohn.Forte@Sun.COM * 41527836SJohn.Forte@Sun.COM * Purpose: Retrieves the group members for a target group 41537836SJohn.Forte@Sun.COM * 41547836SJohn.Forte@Sun.COM * groupName - name of target group for which to retrieve members. 41557836SJohn.Forte@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 41567836SJohn.Forte@Sun.COM * on success, this contains the list of group members. 41577836SJohn.Forte@Sun.COM */ 41587836SJohn.Forte@Sun.COM int 41597836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName, 41607836SJohn.Forte@Sun.COM stmfGroupProperties **groupProp) 41617836SJohn.Forte@Sun.COM { 41627836SJohn.Forte@Sun.COM int ret; 41637836SJohn.Forte@Sun.COM 41647836SJohn.Forte@Sun.COM if (groupName == NULL || groupProp == NULL) { 41657836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41667836SJohn.Forte@Sun.COM } 41677836SJohn.Forte@Sun.COM 41689585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP); 41697836SJohn.Forte@Sun.COM 41707836SJohn.Forte@Sun.COM return (ret); 41717836SJohn.Forte@Sun.COM } 41727836SJohn.Forte@Sun.COM 41737836SJohn.Forte@Sun.COM /* 41747836SJohn.Forte@Sun.COM * stmfGetTargetList 41757836SJohn.Forte@Sun.COM * 41767836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target ports 41777836SJohn.Forte@Sun.COM * 41787836SJohn.Forte@Sun.COM * targetList - pointer to a pointer to an stmfDevidList structure. 41797836SJohn.Forte@Sun.COM * On success, it contains the list of local ports (target). 41807836SJohn.Forte@Sun.COM */ 41817836SJohn.Forte@Sun.COM int 41827836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList) 41837836SJohn.Forte@Sun.COM { 41847836SJohn.Forte@Sun.COM int ret; 41857836SJohn.Forte@Sun.COM int fd; 41867836SJohn.Forte@Sun.COM int ioctlRet; 41877836SJohn.Forte@Sun.COM int i; 41887836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 41897836SJohn.Forte@Sun.COM /* framework target port list */ 41909585STim.Szeto@Sun.COM slist_target_port_t *fTargetList, *fTargetListP = NULL; 41917836SJohn.Forte@Sun.COM uint32_t fTargetListSize; 41927836SJohn.Forte@Sun.COM 41937836SJohn.Forte@Sun.COM if (targetList == NULL) { 41947836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41957836SJohn.Forte@Sun.COM } 41967836SJohn.Forte@Sun.COM 41977836SJohn.Forte@Sun.COM /* call init */ 41987836SJohn.Forte@Sun.COM ret = initializeConfig(); 41997836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42007836SJohn.Forte@Sun.COM return (ret); 42017836SJohn.Forte@Sun.COM } 42027836SJohn.Forte@Sun.COM 42037836SJohn.Forte@Sun.COM /* 42047836SJohn.Forte@Sun.COM * Open control node for stmf 42057836SJohn.Forte@Sun.COM */ 42067836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 42077836SJohn.Forte@Sun.COM return (ret); 42087836SJohn.Forte@Sun.COM 42097836SJohn.Forte@Sun.COM /* 42107836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 42117836SJohn.Forte@Sun.COM */ 42129585STim.Szeto@Sun.COM fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t); 42138252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 42148252SJohn.Forte@Sun.COM (slist_target_port_t *)calloc(1, fTargetListSize); 42157836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 42169585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42177836SJohn.Forte@Sun.COM goto done; 42187836SJohn.Forte@Sun.COM } 42197836SJohn.Forte@Sun.COM 42207836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 42217836SJohn.Forte@Sun.COM /* 42228252SJohn.Forte@Sun.COM * Issue ioctl to retrieve target list 42237836SJohn.Forte@Sun.COM */ 42247836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 42257836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 42267836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 42277836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl); 42287836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 42297836SJohn.Forte@Sun.COM switch (errno) { 42307836SJohn.Forte@Sun.COM case EBUSY: 42317836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 42327836SJohn.Forte@Sun.COM break; 42339585STim.Szeto@Sun.COM case EPERM: 42347836SJohn.Forte@Sun.COM case EACCES: 42357836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 42367836SJohn.Forte@Sun.COM break; 42377836SJohn.Forte@Sun.COM default: 42387836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 42397836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", errno); 42407836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 42417836SJohn.Forte@Sun.COM break; 42427836SJohn.Forte@Sun.COM } 42437836SJohn.Forte@Sun.COM goto done; 42447836SJohn.Forte@Sun.COM } 42457836SJohn.Forte@Sun.COM /* 42467836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 42477836SJohn.Forte@Sun.COM */ 42489585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) { 42497836SJohn.Forte@Sun.COM fTargetListSize = stmfIoctl.stmf_obuf_max_nentries * 42508116SJohn.Forte@Sun.COM sizeof (slist_target_port_t); 42518252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 42528252SJohn.Forte@Sun.COM realloc(fTargetList, fTargetListSize); 42537836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 42549585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42559585STim.Szeto@Sun.COM goto done; 42567836SJohn.Forte@Sun.COM } 42577836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 42587836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 42597836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, 42607836SJohn.Forte@Sun.COM &stmfIoctl); 42617836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 42627836SJohn.Forte@Sun.COM switch (errno) { 42637836SJohn.Forte@Sun.COM case EBUSY: 42647836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 42657836SJohn.Forte@Sun.COM break; 42669585STim.Szeto@Sun.COM case EPERM: 42677836SJohn.Forte@Sun.COM case EACCES: 42687836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 42697836SJohn.Forte@Sun.COM break; 42707836SJohn.Forte@Sun.COM default: 42717836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 42727836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", 42737836SJohn.Forte@Sun.COM errno); 42747836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 42757836SJohn.Forte@Sun.COM break; 42767836SJohn.Forte@Sun.COM } 42777836SJohn.Forte@Sun.COM goto done; 42787836SJohn.Forte@Sun.COM } 42797836SJohn.Forte@Sun.COM } 42807836SJohn.Forte@Sun.COM 42817836SJohn.Forte@Sun.COM *targetList = (stmfDevidList *)calloc(1, 42827836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) + 42837836SJohn.Forte@Sun.COM sizeof (stmfDevidList)); 42849585STim.Szeto@Sun.COM if (*targetList == NULL) { 42859585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42869585STim.Szeto@Sun.COM goto done; 42879585STim.Szeto@Sun.COM } 42887836SJohn.Forte@Sun.COM 42897836SJohn.Forte@Sun.COM (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 42907836SJohn.Forte@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) { 42917836SJohn.Forte@Sun.COM (*targetList)->devid[i].identLength = 42927836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]; 42937836SJohn.Forte@Sun.COM bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1], 42947836SJohn.Forte@Sun.COM &(*targetList)->devid[i].ident, 42957836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]); 42967836SJohn.Forte@Sun.COM } 42977836SJohn.Forte@Sun.COM 42987836SJohn.Forte@Sun.COM done: 42997836SJohn.Forte@Sun.COM (void) close(fd); 43008252SJohn.Forte@Sun.COM free(fTargetListP); 43017836SJohn.Forte@Sun.COM return (ret); 43027836SJohn.Forte@Sun.COM } 43037836SJohn.Forte@Sun.COM 43047836SJohn.Forte@Sun.COM /* 43057836SJohn.Forte@Sun.COM * stmfGetTargetProperties 43067836SJohn.Forte@Sun.COM * 43077836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 43087836SJohn.Forte@Sun.COM * 43097836SJohn.Forte@Sun.COM * devid - devid of the target for which to retrieve properties 43107836SJohn.Forte@Sun.COM * targetProps - pointer to an stmfTargetProperties structure. 43117836SJohn.Forte@Sun.COM * On success, it contains the target properties for 43127836SJohn.Forte@Sun.COM * the specified devid. 43137836SJohn.Forte@Sun.COM */ 43147836SJohn.Forte@Sun.COM int 43157836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps) 43167836SJohn.Forte@Sun.COM { 43177836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 43187836SJohn.Forte@Sun.COM int fd; 43197836SJohn.Forte@Sun.COM int ioctlRet; 43207836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 43217836SJohn.Forte@Sun.COM sioc_target_port_props_t targetProperties; 432210725SJohn.Forte@Sun.COM scsi_devid_desc_t *scsiDevid; 43237836SJohn.Forte@Sun.COM 43247836SJohn.Forte@Sun.COM if (devid == NULL || targetProps == NULL) { 43257836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 43267836SJohn.Forte@Sun.COM } 43277836SJohn.Forte@Sun.COM 43287836SJohn.Forte@Sun.COM /* call init */ 43297836SJohn.Forte@Sun.COM ret = initializeConfig(); 43307836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 43317836SJohn.Forte@Sun.COM return (ret); 43327836SJohn.Forte@Sun.COM } 43337836SJohn.Forte@Sun.COM 43347836SJohn.Forte@Sun.COM /* 43357836SJohn.Forte@Sun.COM * Open control node for stmf 43367836SJohn.Forte@Sun.COM */ 43377836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 43387836SJohn.Forte@Sun.COM return (ret); 43397836SJohn.Forte@Sun.COM 43407836SJohn.Forte@Sun.COM targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength; 43417836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1], 43427836SJohn.Forte@Sun.COM devid->identLength); 43437836SJohn.Forte@Sun.COM 43447836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 43457836SJohn.Forte@Sun.COM /* 43467836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 43477836SJohn.Forte@Sun.COM */ 43487836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 43497836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id); 43507836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id; 43517836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties; 43527836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (targetProperties); 43537836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES, 43547836SJohn.Forte@Sun.COM &stmfIoctl); 43557836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 43567836SJohn.Forte@Sun.COM switch (errno) { 43577836SJohn.Forte@Sun.COM case EBUSY: 43587836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 43597836SJohn.Forte@Sun.COM break; 43609585STim.Szeto@Sun.COM case EPERM: 43617836SJohn.Forte@Sun.COM case EACCES: 43627836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 43637836SJohn.Forte@Sun.COM break; 43647836SJohn.Forte@Sun.COM case ENOENT: 43657836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 43667836SJohn.Forte@Sun.COM break; 43677836SJohn.Forte@Sun.COM default: 43687836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 43697836SJohn.Forte@Sun.COM "stmfGetTargetProperties:ioctl errno(%d)", 43707836SJohn.Forte@Sun.COM errno); 43717836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 43727836SJohn.Forte@Sun.COM break; 43737836SJohn.Forte@Sun.COM } 43747836SJohn.Forte@Sun.COM goto done; 43757836SJohn.Forte@Sun.COM } 43767836SJohn.Forte@Sun.COM 43777836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_provider_name, targetProps->providerName, 43787836SJohn.Forte@Sun.COM sizeof (targetProperties.tgt_provider_name)); 43797836SJohn.Forte@Sun.COM if (targetProperties.tgt_state == STMF_STATE_ONLINE) { 43807836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINE; 43817836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) { 43827836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINE; 43837836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) { 43847836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINING; 43857836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) { 43867836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINING; 43877836SJohn.Forte@Sun.COM } 43887836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_alias, targetProps->alias, 43897836SJohn.Forte@Sun.COM sizeof (targetProps->alias)); 439010725SJohn.Forte@Sun.COM 439110725SJohn.Forte@Sun.COM scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id; 439210725SJohn.Forte@Sun.COM targetProps->protocol = scsiDevid->protocol_id; 439310725SJohn.Forte@Sun.COM 43947836SJohn.Forte@Sun.COM done: 43957836SJohn.Forte@Sun.COM (void) close(fd); 43967836SJohn.Forte@Sun.COM return (ret); 43977836SJohn.Forte@Sun.COM } 43987836SJohn.Forte@Sun.COM 43997836SJohn.Forte@Sun.COM /* 44007836SJohn.Forte@Sun.COM * stmfGetLogicalUnitList 44017836SJohn.Forte@Sun.COM * 44027836SJohn.Forte@Sun.COM * Purpose: Retrieves list of logical unit Object IDs 44037836SJohn.Forte@Sun.COM * 44047836SJohn.Forte@Sun.COM * luList - pointer to a pointer to a stmfGuidList structure. On success, 44057836SJohn.Forte@Sun.COM * it contains the list of logical unit guids. 44067836SJohn.Forte@Sun.COM * 44077836SJohn.Forte@Sun.COM */ 44087836SJohn.Forte@Sun.COM int 44097836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList) 44107836SJohn.Forte@Sun.COM { 44117836SJohn.Forte@Sun.COM int ret; 44127836SJohn.Forte@Sun.COM int fd; 44137836SJohn.Forte@Sun.COM int ioctlRet; 44147836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_LU_LIST; 44159585STim.Szeto@Sun.COM int i; 44167836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 44177836SJohn.Forte@Sun.COM slist_lu_t *fLuList; 44187836SJohn.Forte@Sun.COM uint32_t fLuListSize; 44199585STim.Szeto@Sun.COM uint32_t listCnt; 44207836SJohn.Forte@Sun.COM 44217836SJohn.Forte@Sun.COM if (luList == NULL) { 44227836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 44237836SJohn.Forte@Sun.COM } 44247836SJohn.Forte@Sun.COM 44257836SJohn.Forte@Sun.COM /* call init */ 44267836SJohn.Forte@Sun.COM ret = initializeConfig(); 44277836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44287836SJohn.Forte@Sun.COM return (ret); 44297836SJohn.Forte@Sun.COM } 44307836SJohn.Forte@Sun.COM 44317836SJohn.Forte@Sun.COM /* 44327836SJohn.Forte@Sun.COM * Open control node for stmf 44337836SJohn.Forte@Sun.COM */ 44347836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 44357836SJohn.Forte@Sun.COM return (ret); 44367836SJohn.Forte@Sun.COM 44377836SJohn.Forte@Sun.COM /* 44387836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 44397836SJohn.Forte@Sun.COM */ 44409585STim.Szeto@Sun.COM fLuListSize = ALLOC_LU; 44417836SJohn.Forte@Sun.COM fLuListSize = fLuListSize * (sizeof (slist_lu_t)); 44427836SJohn.Forte@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 44437836SJohn.Forte@Sun.COM if (fLuList == NULL) { 44449585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 44459585STim.Szeto@Sun.COM goto done; 44467836SJohn.Forte@Sun.COM } 44477836SJohn.Forte@Sun.COM 44487836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 44497836SJohn.Forte@Sun.COM /* 44507836SJohn.Forte@Sun.COM * Issue ioctl to get the LU list 44517836SJohn.Forte@Sun.COM */ 44527836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 44537836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 44547836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 44557836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 44567836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 44577836SJohn.Forte@Sun.COM switch (errno) { 44587836SJohn.Forte@Sun.COM case EBUSY: 44597836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 44607836SJohn.Forte@Sun.COM break; 44619585STim.Szeto@Sun.COM case EPERM: 44627836SJohn.Forte@Sun.COM case EACCES: 44637836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 44647836SJohn.Forte@Sun.COM break; 44657836SJohn.Forte@Sun.COM default: 44667836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 44677836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:ioctl errno(%d)", 44687836SJohn.Forte@Sun.COM errno); 44697836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 44707836SJohn.Forte@Sun.COM break; 44717836SJohn.Forte@Sun.COM } 44727836SJohn.Forte@Sun.COM goto done; 44737836SJohn.Forte@Sun.COM } 44747836SJohn.Forte@Sun.COM /* 44757836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 44767836SJohn.Forte@Sun.COM */ 44779585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) { 44787836SJohn.Forte@Sun.COM fLuListSize = stmfIoctl.stmf_obuf_max_nentries * 44797836SJohn.Forte@Sun.COM sizeof (slist_lu_t); 44809585STim.Szeto@Sun.COM free(fLuList); 44819585STim.Szeto@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 44827836SJohn.Forte@Sun.COM if (fLuList == NULL) { 44839585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 44849585STim.Szeto@Sun.COM goto done; 44857836SJohn.Forte@Sun.COM } 44867836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 44877836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 44887836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 44897836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 44907836SJohn.Forte@Sun.COM switch (errno) { 44917836SJohn.Forte@Sun.COM case EBUSY: 44927836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 44937836SJohn.Forte@Sun.COM break; 44949585STim.Szeto@Sun.COM case EPERM: 44957836SJohn.Forte@Sun.COM case EACCES: 44967836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 44977836SJohn.Forte@Sun.COM break; 44987836SJohn.Forte@Sun.COM default: 44997836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 45007836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:" 45017836SJohn.Forte@Sun.COM "ioctl errno(%d)", errno); 45027836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45037836SJohn.Forte@Sun.COM break; 45047836SJohn.Forte@Sun.COM } 45057836SJohn.Forte@Sun.COM goto done; 45067836SJohn.Forte@Sun.COM } 45077836SJohn.Forte@Sun.COM } 45087836SJohn.Forte@Sun.COM 45097836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45107836SJohn.Forte@Sun.COM goto done; 45117836SJohn.Forte@Sun.COM } 45127836SJohn.Forte@Sun.COM 45139585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 45147836SJohn.Forte@Sun.COM 45157836SJohn.Forte@Sun.COM /* 45167836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 45177836SJohn.Forte@Sun.COM */ 45187836SJohn.Forte@Sun.COM *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) + 45199585STim.Szeto@Sun.COM listCnt * sizeof (stmfGuid)); 45207836SJohn.Forte@Sun.COM if (*luList == NULL) { 45217836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 45227836SJohn.Forte@Sun.COM goto done; 45237836SJohn.Forte@Sun.COM } 45247836SJohn.Forte@Sun.COM 45259585STim.Szeto@Sun.COM (*luList)->cnt = listCnt; 45269585STim.Szeto@Sun.COM 45279585STim.Szeto@Sun.COM /* copy to caller's buffer */ 45289585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 45299585STim.Szeto@Sun.COM bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid, 45309585STim.Szeto@Sun.COM sizeof (stmfGuid)); 45319585STim.Szeto@Sun.COM } 45329585STim.Szeto@Sun.COM 45337836SJohn.Forte@Sun.COM /* 45349585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 45357836SJohn.Forte@Sun.COM */ 45369585STim.Szeto@Sun.COM qsort((void *)&((*luList)->guid[0]), (*luList)->cnt, 45379585STim.Szeto@Sun.COM sizeof (stmfGuid), guidCompare); 45387836SJohn.Forte@Sun.COM 45397836SJohn.Forte@Sun.COM done: 45407836SJohn.Forte@Sun.COM (void) close(fd); 45417836SJohn.Forte@Sun.COM /* 45427836SJohn.Forte@Sun.COM * free internal buffers 45437836SJohn.Forte@Sun.COM */ 45447836SJohn.Forte@Sun.COM free(fLuList); 45457836SJohn.Forte@Sun.COM return (ret); 45467836SJohn.Forte@Sun.COM } 45477836SJohn.Forte@Sun.COM 45487836SJohn.Forte@Sun.COM /* 45497836SJohn.Forte@Sun.COM * stmfGetLogicalUnitProperties 45507836SJohn.Forte@Sun.COM * 45517836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 45527836SJohn.Forte@Sun.COM * 45537836SJohn.Forte@Sun.COM * lu - guid of the logical unit for which to retrieve properties 45547836SJohn.Forte@Sun.COM * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success, 45557836SJohn.Forte@Sun.COM * it contains the logical unit properties for the specified guid. 45567836SJohn.Forte@Sun.COM */ 45577836SJohn.Forte@Sun.COM int 45587836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps) 45597836SJohn.Forte@Sun.COM { 45607836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 45617836SJohn.Forte@Sun.COM int stmfRet; 45627836SJohn.Forte@Sun.COM int fd; 45637836SJohn.Forte@Sun.COM int ioctlRet; 45647836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_GET_LU_PROPERTIES; 45657836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 45667836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 45677836SJohn.Forte@Sun.COM sioc_lu_props_t fLuProps; 45687836SJohn.Forte@Sun.COM 45699585STim.Szeto@Sun.COM if (lu == NULL || luProps == NULL) { 45709585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 45717836SJohn.Forte@Sun.COM } 45727836SJohn.Forte@Sun.COM 45737836SJohn.Forte@Sun.COM bzero(luProps, sizeof (stmfLogicalUnitProperties)); 45747836SJohn.Forte@Sun.COM 45757836SJohn.Forte@Sun.COM /* call init */ 45767836SJohn.Forte@Sun.COM ret = initializeConfig(); 45777836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45787836SJohn.Forte@Sun.COM return (ret); 45797836SJohn.Forte@Sun.COM } 45807836SJohn.Forte@Sun.COM 45817836SJohn.Forte@Sun.COM /* 45827836SJohn.Forte@Sun.COM * Open control node for stmf 45837836SJohn.Forte@Sun.COM */ 45847836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 45857836SJohn.Forte@Sun.COM return (ret); 45867836SJohn.Forte@Sun.COM 45877836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 45887836SJohn.Forte@Sun.COM /* 45897836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 45907836SJohn.Forte@Sun.COM */ 45917836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 45927836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 45937836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 45947836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps; 45957836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (fLuProps); 45967836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 45977836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 45987836SJohn.Forte@Sun.COM switch (errno) { 45997836SJohn.Forte@Sun.COM case EBUSY: 46007836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46017836SJohn.Forte@Sun.COM break; 46029585STim.Szeto@Sun.COM case EPERM: 46037836SJohn.Forte@Sun.COM case EACCES: 46047836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 46057836SJohn.Forte@Sun.COM break; 46067836SJohn.Forte@Sun.COM case ENOENT: 46077836SJohn.Forte@Sun.COM stmfRet = stmfGetViewEntryList(lu, 46087836SJohn.Forte@Sun.COM &viewEntryList); 46097836SJohn.Forte@Sun.COM if (stmfRet == STMF_STATUS_SUCCESS) { 46107836SJohn.Forte@Sun.COM luProps->status = 46117836SJohn.Forte@Sun.COM STMF_LOGICAL_UNIT_UNREGISTERED; 46127836SJohn.Forte@Sun.COM if (viewEntryList->cnt > 0) { 46137836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46147836SJohn.Forte@Sun.COM } else { 46157836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46167836SJohn.Forte@Sun.COM } 46177836SJohn.Forte@Sun.COM } else { 46187836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46197836SJohn.Forte@Sun.COM } 46207836SJohn.Forte@Sun.COM stmfFreeMemory(viewEntryList); 46217836SJohn.Forte@Sun.COM break; 46227836SJohn.Forte@Sun.COM default: 46237836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 46247836SJohn.Forte@Sun.COM "stmfGetLogicalUnit:ioctl errno(%d)", 46257836SJohn.Forte@Sun.COM errno); 46267836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46277836SJohn.Forte@Sun.COM break; 46287836SJohn.Forte@Sun.COM } 46297836SJohn.Forte@Sun.COM goto done; 46307836SJohn.Forte@Sun.COM } 46317836SJohn.Forte@Sun.COM 46327836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_provider_name, luProps->providerName, 46337836SJohn.Forte@Sun.COM sizeof (fLuProps.lu_provider_name)); 46347836SJohn.Forte@Sun.COM if (fLuProps.lu_state == STMF_STATE_ONLINE) { 46357836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINE; 46367836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) { 46377836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINE; 46387836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_ONLINING) { 46397836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINING; 46407836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) { 46417836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINING; 46427836SJohn.Forte@Sun.COM } 46437836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias)); 46447836SJohn.Forte@Sun.COM done: 46457836SJohn.Forte@Sun.COM (void) close(fd); 46467836SJohn.Forte@Sun.COM return (ret); 46477836SJohn.Forte@Sun.COM } 46487836SJohn.Forte@Sun.COM 46497836SJohn.Forte@Sun.COM /* 46507836SJohn.Forte@Sun.COM * stmfGetState 46517836SJohn.Forte@Sun.COM * 46527836SJohn.Forte@Sun.COM * Purpose: retrieve the current state of the stmf module 46537836SJohn.Forte@Sun.COM * 46547836SJohn.Forte@Sun.COM * state - pointer to stmfState structure allocated by the caller 46557836SJohn.Forte@Sun.COM * On success, contains the state of stmf 46567836SJohn.Forte@Sun.COM */ 46577836SJohn.Forte@Sun.COM int 46587836SJohn.Forte@Sun.COM stmfGetState(stmfState *state) 46597836SJohn.Forte@Sun.COM { 46607836SJohn.Forte@Sun.COM int ret; 46617836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 46627836SJohn.Forte@Sun.COM 46637836SJohn.Forte@Sun.COM if (state == NULL) { 46647836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 46657836SJohn.Forte@Sun.COM } 46667836SJohn.Forte@Sun.COM 46677836SJohn.Forte@Sun.COM ret = getStmfState(&iState); 46687836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46697836SJohn.Forte@Sun.COM return (ret); 46707836SJohn.Forte@Sun.COM } 46717836SJohn.Forte@Sun.COM switch (iState.state) { 46727836SJohn.Forte@Sun.COM case STMF_STATE_ONLINE: 46737836SJohn.Forte@Sun.COM state->operationalState = 46747836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINE; 46757836SJohn.Forte@Sun.COM break; 46767836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINE: 46777836SJohn.Forte@Sun.COM state->operationalState = 46787836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINE; 46797836SJohn.Forte@Sun.COM break; 46807836SJohn.Forte@Sun.COM case STMF_STATE_ONLINING: 46817836SJohn.Forte@Sun.COM state->operationalState = 46827836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINING; 46837836SJohn.Forte@Sun.COM break; 46847836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINING: 46857836SJohn.Forte@Sun.COM state->operationalState = 46867836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINING; 46877836SJohn.Forte@Sun.COM break; 46887836SJohn.Forte@Sun.COM default: 46897836SJohn.Forte@Sun.COM state->operationalState = 46907836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_UNKNOWN; 46917836SJohn.Forte@Sun.COM break; 46927836SJohn.Forte@Sun.COM } 46937836SJohn.Forte@Sun.COM switch (iState.config_state) { 46947836SJohn.Forte@Sun.COM case STMF_CONFIG_NONE: 46957836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_NONE; 46967836SJohn.Forte@Sun.COM break; 46977836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT: 46987836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_INIT; 46997836SJohn.Forte@Sun.COM break; 47007836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT_DONE: 47017836SJohn.Forte@Sun.COM state->configState = 47027836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_INIT_DONE; 47037836SJohn.Forte@Sun.COM break; 47047836SJohn.Forte@Sun.COM default: 47057836SJohn.Forte@Sun.COM state->configState = 47067836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_UNKNOWN; 47077836SJohn.Forte@Sun.COM break; 47087836SJohn.Forte@Sun.COM } 47097836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 47107836SJohn.Forte@Sun.COM } 47117836SJohn.Forte@Sun.COM 47127836SJohn.Forte@Sun.COM /* 47137836SJohn.Forte@Sun.COM * stmfGetViewEntryList 47147836SJohn.Forte@Sun.COM * 47157836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of view entries for the specified 47167836SJohn.Forte@Sun.COM * logical unit. 47177836SJohn.Forte@Sun.COM * 47187836SJohn.Forte@Sun.COM * lu - the guid of the logical unit for which to retrieve the view entry list 47197836SJohn.Forte@Sun.COM * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On 47207836SJohn.Forte@Sun.COM * success, contains the list of view entries. 47217836SJohn.Forte@Sun.COM */ 47227836SJohn.Forte@Sun.COM int 47237836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList) 47247836SJohn.Forte@Sun.COM { 47257836SJohn.Forte@Sun.COM int ret; 47269585STim.Szeto@Sun.COM int fd; 47279585STim.Szeto@Sun.COM int ioctlRet; 47289585STim.Szeto@Sun.COM int cmd = STMF_IOCTL_LU_VE_LIST; 47299585STim.Szeto@Sun.COM int i; 47309585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 47319585STim.Szeto@Sun.COM stmf_view_op_entry_t *fVeList; 47329585STim.Szeto@Sun.COM uint32_t fVeListSize; 47339585STim.Szeto@Sun.COM uint32_t listCnt; 47347836SJohn.Forte@Sun.COM 47357836SJohn.Forte@Sun.COM if (lu == NULL || viewEntryList == NULL) { 47367836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 47377836SJohn.Forte@Sun.COM } 47387836SJohn.Forte@Sun.COM 47399585STim.Szeto@Sun.COM /* call init */ 47409585STim.Szeto@Sun.COM ret = initializeConfig(); 47419585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47429585STim.Szeto@Sun.COM return (ret); 47439585STim.Szeto@Sun.COM } 47449585STim.Szeto@Sun.COM 47459585STim.Szeto@Sun.COM /* 47469585STim.Szeto@Sun.COM * Open control node for stmf 47479585STim.Szeto@Sun.COM */ 47489585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 47499585STim.Szeto@Sun.COM return (ret); 47509585STim.Szeto@Sun.COM 47519585STim.Szeto@Sun.COM /* 47529585STim.Szeto@Sun.COM * Allocate ioctl input buffer 47539585STim.Szeto@Sun.COM */ 47549585STim.Szeto@Sun.COM fVeListSize = ALLOC_VE; 47559585STim.Szeto@Sun.COM fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t)); 47569585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 47579585STim.Szeto@Sun.COM if (fVeList == NULL) { 47589585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 47599585STim.Szeto@Sun.COM goto done; 47609585STim.Szeto@Sun.COM } 47619585STim.Szeto@Sun.COM 47629585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 47639585STim.Szeto@Sun.COM /* 47649585STim.Szeto@Sun.COM * Issue ioctl to get the LU list 47659585STim.Szeto@Sun.COM */ 47669585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 47679585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 47689585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 47699585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 47709585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 47719585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 47729585STim.Szeto@Sun.COM if (ioctlRet != 0) { 47739585STim.Szeto@Sun.COM switch (errno) { 47749585STim.Szeto@Sun.COM case EBUSY: 47759585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 47769585STim.Szeto@Sun.COM break; 47779585STim.Szeto@Sun.COM case EPERM: 47789585STim.Szeto@Sun.COM case EACCES: 47799585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 47809585STim.Szeto@Sun.COM break; 47819585STim.Szeto@Sun.COM default: 47829585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 47839585STim.Szeto@Sun.COM "stmfGetViewEntryList:ioctl errno(%d)", 47849585STim.Szeto@Sun.COM errno); 47859585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 47869585STim.Szeto@Sun.COM break; 47879585STim.Szeto@Sun.COM } 47889585STim.Szeto@Sun.COM goto done; 47899585STim.Szeto@Sun.COM } 47909585STim.Szeto@Sun.COM /* 47919585STim.Szeto@Sun.COM * Check whether input buffer was large enough 47929585STim.Szeto@Sun.COM */ 47939585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) { 47949585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 47959585STim.Szeto@Sun.COM fVeListSize = stmfIoctl.stmf_obuf_max_nentries * 47969585STim.Szeto@Sun.COM sizeof (stmf_view_op_entry_t); 47979585STim.Szeto@Sun.COM free(fVeList); 47989585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 47999585STim.Szeto@Sun.COM if (fVeList == NULL) { 48009585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 48019585STim.Szeto@Sun.COM } 48029585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 48039585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 48049585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 48059585STim.Szeto@Sun.COM if (ioctlRet != 0) { 48069585STim.Szeto@Sun.COM switch (errno) { 48079585STim.Szeto@Sun.COM case EBUSY: 48089585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 48099585STim.Szeto@Sun.COM break; 48109585STim.Szeto@Sun.COM case EPERM: 48119585STim.Szeto@Sun.COM case EACCES: 48129585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 48139585STim.Szeto@Sun.COM break; 48149585STim.Szeto@Sun.COM default: 48159585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 48169585STim.Szeto@Sun.COM "stmfGetLogicalUnitList:" 48179585STim.Szeto@Sun.COM "ioctl errno(%d)", errno); 48189585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 48199585STim.Szeto@Sun.COM break; 48209585STim.Szeto@Sun.COM } 48219585STim.Szeto@Sun.COM goto done; 48229585STim.Szeto@Sun.COM } 48239585STim.Szeto@Sun.COM } 48249585STim.Szeto@Sun.COM 48259585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 48269585STim.Szeto@Sun.COM goto done; 48279585STim.Szeto@Sun.COM } 48289585STim.Szeto@Sun.COM 48299585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_nentries == 0) { 48309585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 48319585STim.Szeto@Sun.COM goto done; 48329585STim.Szeto@Sun.COM } 48339585STim.Szeto@Sun.COM 48349585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 48359585STim.Szeto@Sun.COM 48369585STim.Szeto@Sun.COM /* 48379585STim.Szeto@Sun.COM * allocate caller's buffer with the final size 48389585STim.Szeto@Sun.COM */ 48399585STim.Szeto@Sun.COM *viewEntryList = (stmfViewEntryList *)calloc(1, 48409585STim.Szeto@Sun.COM sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry)); 48419585STim.Szeto@Sun.COM if (*viewEntryList == NULL) { 48429585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 48439585STim.Szeto@Sun.COM goto done; 48449585STim.Szeto@Sun.COM } 48459585STim.Szeto@Sun.COM 48469585STim.Szeto@Sun.COM (*viewEntryList)->cnt = listCnt; 48479585STim.Szeto@Sun.COM 48489585STim.Szeto@Sun.COM /* copy to caller's buffer */ 48499585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 48509585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndexValid = B_TRUE; 48519585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx; 48529585STim.Szeto@Sun.COM if (fVeList[i].ve_all_hosts == 1) { 48539585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allHosts = B_TRUE; 48549585STim.Szeto@Sun.COM } else { 48559585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_host_group.name, 48569585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].hostGroup, 48579585STim.Szeto@Sun.COM fVeList[i].ve_host_group.name_size); 48589585STim.Szeto@Sun.COM } 48599585STim.Szeto@Sun.COM if (fVeList[i].ve_all_targets == 1) { 48609585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allTargets = B_TRUE; 48619585STim.Szeto@Sun.COM } else { 48629585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_target_group.name, 48639585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].targetGroup, 48649585STim.Szeto@Sun.COM fVeList[i].ve_target_group.name_size); 48659585STim.Szeto@Sun.COM } 48669585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr, 48679585STim.Szeto@Sun.COM sizeof ((*viewEntryList)->ve[i].luNbr)); 48689585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].luNbrValid = B_TRUE; 48699585STim.Szeto@Sun.COM } 48709585STim.Szeto@Sun.COM 48719585STim.Szeto@Sun.COM /* 48729585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 48739585STim.Szeto@Sun.COM */ 48749585STim.Szeto@Sun.COM qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt, 48759585STim.Szeto@Sun.COM sizeof (stmfViewEntry), viewEntryCompare); 48769585STim.Szeto@Sun.COM 48779585STim.Szeto@Sun.COM done: 48789585STim.Szeto@Sun.COM (void) close(fd); 48799585STim.Szeto@Sun.COM /* 48809585STim.Szeto@Sun.COM * free internal buffers 48819585STim.Szeto@Sun.COM */ 48829585STim.Szeto@Sun.COM free(fVeList); 48837836SJohn.Forte@Sun.COM return (ret); 48847836SJohn.Forte@Sun.COM } 48857836SJohn.Forte@Sun.COM 48869585STim.Szeto@Sun.COM 48877836SJohn.Forte@Sun.COM /* 48887836SJohn.Forte@Sun.COM * loadHostGroups 48897836SJohn.Forte@Sun.COM * 48907836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the host groups into stmf 48917836SJohn.Forte@Sun.COM * 48927836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 48937836SJohn.Forte@Sun.COM * groupList - populated host group list 48947836SJohn.Forte@Sun.COM */ 48957836SJohn.Forte@Sun.COM static int 48967836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList) 48977836SJohn.Forte@Sun.COM { 48987836SJohn.Forte@Sun.COM int i, j; 48997836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49007836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 49017836SJohn.Forte@Sun.COM 49027836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 49037836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 49047836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 49057836SJohn.Forte@Sun.COM goto out; 49067836SJohn.Forte@Sun.COM } 49079585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 49089585STim.Szeto@Sun.COM &groupProps, HOST_GROUP); 49097836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 49107836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, 49117836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 49127836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 49137836SJohn.Forte@Sun.COM goto out; 49147836SJohn.Forte@Sun.COM } 49157836SJohn.Forte@Sun.COM } 49167836SJohn.Forte@Sun.COM } 49177836SJohn.Forte@Sun.COM 49187836SJohn.Forte@Sun.COM 49197836SJohn.Forte@Sun.COM out: 49207836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 49217836SJohn.Forte@Sun.COM return (ret); 49227836SJohn.Forte@Sun.COM } 49237836SJohn.Forte@Sun.COM 49247836SJohn.Forte@Sun.COM /* 49257836SJohn.Forte@Sun.COM * loadTargetGroups 49267836SJohn.Forte@Sun.COM * 49277836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the target groups into stmf 49287836SJohn.Forte@Sun.COM * 49297836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 49307836SJohn.Forte@Sun.COM * groupList - populated target group list. 49317836SJohn.Forte@Sun.COM */ 49327836SJohn.Forte@Sun.COM static int 49337836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList) 49347836SJohn.Forte@Sun.COM { 49357836SJohn.Forte@Sun.COM int i, j; 49367836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49377836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 49387836SJohn.Forte@Sun.COM 49397836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 49407836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 49417836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 49427836SJohn.Forte@Sun.COM goto out; 49437836SJohn.Forte@Sun.COM } 49449585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 49459585STim.Szeto@Sun.COM &groupProps, TARGET_GROUP); 49467836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 49477836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 49487836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 49497836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 49507836SJohn.Forte@Sun.COM goto out; 49517836SJohn.Forte@Sun.COM } 49527836SJohn.Forte@Sun.COM } 49537836SJohn.Forte@Sun.COM } 49547836SJohn.Forte@Sun.COM 49557836SJohn.Forte@Sun.COM 49567836SJohn.Forte@Sun.COM out: 49577836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 49587836SJohn.Forte@Sun.COM return (ret); 49597836SJohn.Forte@Sun.COM } 49607836SJohn.Forte@Sun.COM 49617836SJohn.Forte@Sun.COM 49627836SJohn.Forte@Sun.COM /* 49637836SJohn.Forte@Sun.COM * loadStore 49647836SJohn.Forte@Sun.COM * 49657836SJohn.Forte@Sun.COM * Purpose: Load the configuration data from the store 49667836SJohn.Forte@Sun.COM * 49677836SJohn.Forte@Sun.COM * First load the host groups and target groups, then the view entries 49687836SJohn.Forte@Sun.COM * and finally the provider data 49697836SJohn.Forte@Sun.COM * 49707836SJohn.Forte@Sun.COM * fd - file descriptor of control node for stmf. 49717836SJohn.Forte@Sun.COM */ 49727836SJohn.Forte@Sun.COM static int 49737836SJohn.Forte@Sun.COM loadStore(int fd) 49747836SJohn.Forte@Sun.COM { 49757836SJohn.Forte@Sun.COM int ret; 49767836SJohn.Forte@Sun.COM int i, j; 49777836SJohn.Forte@Sun.COM stmfGroupList *groupList = NULL; 49787836SJohn.Forte@Sun.COM stmfGuidList *guidList = NULL; 49797836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 49807836SJohn.Forte@Sun.COM stmfProviderList *providerList = NULL; 49817836SJohn.Forte@Sun.COM int providerType; 49827836SJohn.Forte@Sun.COM nvlist_t *nvl = NULL; 49837836SJohn.Forte@Sun.COM 49847836SJohn.Forte@Sun.COM 49857836SJohn.Forte@Sun.COM 49867836SJohn.Forte@Sun.COM /* load host groups */ 49879585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, HOST_GROUP); 49887836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 49897836SJohn.Forte@Sun.COM return (ret); 49907836SJohn.Forte@Sun.COM } 49917836SJohn.Forte@Sun.COM ret = loadHostGroups(fd, groupList); 49927836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 49937836SJohn.Forte@Sun.COM goto out; 49947836SJohn.Forte@Sun.COM } 49957836SJohn.Forte@Sun.COM 49967836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 49977836SJohn.Forte@Sun.COM groupList = NULL; 49987836SJohn.Forte@Sun.COM 49997836SJohn.Forte@Sun.COM /* load target groups */ 50009585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, TARGET_GROUP); 50017836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50027836SJohn.Forte@Sun.COM goto out; 50037836SJohn.Forte@Sun.COM } 50047836SJohn.Forte@Sun.COM ret = loadTargetGroups(fd, groupList); 50057836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50067836SJohn.Forte@Sun.COM goto out; 50077836SJohn.Forte@Sun.COM } 50087836SJohn.Forte@Sun.COM 50097836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 50107836SJohn.Forte@Sun.COM groupList = NULL; 50117836SJohn.Forte@Sun.COM 50127836SJohn.Forte@Sun.COM /* Get the guid list */ 50137836SJohn.Forte@Sun.COM ret = psGetLogicalUnitList(&guidList); 50147836SJohn.Forte@Sun.COM switch (ret) { 50157836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 50167836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 50177836SJohn.Forte@Sun.COM break; 50187836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 50197836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 50207836SJohn.Forte@Sun.COM break; 50217836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 50227836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 50237836SJohn.Forte@Sun.COM break; 50247836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 50257836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 50267836SJohn.Forte@Sun.COM break; 50277836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 50287836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 50297836SJohn.Forte@Sun.COM break; 50307836SJohn.Forte@Sun.COM default: 50317836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 50327836SJohn.Forte@Sun.COM break; 50337836SJohn.Forte@Sun.COM } 50347836SJohn.Forte@Sun.COM 50357836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50367836SJohn.Forte@Sun.COM goto out; 50377836SJohn.Forte@Sun.COM } 50387836SJohn.Forte@Sun.COM 50397836SJohn.Forte@Sun.COM /* 50407836SJohn.Forte@Sun.COM * We have the guid list, now get the corresponding 50417836SJohn.Forte@Sun.COM * view entries for each guid 50427836SJohn.Forte@Sun.COM */ 50437836SJohn.Forte@Sun.COM for (i = 0; i < guidList->cnt; i++) { 50447836SJohn.Forte@Sun.COM ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList); 50457836SJohn.Forte@Sun.COM switch (ret) { 50467836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 50477836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 50487836SJohn.Forte@Sun.COM break; 50497836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 50507836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 50517836SJohn.Forte@Sun.COM break; 50527836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 50537836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 50547836SJohn.Forte@Sun.COM break; 50557836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 50567836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 50577836SJohn.Forte@Sun.COM break; 50587836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 50597836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 50607836SJohn.Forte@Sun.COM break; 50617836SJohn.Forte@Sun.COM default: 50627836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 50637836SJohn.Forte@Sun.COM break; 50647836SJohn.Forte@Sun.COM } 50657836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50667836SJohn.Forte@Sun.COM goto out; 50677836SJohn.Forte@Sun.COM } 50687836SJohn.Forte@Sun.COM for (j = 0; j < viewEntryList->cnt; j++) { 50697836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, &guidList->guid[i], 50707836SJohn.Forte@Sun.COM &viewEntryList->ve[j]); 50717836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50727836SJohn.Forte@Sun.COM goto out; 50737836SJohn.Forte@Sun.COM } 50747836SJohn.Forte@Sun.COM } 50757836SJohn.Forte@Sun.COM } 50767836SJohn.Forte@Sun.COM 50777836SJohn.Forte@Sun.COM /* get the list of providers that have data */ 50787836SJohn.Forte@Sun.COM ret = psGetProviderDataList(&providerList); 50797836SJohn.Forte@Sun.COM switch (ret) { 50807836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 50817836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 50827836SJohn.Forte@Sun.COM break; 50837836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 50847836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 50857836SJohn.Forte@Sun.COM break; 50867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 50877836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 50887836SJohn.Forte@Sun.COM break; 50897836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 50907836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 50917836SJohn.Forte@Sun.COM break; 50927836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 50937836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 50947836SJohn.Forte@Sun.COM break; 50957836SJohn.Forte@Sun.COM default: 50967836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 50977836SJohn.Forte@Sun.COM break; 50987836SJohn.Forte@Sun.COM } 50997836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51007836SJohn.Forte@Sun.COM goto out; 51017836SJohn.Forte@Sun.COM } 51027836SJohn.Forte@Sun.COM 51037836SJohn.Forte@Sun.COM for (i = 0; i < providerList->cnt; i++) { 51047836SJohn.Forte@Sun.COM providerType = providerList->provider[i].providerType; 51057836SJohn.Forte@Sun.COM ret = psGetProviderData(providerList->provider[i].name, 51067836SJohn.Forte@Sun.COM &nvl, providerType, NULL); 51077836SJohn.Forte@Sun.COM switch (ret) { 51087836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51097836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51107836SJohn.Forte@Sun.COM break; 51117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 51127836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 51137836SJohn.Forte@Sun.COM break; 51147836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51157836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51167836SJohn.Forte@Sun.COM break; 51177836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51187836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51197836SJohn.Forte@Sun.COM break; 51207836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51217836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51227836SJohn.Forte@Sun.COM break; 51237836SJohn.Forte@Sun.COM default: 51247836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51257836SJohn.Forte@Sun.COM break; 51267836SJohn.Forte@Sun.COM } 51277836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51287836SJohn.Forte@Sun.COM goto out; 51297836SJohn.Forte@Sun.COM } 51307836SJohn.Forte@Sun.COM 51317836SJohn.Forte@Sun.COM /* call setProviderData */ 51327836SJohn.Forte@Sun.COM ret = setProviderData(fd, providerList->provider[i].name, nvl, 51339585STim.Szeto@Sun.COM providerType, NULL); 51347836SJohn.Forte@Sun.COM switch (ret) { 51357836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51367836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51377836SJohn.Forte@Sun.COM break; 51387836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 51397836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 51407836SJohn.Forte@Sun.COM break; 51417836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51427836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51437836SJohn.Forte@Sun.COM break; 51447836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51457836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51467836SJohn.Forte@Sun.COM break; 51477836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51487836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51497836SJohn.Forte@Sun.COM break; 51507836SJohn.Forte@Sun.COM default: 51517836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51527836SJohn.Forte@Sun.COM break; 51537836SJohn.Forte@Sun.COM } 51547836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51557836SJohn.Forte@Sun.COM goto out; 51567836SJohn.Forte@Sun.COM } 51577836SJohn.Forte@Sun.COM 51587836SJohn.Forte@Sun.COM nvlist_free(nvl); 51597836SJohn.Forte@Sun.COM nvl = NULL; 51607836SJohn.Forte@Sun.COM } 51617836SJohn.Forte@Sun.COM out: 51627836SJohn.Forte@Sun.COM if (groupList != NULL) { 51637836SJohn.Forte@Sun.COM free(groupList); 51647836SJohn.Forte@Sun.COM } 51657836SJohn.Forte@Sun.COM if (guidList != NULL) { 51667836SJohn.Forte@Sun.COM free(guidList); 51677836SJohn.Forte@Sun.COM } 51687836SJohn.Forte@Sun.COM if (viewEntryList != NULL) { 51697836SJohn.Forte@Sun.COM free(viewEntryList); 51707836SJohn.Forte@Sun.COM } 51717836SJohn.Forte@Sun.COM if (nvl != NULL) { 51727836SJohn.Forte@Sun.COM nvlist_free(nvl); 51737836SJohn.Forte@Sun.COM } 51747836SJohn.Forte@Sun.COM return (ret); 51757836SJohn.Forte@Sun.COM } 51767836SJohn.Forte@Sun.COM 51777836SJohn.Forte@Sun.COM /* 517810725SJohn.Forte@Sun.COM * stmfGetAluaState 517910725SJohn.Forte@Sun.COM * 518010725SJohn.Forte@Sun.COM * Purpose - Get the alua state 518110725SJohn.Forte@Sun.COM * 518210725SJohn.Forte@Sun.COM */ 518310725SJohn.Forte@Sun.COM int 518410725SJohn.Forte@Sun.COM stmfGetAluaState(boolean_t *enabled, uint32_t *node) 518510725SJohn.Forte@Sun.COM { 518610725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 518710725SJohn.Forte@Sun.COM int fd; 518810725SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl = {0}; 518910725SJohn.Forte@Sun.COM stmf_alua_state_desc_t alua_state = {0}; 519010725SJohn.Forte@Sun.COM int ioctlRet; 519110725SJohn.Forte@Sun.COM 519210725SJohn.Forte@Sun.COM if (enabled == NULL || node == NULL) { 519310725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 519410725SJohn.Forte@Sun.COM } 519510725SJohn.Forte@Sun.COM 519610725SJohn.Forte@Sun.COM /* 519710725SJohn.Forte@Sun.COM * Open control node for stmf 519810725SJohn.Forte@Sun.COM */ 519910725SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 520010725SJohn.Forte@Sun.COM return (ret); 520110725SJohn.Forte@Sun.COM 520210725SJohn.Forte@Sun.COM /* 520310725SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 520410725SJohn.Forte@Sun.COM */ 520510725SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 520610725SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (alua_state); 520710725SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state; 520810725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl); 520910725SJohn.Forte@Sun.COM 521010725SJohn.Forte@Sun.COM (void) close(fd); 521110725SJohn.Forte@Sun.COM 521210725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 521310725SJohn.Forte@Sun.COM switch (errno) { 521410725SJohn.Forte@Sun.COM case EBUSY: 521510725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 521610725SJohn.Forte@Sun.COM break; 521710725SJohn.Forte@Sun.COM case EPERM: 521810725SJohn.Forte@Sun.COM case EACCES: 521910725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 522010725SJohn.Forte@Sun.COM break; 522110725SJohn.Forte@Sun.COM default: 522210725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 522310725SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 522410725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 522510725SJohn.Forte@Sun.COM break; 522610725SJohn.Forte@Sun.COM } 522710725SJohn.Forte@Sun.COM } else { 522810725SJohn.Forte@Sun.COM if (alua_state.alua_state == 1) { 522910725SJohn.Forte@Sun.COM *enabled = B_TRUE; 523010725SJohn.Forte@Sun.COM } else { 523110725SJohn.Forte@Sun.COM *enabled = B_FALSE; 523210725SJohn.Forte@Sun.COM } 523310725SJohn.Forte@Sun.COM *node = alua_state.alua_node; 523410725SJohn.Forte@Sun.COM } 523510725SJohn.Forte@Sun.COM 523610725SJohn.Forte@Sun.COM return (ret); 523710725SJohn.Forte@Sun.COM } 523810725SJohn.Forte@Sun.COM 523910725SJohn.Forte@Sun.COM /* 524010725SJohn.Forte@Sun.COM * stmfSetAluaState 524110725SJohn.Forte@Sun.COM * 524210725SJohn.Forte@Sun.COM * Purpose - set the alua state to enabled/disabled 524310725SJohn.Forte@Sun.COM * 524410725SJohn.Forte@Sun.COM */ 524510725SJohn.Forte@Sun.COM int 524610725SJohn.Forte@Sun.COM stmfSetAluaState(boolean_t enabled, uint32_t node) 524710725SJohn.Forte@Sun.COM { 524810725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 524910725SJohn.Forte@Sun.COM int fd; 525010725SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl = {0}; 525110725SJohn.Forte@Sun.COM stmf_alua_state_desc_t alua_state = {0}; 525210725SJohn.Forte@Sun.COM int ioctlRet; 525310725SJohn.Forte@Sun.COM 525410725SJohn.Forte@Sun.COM if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) { 525510725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 525610725SJohn.Forte@Sun.COM } 525710725SJohn.Forte@Sun.COM 525810725SJohn.Forte@Sun.COM if (enabled) { 525910725SJohn.Forte@Sun.COM alua_state.alua_state = 1; 526010725SJohn.Forte@Sun.COM } 526110725SJohn.Forte@Sun.COM 526210725SJohn.Forte@Sun.COM alua_state.alua_node = node; 526310725SJohn.Forte@Sun.COM 526410725SJohn.Forte@Sun.COM /* 526510725SJohn.Forte@Sun.COM * Open control node for stmf 526610725SJohn.Forte@Sun.COM */ 526710725SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 526810725SJohn.Forte@Sun.COM return (ret); 526910725SJohn.Forte@Sun.COM 527010725SJohn.Forte@Sun.COM /* 527110725SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 527210725SJohn.Forte@Sun.COM */ 527310725SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 527410725SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (alua_state); 527510725SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state; 527610725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl); 527710725SJohn.Forte@Sun.COM 527810725SJohn.Forte@Sun.COM (void) close(fd); 527910725SJohn.Forte@Sun.COM 528010725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 528110725SJohn.Forte@Sun.COM switch (errno) { 528210725SJohn.Forte@Sun.COM case EBUSY: 528310725SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 528410725SJohn.Forte@Sun.COM break; 528510725SJohn.Forte@Sun.COM case EPERM: 528610725SJohn.Forte@Sun.COM case EACCES: 528710725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 528810725SJohn.Forte@Sun.COM break; 528910725SJohn.Forte@Sun.COM default: 529010725SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 529110725SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 529210725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 529310725SJohn.Forte@Sun.COM break; 529410725SJohn.Forte@Sun.COM } 529510725SJohn.Forte@Sun.COM } 5296*11116SJohn.Forte@Sun.COM if (!enabled && ret == STMF_STATUS_SUCCESS) { 529710725SJohn.Forte@Sun.COM deleteNonActiveLus(); 529810725SJohn.Forte@Sun.COM } 529910725SJohn.Forte@Sun.COM 530010725SJohn.Forte@Sun.COM return (ret); 530110725SJohn.Forte@Sun.COM } 530210725SJohn.Forte@Sun.COM 530310725SJohn.Forte@Sun.COM static void 530410725SJohn.Forte@Sun.COM deleteNonActiveLus() 530510725SJohn.Forte@Sun.COM { 530610725SJohn.Forte@Sun.COM int stmfRet; 530710725SJohn.Forte@Sun.COM int i; 530810725SJohn.Forte@Sun.COM stmfGuidList *luList; 530910725SJohn.Forte@Sun.COM luResource hdl = NULL; 531010725SJohn.Forte@Sun.COM char propVal[10]; 531110725SJohn.Forte@Sun.COM size_t propValSize = sizeof (propVal); 531210725SJohn.Forte@Sun.COM 531310725SJohn.Forte@Sun.COM stmfRet = stmfGetLogicalUnitList(&luList); 531410725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 531510725SJohn.Forte@Sun.COM return; 531610725SJohn.Forte@Sun.COM } 531710725SJohn.Forte@Sun.COM 531810725SJohn.Forte@Sun.COM for (i = 0; i < luList->cnt; i++) { 531910725SJohn.Forte@Sun.COM stmfRet = stmfGetLuResource(&luList->guid[i], &hdl); 532010725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 532110725SJohn.Forte@Sun.COM goto err; 532210725SJohn.Forte@Sun.COM } 532310725SJohn.Forte@Sun.COM stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal, 532410725SJohn.Forte@Sun.COM &propValSize); 532510725SJohn.Forte@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 532610725SJohn.Forte@Sun.COM goto err; 532710725SJohn.Forte@Sun.COM } 532810725SJohn.Forte@Sun.COM if (propVal[0] == '0') { 532910725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 533010725SJohn.Forte@Sun.COM hdl = NULL; 533110725SJohn.Forte@Sun.COM continue; 533210725SJohn.Forte@Sun.COM } 533310725SJohn.Forte@Sun.COM (void) stmfDeleteLu(&luList->guid[i]); 533410725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 533510725SJohn.Forte@Sun.COM hdl = NULL; 533610725SJohn.Forte@Sun.COM } 533710725SJohn.Forte@Sun.COM 533810725SJohn.Forte@Sun.COM err: 533910725SJohn.Forte@Sun.COM stmfFreeMemory(luList); 534010725SJohn.Forte@Sun.COM (void) stmfFreeLuResource(hdl); 534110725SJohn.Forte@Sun.COM } 534210725SJohn.Forte@Sun.COM 534310725SJohn.Forte@Sun.COM /* 53447836SJohn.Forte@Sun.COM * stmfLoadConfig 53457836SJohn.Forte@Sun.COM * 53467836SJohn.Forte@Sun.COM * Purpose - load the configuration data from smf into stmf 53477836SJohn.Forte@Sun.COM * 53487836SJohn.Forte@Sun.COM */ 53497836SJohn.Forte@Sun.COM int 53507836SJohn.Forte@Sun.COM stmfLoadConfig(void) 53517836SJohn.Forte@Sun.COM { 53529585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 53537836SJohn.Forte@Sun.COM int fd; 53547836SJohn.Forte@Sun.COM stmf_state_desc_t stmfStateSet; 53557836SJohn.Forte@Sun.COM stmfState state; 53567836SJohn.Forte@Sun.COM 53579585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 53589585STim.Szeto@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 535910560SSusan.Gleeson@Sun.COM 53609585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) 53619585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 53629585STim.Szeto@Sun.COM return (ret); 53639585STim.Szeto@Sun.COM } 536410560SSusan.Gleeson@Sun.COM /* 536510560SSusan.Gleeson@Sun.COM * Configuration not stored persistently; nothing to 536610560SSusan.Gleeson@Sun.COM * initialize so do not set to STMF_CONFIG_INIT. 536710560SSusan.Gleeson@Sun.COM */ 53689585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 53699585STim.Szeto@Sun.COM goto done; 53709585STim.Szeto@Sun.COM } 53717836SJohn.Forte@Sun.COM 53727836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 53737836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 53747836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 53757836SJohn.Forte@Sun.COM } 53767836SJohn.Forte@Sun.COM 53777836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 53787836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 53797836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 53807836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 53817836SJohn.Forte@Sun.COM } 53827836SJohn.Forte@Sun.COM } else { 53837836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 53847836SJohn.Forte@Sun.COM } 53857836SJohn.Forte@Sun.COM 53867836SJohn.Forte@Sun.COM 53877836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 53887836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 53897836SJohn.Forte@Sun.COM 53907836SJohn.Forte@Sun.COM /* 53917836SJohn.Forte@Sun.COM * Open control node for stmf 53927836SJohn.Forte@Sun.COM */ 53937836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 53947836SJohn.Forte@Sun.COM return (ret); 53957836SJohn.Forte@Sun.COM 53967836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 53977836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 53987836SJohn.Forte@Sun.COM goto done; 53997836SJohn.Forte@Sun.COM } 54007836SJohn.Forte@Sun.COM 54017836SJohn.Forte@Sun.COM /* Load the persistent configuration data */ 54027836SJohn.Forte@Sun.COM ret = loadStore(fd); 54037836SJohn.Forte@Sun.COM if (ret != 0) { 54047836SJohn.Forte@Sun.COM goto done; 54057836SJohn.Forte@Sun.COM } 54067836SJohn.Forte@Sun.COM 54077836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 54087836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 54097836SJohn.Forte@Sun.COM 54107836SJohn.Forte@Sun.COM done: 54117836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 54127836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 54137836SJohn.Forte@Sun.COM } 54147836SJohn.Forte@Sun.COM (void) close(fd); 54157836SJohn.Forte@Sun.COM return (ret); 54167836SJohn.Forte@Sun.COM } 54177836SJohn.Forte@Sun.COM 54189585STim.Szeto@Sun.COM 54197836SJohn.Forte@Sun.COM /* 54207836SJohn.Forte@Sun.COM * getStmfState 54217836SJohn.Forte@Sun.COM * 54227836SJohn.Forte@Sun.COM * stmfState - pointer to stmf_state_desc_t structure. Will contain the state 54237836SJohn.Forte@Sun.COM * information of the stmf service on success. 54247836SJohn.Forte@Sun.COM */ 54257836SJohn.Forte@Sun.COM static int 54267836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState) 54277836SJohn.Forte@Sun.COM { 54287836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 54297836SJohn.Forte@Sun.COM int fd; 54307836SJohn.Forte@Sun.COM int ioctlRet; 54317836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 54327836SJohn.Forte@Sun.COM 54337836SJohn.Forte@Sun.COM /* 54347836SJohn.Forte@Sun.COM * Open control node for stmf 54357836SJohn.Forte@Sun.COM */ 54367836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 54377836SJohn.Forte@Sun.COM return (ret); 54387836SJohn.Forte@Sun.COM 54397836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 54407836SJohn.Forte@Sun.COM /* 54417836SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 54427836SJohn.Forte@Sun.COM */ 54437836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 54447836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 54457836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 54467836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t); 54477836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState; 54487836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl); 54497836SJohn.Forte@Sun.COM 54507836SJohn.Forte@Sun.COM (void) close(fd); 54517836SJohn.Forte@Sun.COM 54527836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 54537836SJohn.Forte@Sun.COM switch (errno) { 54547836SJohn.Forte@Sun.COM case EBUSY: 54557836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 54567836SJohn.Forte@Sun.COM break; 54577836SJohn.Forte@Sun.COM case EPERM: 54587836SJohn.Forte@Sun.COM case EACCES: 54597836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 54607836SJohn.Forte@Sun.COM break; 54617836SJohn.Forte@Sun.COM default: 54627836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 54637836SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 54647836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 54657836SJohn.Forte@Sun.COM break; 54667836SJohn.Forte@Sun.COM } 54677836SJohn.Forte@Sun.COM } 54687836SJohn.Forte@Sun.COM return (ret); 54697836SJohn.Forte@Sun.COM } 54707836SJohn.Forte@Sun.COM 54717836SJohn.Forte@Sun.COM 54727836SJohn.Forte@Sun.COM /* 54737836SJohn.Forte@Sun.COM * setStmfState 54747836SJohn.Forte@Sun.COM * 54757836SJohn.Forte@Sun.COM * stmfState - pointer to caller set state structure 54767836SJohn.Forte@Sun.COM * objectType - one of: 54777836SJohn.Forte@Sun.COM * LOGICAL_UNIT_TYPE 54787836SJohn.Forte@Sun.COM * TARGET_TYPE 54797836SJohn.Forte@Sun.COM * STMF_SERVICE_TYPE 54807836SJohn.Forte@Sun.COM */ 54817836SJohn.Forte@Sun.COM static int 54827836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType) 54837836SJohn.Forte@Sun.COM { 54847836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 54857836SJohn.Forte@Sun.COM int ioctlRet; 54867836SJohn.Forte@Sun.COM int cmd; 54877836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 54887836SJohn.Forte@Sun.COM 54897836SJohn.Forte@Sun.COM switch (objectType) { 54907836SJohn.Forte@Sun.COM case LOGICAL_UNIT_TYPE: 54917836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_LU_STATE; 54927836SJohn.Forte@Sun.COM break; 54937836SJohn.Forte@Sun.COM case TARGET_TYPE: 54947836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_TARGET_PORT_STATE; 54957836SJohn.Forte@Sun.COM break; 54967836SJohn.Forte@Sun.COM case STMF_SERVICE_TYPE: 54977836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_STMF_STATE; 54987836SJohn.Forte@Sun.COM break; 54997836SJohn.Forte@Sun.COM default: 55007836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 55017836SJohn.Forte@Sun.COM goto done; 55027836SJohn.Forte@Sun.COM } 55037836SJohn.Forte@Sun.COM 55047836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 55057836SJohn.Forte@Sun.COM /* 55067836SJohn.Forte@Sun.COM * Issue ioctl to set the stmf state 55077836SJohn.Forte@Sun.COM */ 55087836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 55097836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 55107836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 55117836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 55127836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 55137836SJohn.Forte@Sun.COM switch (errno) { 55147836SJohn.Forte@Sun.COM case EBUSY: 55157836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 55167836SJohn.Forte@Sun.COM break; 55179585STim.Szeto@Sun.COM case EPERM: 55187836SJohn.Forte@Sun.COM case EACCES: 55197836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 55207836SJohn.Forte@Sun.COM break; 55217836SJohn.Forte@Sun.COM case ENOENT: 55227836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 55237836SJohn.Forte@Sun.COM break; 55247836SJohn.Forte@Sun.COM default: 55257836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 55267836SJohn.Forte@Sun.COM "setStmfState:ioctl errno(%d)", errno); 55277836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 55287836SJohn.Forte@Sun.COM break; 55297836SJohn.Forte@Sun.COM } 55307836SJohn.Forte@Sun.COM } 55317836SJohn.Forte@Sun.COM done: 55327836SJohn.Forte@Sun.COM return (ret); 55337836SJohn.Forte@Sun.COM } 55347836SJohn.Forte@Sun.COM 55357836SJohn.Forte@Sun.COM /* 55367836SJohn.Forte@Sun.COM * stmfOnline 55377836SJohn.Forte@Sun.COM * 55387836SJohn.Forte@Sun.COM * Purpose: Online stmf service 55397836SJohn.Forte@Sun.COM * 55407836SJohn.Forte@Sun.COM */ 55417836SJohn.Forte@Sun.COM int 55427836SJohn.Forte@Sun.COM stmfOnline(void) 55437836SJohn.Forte@Sun.COM { 55447836SJohn.Forte@Sun.COM int ret; 55457836SJohn.Forte@Sun.COM int fd; 55467836SJohn.Forte@Sun.COM stmfState state; 55477836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 55487836SJohn.Forte@Sun.COM 55497836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 55507836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 55517836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 55527836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 55537836SJohn.Forte@Sun.COM } 55547836SJohn.Forte@Sun.COM } else { 55557836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 55567836SJohn.Forte@Sun.COM } 55577836SJohn.Forte@Sun.COM iState.state = STMF_STATE_ONLINE; 55587836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 55597836SJohn.Forte@Sun.COM /* 55607836SJohn.Forte@Sun.COM * Open control node for stmf 55617836SJohn.Forte@Sun.COM * to make call to setStmfState() 55627836SJohn.Forte@Sun.COM */ 55637836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 55647836SJohn.Forte@Sun.COM return (ret); 55657836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 55667836SJohn.Forte@Sun.COM (void) close(fd); 55677836SJohn.Forte@Sun.COM return (ret); 55687836SJohn.Forte@Sun.COM } 55697836SJohn.Forte@Sun.COM 55707836SJohn.Forte@Sun.COM /* 55717836SJohn.Forte@Sun.COM * stmfOffline 55727836SJohn.Forte@Sun.COM * 55737836SJohn.Forte@Sun.COM * Purpose: Offline stmf service 55747836SJohn.Forte@Sun.COM * 55757836SJohn.Forte@Sun.COM */ 55767836SJohn.Forte@Sun.COM int 55777836SJohn.Forte@Sun.COM stmfOffline(void) 55787836SJohn.Forte@Sun.COM { 55797836SJohn.Forte@Sun.COM int ret; 55807836SJohn.Forte@Sun.COM int fd; 55817836SJohn.Forte@Sun.COM stmfState state; 55827836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 55837836SJohn.Forte@Sun.COM 55847836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 55857836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 55867836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 55877836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_OFFLINE); 55887836SJohn.Forte@Sun.COM } 55897836SJohn.Forte@Sun.COM } else { 55907836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 55917836SJohn.Forte@Sun.COM } 55927836SJohn.Forte@Sun.COM iState.state = STMF_STATE_OFFLINE; 55937836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 55947836SJohn.Forte@Sun.COM 55957836SJohn.Forte@Sun.COM /* 55967836SJohn.Forte@Sun.COM * Open control node for stmf 55977836SJohn.Forte@Sun.COM * to make call to setStmfState() 55987836SJohn.Forte@Sun.COM */ 55997836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 56007836SJohn.Forte@Sun.COM return (ret); 56017836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 56027836SJohn.Forte@Sun.COM (void) close(fd); 56037836SJohn.Forte@Sun.COM return (ret); 56047836SJohn.Forte@Sun.COM } 56057836SJohn.Forte@Sun.COM 56067836SJohn.Forte@Sun.COM 56077836SJohn.Forte@Sun.COM /* 56087836SJohn.Forte@Sun.COM * stmfOfflineTarget 56097836SJohn.Forte@Sun.COM * 56107836SJohn.Forte@Sun.COM * Purpose: Change state of target to offline 56117836SJohn.Forte@Sun.COM * 56127836SJohn.Forte@Sun.COM * devid - devid of the target to offline 56137836SJohn.Forte@Sun.COM */ 56147836SJohn.Forte@Sun.COM int 56157836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid) 56167836SJohn.Forte@Sun.COM { 56177836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 56187836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56197836SJohn.Forte@Sun.COM int fd; 56207836SJohn.Forte@Sun.COM 56217836SJohn.Forte@Sun.COM if (devid == NULL) { 56227836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56237836SJohn.Forte@Sun.COM } 56247836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 56257836SJohn.Forte@Sun.COM 56267836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_OFFLINE; 56277836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 56287836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 56297836SJohn.Forte@Sun.COM devid->identLength); 56307836SJohn.Forte@Sun.COM /* 56317836SJohn.Forte@Sun.COM * Open control node for stmf 56327836SJohn.Forte@Sun.COM * to make call to setStmfState() 56337836SJohn.Forte@Sun.COM */ 56347836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 56357836SJohn.Forte@Sun.COM return (ret); 56367836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 56377836SJohn.Forte@Sun.COM (void) close(fd); 56387836SJohn.Forte@Sun.COM return (ret); 56397836SJohn.Forte@Sun.COM } 56407836SJohn.Forte@Sun.COM 56417836SJohn.Forte@Sun.COM /* 56427836SJohn.Forte@Sun.COM * stmfOfflineLogicalUnit 56437836SJohn.Forte@Sun.COM * 56447836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to offline 56457836SJohn.Forte@Sun.COM * 56467836SJohn.Forte@Sun.COM * lu - guid of the logical unit to offline 56477836SJohn.Forte@Sun.COM */ 56487836SJohn.Forte@Sun.COM int 56497836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu) 56507836SJohn.Forte@Sun.COM { 56517836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 56527836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56537836SJohn.Forte@Sun.COM int fd; 56547836SJohn.Forte@Sun.COM 56557836SJohn.Forte@Sun.COM if (lu == NULL) { 56567836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56577836SJohn.Forte@Sun.COM } 56587836SJohn.Forte@Sun.COM 56597836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 56607836SJohn.Forte@Sun.COM 56617836SJohn.Forte@Sun.COM luState.state = STMF_STATE_OFFLINE; 56627836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 56637836SJohn.Forte@Sun.COM /* 56647836SJohn.Forte@Sun.COM * Open control node for stmf 56657836SJohn.Forte@Sun.COM * to make call to setStmfState() 56667836SJohn.Forte@Sun.COM */ 56677836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 56687836SJohn.Forte@Sun.COM return (ret); 56697836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 56707836SJohn.Forte@Sun.COM (void) close(fd); 56717836SJohn.Forte@Sun.COM return (ret); 56727836SJohn.Forte@Sun.COM } 56737836SJohn.Forte@Sun.COM 56747836SJohn.Forte@Sun.COM /* 56757836SJohn.Forte@Sun.COM * stmfOnlineTarget 56767836SJohn.Forte@Sun.COM * 56777836SJohn.Forte@Sun.COM * Purpose: Change state of target to online 56787836SJohn.Forte@Sun.COM * 56797836SJohn.Forte@Sun.COM * devid - devid of the target to online 56807836SJohn.Forte@Sun.COM */ 56817836SJohn.Forte@Sun.COM int 56827836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid) 56837836SJohn.Forte@Sun.COM { 56847836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 56857836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56867836SJohn.Forte@Sun.COM int fd; 56877836SJohn.Forte@Sun.COM 56887836SJohn.Forte@Sun.COM if (devid == NULL) { 56897836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56907836SJohn.Forte@Sun.COM } 56917836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 56927836SJohn.Forte@Sun.COM 56937836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_ONLINE; 56947836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 56957836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 56967836SJohn.Forte@Sun.COM devid->identLength); 56977836SJohn.Forte@Sun.COM /* 56987836SJohn.Forte@Sun.COM * Open control node for stmf 56997836SJohn.Forte@Sun.COM * to make call to setStmfState() 57007836SJohn.Forte@Sun.COM */ 57017836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 57027836SJohn.Forte@Sun.COM return (ret); 57037836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 57047836SJohn.Forte@Sun.COM (void) close(fd); 57057836SJohn.Forte@Sun.COM return (ret); 57067836SJohn.Forte@Sun.COM } 57077836SJohn.Forte@Sun.COM 57087836SJohn.Forte@Sun.COM /* 57097836SJohn.Forte@Sun.COM * stmfOnlineLogicalUnit 57107836SJohn.Forte@Sun.COM * 57117836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to online 57127836SJohn.Forte@Sun.COM * 57137836SJohn.Forte@Sun.COM * lu - guid of the logical unit to online 57147836SJohn.Forte@Sun.COM */ 57157836SJohn.Forte@Sun.COM int 57167836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu) 57177836SJohn.Forte@Sun.COM { 57187836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 57197836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 57207836SJohn.Forte@Sun.COM int fd; 57217836SJohn.Forte@Sun.COM 57227836SJohn.Forte@Sun.COM if (lu == NULL) { 57237836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 57247836SJohn.Forte@Sun.COM } 57257836SJohn.Forte@Sun.COM 57267836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 57277836SJohn.Forte@Sun.COM 57287836SJohn.Forte@Sun.COM luState.state = STMF_STATE_ONLINE; 57297836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 57307836SJohn.Forte@Sun.COM /* 57317836SJohn.Forte@Sun.COM * Open control node for stmf 57327836SJohn.Forte@Sun.COM * to make call to setStmfState() 57337836SJohn.Forte@Sun.COM */ 57347836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 57357836SJohn.Forte@Sun.COM return (ret); 57367836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 57377836SJohn.Forte@Sun.COM (void) close(fd); 57387836SJohn.Forte@Sun.COM return (ret); 57397836SJohn.Forte@Sun.COM } 57407836SJohn.Forte@Sun.COM 57417836SJohn.Forte@Sun.COM /* 57427836SJohn.Forte@Sun.COM * stmfRemoveFromHostGroup 57437836SJohn.Forte@Sun.COM * 57447836SJohn.Forte@Sun.COM * Purpose: Removes an initiator from an initiator group 57457836SJohn.Forte@Sun.COM * 57467836SJohn.Forte@Sun.COM * hostGroupName - name of an initiator group 57477836SJohn.Forte@Sun.COM * hostName - name of host group member to remove 57487836SJohn.Forte@Sun.COM */ 57497836SJohn.Forte@Sun.COM int 57507836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 57517836SJohn.Forte@Sun.COM { 57527836SJohn.Forte@Sun.COM int ret; 57537836SJohn.Forte@Sun.COM int fd; 57547836SJohn.Forte@Sun.COM 57557836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 57567836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 57577836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 57587836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 57597836SJohn.Forte@Sun.COM } 57607836SJohn.Forte@Sun.COM 57617836SJohn.Forte@Sun.COM /* call init */ 57627836SJohn.Forte@Sun.COM ret = initializeConfig(); 57637836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 57647836SJohn.Forte@Sun.COM return (ret); 57657836SJohn.Forte@Sun.COM } 57667836SJohn.Forte@Sun.COM 57677836SJohn.Forte@Sun.COM /* 57687836SJohn.Forte@Sun.COM * Open control node for stmf 57697836SJohn.Forte@Sun.COM */ 57707836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 57717836SJohn.Forte@Sun.COM return (ret); 57727836SJohn.Forte@Sun.COM 57737836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY, 57747836SJohn.Forte@Sun.COM hostGroupName, hostName)) != STMF_STATUS_SUCCESS) { 57757836SJohn.Forte@Sun.COM goto done; 57767836SJohn.Forte@Sun.COM } 57777836SJohn.Forte@Sun.COM 57789585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 57799585STim.Szeto@Sun.COM goto done; 57809585STim.Szeto@Sun.COM } 57819585STim.Szeto@Sun.COM 57827836SJohn.Forte@Sun.COM ret = psRemoveHostGroupMember((char *)hostGroupName, 57837836SJohn.Forte@Sun.COM (char *)hostName->ident); 57847836SJohn.Forte@Sun.COM switch (ret) { 57857836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 57867836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 57877836SJohn.Forte@Sun.COM break; 57887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 57897836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 57907836SJohn.Forte@Sun.COM break; 57917836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 57927836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 57937836SJohn.Forte@Sun.COM break; 57947836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 57957836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 57967836SJohn.Forte@Sun.COM break; 57977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 57987836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 57997836SJohn.Forte@Sun.COM break; 58007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 58017836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 58027836SJohn.Forte@Sun.COM break; 58037836SJohn.Forte@Sun.COM default: 58047836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 58057836SJohn.Forte@Sun.COM "stmfRemoveFromHostGroup" 58067836SJohn.Forte@Sun.COM "psRemoveHostGroupMember:error(%d)", ret); 58077836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 58087836SJohn.Forte@Sun.COM break; 58097836SJohn.Forte@Sun.COM } 58107836SJohn.Forte@Sun.COM 58117836SJohn.Forte@Sun.COM done: 58127836SJohn.Forte@Sun.COM (void) close(fd); 58137836SJohn.Forte@Sun.COM return (ret); 58147836SJohn.Forte@Sun.COM } 58157836SJohn.Forte@Sun.COM 58167836SJohn.Forte@Sun.COM /* 58177836SJohn.Forte@Sun.COM * stmfRemoveFromTargetGroup 58187836SJohn.Forte@Sun.COM * 58197836SJohn.Forte@Sun.COM * Purpose: Removes a local port from a local port group 58207836SJohn.Forte@Sun.COM * 58217836SJohn.Forte@Sun.COM * targetGroupName - name of a target group 58227836SJohn.Forte@Sun.COM * targetName - name of target to remove 58237836SJohn.Forte@Sun.COM */ 58247836SJohn.Forte@Sun.COM int 58257836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 58267836SJohn.Forte@Sun.COM { 58277836SJohn.Forte@Sun.COM int ret; 58287836SJohn.Forte@Sun.COM int fd; 58297836SJohn.Forte@Sun.COM 58307836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 58317836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 58327836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 58337836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 58347836SJohn.Forte@Sun.COM } 58357836SJohn.Forte@Sun.COM 58367836SJohn.Forte@Sun.COM /* call init */ 58377836SJohn.Forte@Sun.COM ret = initializeConfig(); 58387836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 58397836SJohn.Forte@Sun.COM return (ret); 58407836SJohn.Forte@Sun.COM } 58417836SJohn.Forte@Sun.COM 58427836SJohn.Forte@Sun.COM /* 58437836SJohn.Forte@Sun.COM * Open control node for stmf 58447836SJohn.Forte@Sun.COM */ 58457836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 58467836SJohn.Forte@Sun.COM return (ret); 58477836SJohn.Forte@Sun.COM 58487836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY, 58497836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 58507836SJohn.Forte@Sun.COM goto done; 58517836SJohn.Forte@Sun.COM } 58527836SJohn.Forte@Sun.COM 58539585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 58549585STim.Szeto@Sun.COM goto done; 58559585STim.Szeto@Sun.COM } 58569585STim.Szeto@Sun.COM 58577836SJohn.Forte@Sun.COM ret = psRemoveTargetGroupMember((char *)targetGroupName, 58587836SJohn.Forte@Sun.COM (char *)targetName->ident); 58597836SJohn.Forte@Sun.COM switch (ret) { 58607836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 58617836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 58627836SJohn.Forte@Sun.COM break; 58637836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 58647836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 58657836SJohn.Forte@Sun.COM break; 58667836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 58677836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 58687836SJohn.Forte@Sun.COM break; 58697836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 58707836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 58717836SJohn.Forte@Sun.COM break; 58727836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 58737836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 58747836SJohn.Forte@Sun.COM break; 58757836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 58767836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 58777836SJohn.Forte@Sun.COM break; 58787836SJohn.Forte@Sun.COM default: 58797836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 58807836SJohn.Forte@Sun.COM "stmfRemoveFromTargetGroup" 58817836SJohn.Forte@Sun.COM "psRemoveTargetGroupMember:error(%d)", ret); 58827836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 58837836SJohn.Forte@Sun.COM break; 58847836SJohn.Forte@Sun.COM } 58857836SJohn.Forte@Sun.COM 58867836SJohn.Forte@Sun.COM done: 58877836SJohn.Forte@Sun.COM (void) close(fd); 58887836SJohn.Forte@Sun.COM return (ret); 58897836SJohn.Forte@Sun.COM } 58907836SJohn.Forte@Sun.COM 58917836SJohn.Forte@Sun.COM /* 58927836SJohn.Forte@Sun.COM * stmfRemoveViewEntry 58937836SJohn.Forte@Sun.COM * 58947836SJohn.Forte@Sun.COM * Purpose: Removes a view entry from a logical unit 58957836SJohn.Forte@Sun.COM * 58967836SJohn.Forte@Sun.COM * lu - guid of lu for which view entry is being removed 58977836SJohn.Forte@Sun.COM * viewEntryIndex - index of view entry to remove 58987836SJohn.Forte@Sun.COM * 58997836SJohn.Forte@Sun.COM */ 59007836SJohn.Forte@Sun.COM int 59017836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex) 59027836SJohn.Forte@Sun.COM { 59037836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 59047836SJohn.Forte@Sun.COM int fd; 59057836SJohn.Forte@Sun.COM int ioctlRet; 59067836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 59077836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 59087836SJohn.Forte@Sun.COM 59097836SJohn.Forte@Sun.COM if (lu == NULL) { 59107836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 59117836SJohn.Forte@Sun.COM } 59127836SJohn.Forte@Sun.COM 59137836SJohn.Forte@Sun.COM /* call init */ 59147836SJohn.Forte@Sun.COM ret = initializeConfig(); 59157836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 59167836SJohn.Forte@Sun.COM return (ret); 59177836SJohn.Forte@Sun.COM } 59187836SJohn.Forte@Sun.COM 59197836SJohn.Forte@Sun.COM /* 59207836SJohn.Forte@Sun.COM * Open control node for stmf 59217836SJohn.Forte@Sun.COM */ 59227836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 59237836SJohn.Forte@Sun.COM return (ret); 59247836SJohn.Forte@Sun.COM 59257836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 59267836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx_valid = B_TRUE; 59277836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx = viewEntryIndex; 59287836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 59297836SJohn.Forte@Sun.COM 59307836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 59317836SJohn.Forte@Sun.COM /* 59327836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 59337836SJohn.Forte@Sun.COM */ 59347836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 59357836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 59367836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 59377836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl); 59387836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 59397836SJohn.Forte@Sun.COM switch (errno) { 59407836SJohn.Forte@Sun.COM case EBUSY: 59417836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 59427836SJohn.Forte@Sun.COM break; 59439585STim.Szeto@Sun.COM case EPERM: 59449585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 59459585STim.Szeto@Sun.COM break; 59467836SJohn.Forte@Sun.COM case EACCES: 59477836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 59487836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 59497836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 59507836SJohn.Forte@Sun.COM break; 59517836SJohn.Forte@Sun.COM default: 59527836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 59537836SJohn.Forte@Sun.COM break; 59547836SJohn.Forte@Sun.COM } 59557836SJohn.Forte@Sun.COM break; 59567836SJohn.Forte@Sun.COM case ENODEV: 59577836SJohn.Forte@Sun.COM case ENOENT: 59587836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 59597836SJohn.Forte@Sun.COM break; 59607836SJohn.Forte@Sun.COM default: 59617836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 59627836SJohn.Forte@Sun.COM "stmfRemoveViewEntry:ioctl errno(%d)", 59637836SJohn.Forte@Sun.COM errno); 59647836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 59657836SJohn.Forte@Sun.COM break; 59667836SJohn.Forte@Sun.COM } 59677836SJohn.Forte@Sun.COM goto done; 59687836SJohn.Forte@Sun.COM } 59697836SJohn.Forte@Sun.COM 59709585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 59719585STim.Szeto@Sun.COM goto done; 59729585STim.Szeto@Sun.COM } 59739585STim.Szeto@Sun.COM 59747836SJohn.Forte@Sun.COM ret = psRemoveViewEntry(lu, viewEntryIndex); 59757836SJohn.Forte@Sun.COM switch (ret) { 59767836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 59777836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 59787836SJohn.Forte@Sun.COM break; 59797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 59807836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 59817836SJohn.Forte@Sun.COM break; 59827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 59837836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 59847836SJohn.Forte@Sun.COM break; 59857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 59867836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 59877836SJohn.Forte@Sun.COM break; 59887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 59897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 59907836SJohn.Forte@Sun.COM break; 59917836SJohn.Forte@Sun.COM default: 59927836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 59937836SJohn.Forte@Sun.COM "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)", 59947836SJohn.Forte@Sun.COM ret); 59957836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 59967836SJohn.Forte@Sun.COM break; 59977836SJohn.Forte@Sun.COM } 59987836SJohn.Forte@Sun.COM 59997836SJohn.Forte@Sun.COM done: 60007836SJohn.Forte@Sun.COM (void) close(fd); 60017836SJohn.Forte@Sun.COM return (ret); 60027836SJohn.Forte@Sun.COM } 60037836SJohn.Forte@Sun.COM 60047836SJohn.Forte@Sun.COM /* 60057836SJohn.Forte@Sun.COM * stmfSetProviderData 60067836SJohn.Forte@Sun.COM * 60077836SJohn.Forte@Sun.COM * Purpose: set the provider data 60087836SJohn.Forte@Sun.COM * 60097836SJohn.Forte@Sun.COM * providerName - unique name of provider 60107836SJohn.Forte@Sun.COM * nvl - nvlist to set 60117836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 60127836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 60137836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 60147836SJohn.Forte@Sun.COM */ 60157836SJohn.Forte@Sun.COM int 60167836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType) 60177836SJohn.Forte@Sun.COM { 60187836SJohn.Forte@Sun.COM return (stmfSetProviderDataProt(providerName, nvl, providerType, 60197836SJohn.Forte@Sun.COM NULL)); 60207836SJohn.Forte@Sun.COM } 60217836SJohn.Forte@Sun.COM 60227836SJohn.Forte@Sun.COM /* 60237836SJohn.Forte@Sun.COM * stmfSetProviderDataProt 60247836SJohn.Forte@Sun.COM * 60257836SJohn.Forte@Sun.COM * Purpose: set the provider data 60267836SJohn.Forte@Sun.COM * 60277836SJohn.Forte@Sun.COM * providerName - unique name of provider 60287836SJohn.Forte@Sun.COM * nvl - nvlist to set 60297836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 60307836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 60317836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 60327836SJohn.Forte@Sun.COM * setToken - Stale data token returned in the stmfGetProviderDataProt() 60337836SJohn.Forte@Sun.COM * call or NULL. 60347836SJohn.Forte@Sun.COM */ 60357836SJohn.Forte@Sun.COM int 60367836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, 60377836SJohn.Forte@Sun.COM uint64_t *setToken) 60387836SJohn.Forte@Sun.COM { 60397836SJohn.Forte@Sun.COM int ret; 60407836SJohn.Forte@Sun.COM int fd; 60417836SJohn.Forte@Sun.COM 60427836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 60437836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 60447836SJohn.Forte@Sun.COM } 60457836SJohn.Forte@Sun.COM 60467836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 60477836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 60487836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 60497836SJohn.Forte@Sun.COM } 60507836SJohn.Forte@Sun.COM 60517836SJohn.Forte@Sun.COM /* call init */ 60527836SJohn.Forte@Sun.COM ret = initializeConfig(); 60537836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 60547836SJohn.Forte@Sun.COM return (ret); 60557836SJohn.Forte@Sun.COM } 60567836SJohn.Forte@Sun.COM 60577836SJohn.Forte@Sun.COM /* 60587836SJohn.Forte@Sun.COM * Open control node for stmf 60597836SJohn.Forte@Sun.COM */ 60607836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 60617836SJohn.Forte@Sun.COM return (ret); 60627836SJohn.Forte@Sun.COM 60639585STim.Szeto@Sun.COM ret = setProviderData(fd, providerName, nvl, providerType, setToken); 60647836SJohn.Forte@Sun.COM 60657836SJohn.Forte@Sun.COM (void) close(fd); 60667836SJohn.Forte@Sun.COM 60677836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 60687836SJohn.Forte@Sun.COM goto done; 60697836SJohn.Forte@Sun.COM } 60707836SJohn.Forte@Sun.COM 60719585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 60729585STim.Szeto@Sun.COM goto done; 60739585STim.Szeto@Sun.COM } 60749585STim.Szeto@Sun.COM 60757836SJohn.Forte@Sun.COM /* setting driver provider data successful. Now persist it */ 60769585STim.Szeto@Sun.COM ret = psSetProviderData(providerName, nvl, providerType, NULL); 60777836SJohn.Forte@Sun.COM switch (ret) { 60787836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 60797836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 60807836SJohn.Forte@Sun.COM break; 60817836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 60827836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 60837836SJohn.Forte@Sun.COM break; 60847836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 60857836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 60867836SJohn.Forte@Sun.COM break; 60877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 60887836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 60897836SJohn.Forte@Sun.COM break; 60907836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 60917836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 60927836SJohn.Forte@Sun.COM break; 60937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_PROV_DATA_STALE: 60947836SJohn.Forte@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 60957836SJohn.Forte@Sun.COM break; 60967836SJohn.Forte@Sun.COM default: 60977836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 60987836SJohn.Forte@Sun.COM "stmfSetProviderData" 60997836SJohn.Forte@Sun.COM "psSetProviderData:error(%d)", ret); 61007836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 61017836SJohn.Forte@Sun.COM break; 61027836SJohn.Forte@Sun.COM } 61037836SJohn.Forte@Sun.COM 61047836SJohn.Forte@Sun.COM done: 61057836SJohn.Forte@Sun.COM return (ret); 61067836SJohn.Forte@Sun.COM } 61077836SJohn.Forte@Sun.COM 61087836SJohn.Forte@Sun.COM /* 61099585STim.Szeto@Sun.COM * getProviderData 61109585STim.Szeto@Sun.COM * 61119585STim.Szeto@Sun.COM * Purpose: set the provider data from stmf 61129585STim.Szeto@Sun.COM * 61139585STim.Szeto@Sun.COM * providerName - unique name of provider 61149585STim.Szeto@Sun.COM * nvl - nvlist to load/retrieve 61159585STim.Szeto@Sun.COM * providerType - logical unit or port provider 61169585STim.Szeto@Sun.COM * setToken - returned stale data token 61179585STim.Szeto@Sun.COM */ 61189585STim.Szeto@Sun.COM int 61199585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType, 61209585STim.Szeto@Sun.COM uint64_t *setToken) 61219585STim.Szeto@Sun.COM { 61229585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 61239585STim.Szeto@Sun.COM int fd; 61249585STim.Szeto@Sun.COM int ioctlRet; 61259585STim.Szeto@Sun.COM size_t nvlistSize = ALLOC_PP_DATA_SIZE; 61269585STim.Szeto@Sun.COM int retryCnt = 0; 61279585STim.Szeto@Sun.COM int retryCntMax = MAX_PROVIDER_RETRY; 61289585STim.Szeto@Sun.COM stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL; 61299585STim.Szeto@Sun.COM boolean_t retry = B_TRUE; 61309585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 61319585STim.Szeto@Sun.COM 61329585STim.Szeto@Sun.COM if (providerName == NULL) { 61339585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 61349585STim.Szeto@Sun.COM } 61359585STim.Szeto@Sun.COM 61369585STim.Szeto@Sun.COM /* 61379585STim.Szeto@Sun.COM * Open control node for stmf 61389585STim.Szeto@Sun.COM */ 61399585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 61409585STim.Szeto@Sun.COM return (ret); 61419585STim.Szeto@Sun.COM 61429585STim.Szeto@Sun.COM /* set provider name and provider type */ 61439585STim.Szeto@Sun.COM if (strlcpy(ppi.ppi_name, providerName, 61449585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) >= 61459585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) { 61469585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 61479585STim.Szeto@Sun.COM goto done; 61489585STim.Szeto@Sun.COM } 61499585STim.Szeto@Sun.COM switch (providerType) { 61509585STim.Szeto@Sun.COM case STMF_LU_PROVIDER_TYPE: 61519585STim.Szeto@Sun.COM ppi.ppi_lu_provider = 1; 61529585STim.Szeto@Sun.COM break; 61539585STim.Szeto@Sun.COM case STMF_PORT_PROVIDER_TYPE: 61549585STim.Szeto@Sun.COM ppi.ppi_port_provider = 1; 61559585STim.Szeto@Sun.COM break; 61569585STim.Szeto@Sun.COM default: 61579585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 61589585STim.Szeto@Sun.COM goto done; 61599585STim.Szeto@Sun.COM } 61609585STim.Szeto@Sun.COM 61619585STim.Szeto@Sun.COM do { 61629585STim.Szeto@Sun.COM /* allocate memory for ioctl */ 61639585STim.Szeto@Sun.COM ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize + 61649585STim.Szeto@Sun.COM sizeof (stmf_ppioctl_data_t)); 61659585STim.Szeto@Sun.COM if (ppi_out == NULL) { 61669585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 61679585STim.Szeto@Sun.COM goto done; 61689585STim.Szeto@Sun.COM 61699585STim.Szeto@Sun.COM } 61709585STim.Szeto@Sun.COM 61719585STim.Szeto@Sun.COM /* set the size of the ioctl data to allocated buffer */ 61729585STim.Szeto@Sun.COM ppi.ppi_data_size = nvlistSize; 61739585STim.Szeto@Sun.COM 61749585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 61759585STim.Szeto@Sun.COM 61769585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 61779585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 61789585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 61799585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) + 61809585STim.Szeto@Sun.COM nvlistSize; 61819585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out; 61829585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl); 61839585STim.Szeto@Sun.COM if (ioctlRet != 0) { 61849585STim.Szeto@Sun.COM switch (errno) { 61859585STim.Szeto@Sun.COM case EBUSY: 61869585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 61879585STim.Szeto@Sun.COM break; 61889585STim.Szeto@Sun.COM case EPERM: 61899585STim.Szeto@Sun.COM case EACCES: 61909585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 61919585STim.Szeto@Sun.COM break; 61929585STim.Szeto@Sun.COM case EINVAL: 61939585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 61949585STim.Szeto@Sun.COM STMF_IOCERR_INSUFFICIENT_BUF) { 61959585STim.Szeto@Sun.COM nvlistSize = 61969585STim.Szeto@Sun.COM ppi_out->ppi_data_size; 61979585STim.Szeto@Sun.COM free(ppi_out); 61989585STim.Szeto@Sun.COM ppi_out = NULL; 61999585STim.Szeto@Sun.COM if (retryCnt++ > retryCntMax) { 62009585STim.Szeto@Sun.COM retry = B_FALSE; 62019585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 62029585STim.Szeto@Sun.COM } else { 62039585STim.Szeto@Sun.COM ret = 62049585STim.Szeto@Sun.COM STMF_STATUS_SUCCESS; 62059585STim.Szeto@Sun.COM } 62069585STim.Szeto@Sun.COM } else { 62079585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 62089585STim.Szeto@Sun.COM "getProviderData:ioctl" 62099585STim.Szeto@Sun.COM "unable to retrieve " 62109585STim.Szeto@Sun.COM "nvlist"); 62119585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 62129585STim.Szeto@Sun.COM } 62139585STim.Szeto@Sun.COM break; 62149585STim.Szeto@Sun.COM case ENOENT: 62159585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 62169585STim.Szeto@Sun.COM break; 62179585STim.Szeto@Sun.COM default: 62189585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 62199585STim.Szeto@Sun.COM "getProviderData:ioctl errno(%d)", 62209585STim.Szeto@Sun.COM errno); 62219585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 62229585STim.Szeto@Sun.COM break; 62239585STim.Szeto@Sun.COM } 62249585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) 62259585STim.Szeto@Sun.COM goto done; 62269585STim.Szeto@Sun.COM } 62279585STim.Szeto@Sun.COM } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF); 62289585STim.Szeto@Sun.COM 62299585STim.Szeto@Sun.COM if ((ret = nvlist_unpack((char *)ppi_out->ppi_data, 62309585STim.Szeto@Sun.COM ppi_out->ppi_data_size, nvl, 0)) != 0) { 62319585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 62329585STim.Szeto@Sun.COM goto done; 62339585STim.Szeto@Sun.COM } 62349585STim.Szeto@Sun.COM 62359585STim.Szeto@Sun.COM /* caller has asked for new token */ 62369585STim.Szeto@Sun.COM if (setToken) { 62379585STim.Szeto@Sun.COM *setToken = ppi_out->ppi_token; 62389585STim.Szeto@Sun.COM } 62399585STim.Szeto@Sun.COM done: 62409585STim.Szeto@Sun.COM free(ppi_out); 62419585STim.Szeto@Sun.COM (void) close(fd); 62429585STim.Szeto@Sun.COM return (ret); 62439585STim.Szeto@Sun.COM } 62449585STim.Szeto@Sun.COM 62459585STim.Szeto@Sun.COM /* 62467836SJohn.Forte@Sun.COM * setProviderData 62477836SJohn.Forte@Sun.COM * 62489585STim.Szeto@Sun.COM * Purpose: set the provider data in stmf 62497836SJohn.Forte@Sun.COM * 62507836SJohn.Forte@Sun.COM * providerName - unique name of provider 62517836SJohn.Forte@Sun.COM * nvl - nvlist to set 62527836SJohn.Forte@Sun.COM * providerType - logical unit or port provider 62539585STim.Szeto@Sun.COM * setToken - stale data token to check if not NULL 62547836SJohn.Forte@Sun.COM */ 62557836SJohn.Forte@Sun.COM static int 62569585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType, 62579585STim.Szeto@Sun.COM uint64_t *setToken) 62587836SJohn.Forte@Sun.COM { 62597836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 62607836SJohn.Forte@Sun.COM int ioctlRet; 62617836SJohn.Forte@Sun.COM size_t nvlistEncodedSize; 62627836SJohn.Forte@Sun.COM stmf_ppioctl_data_t *ppi = NULL; 62639585STim.Szeto@Sun.COM uint64_t outToken; 62647836SJohn.Forte@Sun.COM char *allocatedNvBuffer; 62657836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 62667836SJohn.Forte@Sun.COM 62677836SJohn.Forte@Sun.COM if (providerName == NULL) { 62687836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 62697836SJohn.Forte@Sun.COM } 62707836SJohn.Forte@Sun.COM 62717836SJohn.Forte@Sun.COM /* get size of encoded nvlist */ 62727836SJohn.Forte@Sun.COM if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) { 62737836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 62747836SJohn.Forte@Sun.COM } 62757836SJohn.Forte@Sun.COM 62767836SJohn.Forte@Sun.COM /* allocate memory for ioctl */ 62777836SJohn.Forte@Sun.COM ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize + 62787836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t)); 62797836SJohn.Forte@Sun.COM if (ppi == NULL) { 62807836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 62817836SJohn.Forte@Sun.COM } 62827836SJohn.Forte@Sun.COM 62839585STim.Szeto@Sun.COM if (setToken) { 62849585STim.Szeto@Sun.COM ppi->ppi_token_valid = 1; 62859585STim.Szeto@Sun.COM ppi->ppi_token = *setToken; 62869585STim.Szeto@Sun.COM } 62879585STim.Szeto@Sun.COM 62887836SJohn.Forte@Sun.COM allocatedNvBuffer = (char *)&ppi->ppi_data; 62897836SJohn.Forte@Sun.COM if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize, 62907836SJohn.Forte@Sun.COM NV_ENCODE_XDR, 0) != 0) { 62917836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 62927836SJohn.Forte@Sun.COM } 62937836SJohn.Forte@Sun.COM 62947836SJohn.Forte@Sun.COM /* set provider name and provider type */ 62957836SJohn.Forte@Sun.COM (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name)); 62967836SJohn.Forte@Sun.COM switch (providerType) { 62977836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 62987836SJohn.Forte@Sun.COM ppi->ppi_lu_provider = 1; 62997836SJohn.Forte@Sun.COM break; 63007836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 63017836SJohn.Forte@Sun.COM ppi->ppi_port_provider = 1; 63027836SJohn.Forte@Sun.COM break; 63037836SJohn.Forte@Sun.COM default: 63047836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 63057836SJohn.Forte@Sun.COM } 63067836SJohn.Forte@Sun.COM 63077836SJohn.Forte@Sun.COM /* set the size of the ioctl data to packed data size */ 63087836SJohn.Forte@Sun.COM ppi->ppi_data_size = nvlistEncodedSize; 63097836SJohn.Forte@Sun.COM 63107836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 63117836SJohn.Forte@Sun.COM 63127836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 63137836SJohn.Forte@Sun.COM /* 63147836SJohn.Forte@Sun.COM * Subtracting 8 from the size as that is the size of the last member 63157836SJohn.Forte@Sun.COM * of the structure where the packed data resides 63167836SJohn.Forte@Sun.COM */ 63177836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = nvlistEncodedSize + 63187836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t) - 8; 63197836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi; 63209585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (uint64_t); 63219585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken; 63227836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl); 63237836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 63247836SJohn.Forte@Sun.COM switch (errno) { 63257836SJohn.Forte@Sun.COM case EBUSY: 63267836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 63277836SJohn.Forte@Sun.COM break; 63289585STim.Szeto@Sun.COM case EPERM: 63297836SJohn.Forte@Sun.COM case EACCES: 63307836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 63317836SJohn.Forte@Sun.COM break; 63329585STim.Szeto@Sun.COM case EINVAL: 63339585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 63349585STim.Szeto@Sun.COM STMF_IOCERR_PPD_UPDATED) { 63359585STim.Szeto@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 63369585STim.Szeto@Sun.COM } else { 63379585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 63389585STim.Szeto@Sun.COM } 63399585STim.Szeto@Sun.COM break; 63407836SJohn.Forte@Sun.COM default: 63417836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 63427836SJohn.Forte@Sun.COM "setProviderData:ioctl errno(%d)", errno); 63437836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 63447836SJohn.Forte@Sun.COM break; 63457836SJohn.Forte@Sun.COM } 63467836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) 63477836SJohn.Forte@Sun.COM goto done; 63487836SJohn.Forte@Sun.COM } 63497836SJohn.Forte@Sun.COM 63509585STim.Szeto@Sun.COM /* caller has asked for new token */ 63519585STim.Szeto@Sun.COM if (setToken) { 63529585STim.Szeto@Sun.COM *setToken = outToken; 63539585STim.Szeto@Sun.COM } 63547836SJohn.Forte@Sun.COM done: 63557836SJohn.Forte@Sun.COM free(ppi); 63567836SJohn.Forte@Sun.COM return (ret); 63577836SJohn.Forte@Sun.COM } 63589585STim.Szeto@Sun.COM 63599585STim.Szeto@Sun.COM /* 63609585STim.Szeto@Sun.COM * set the persistence method in the library only or library and service 63619585STim.Szeto@Sun.COM */ 63629585STim.Szeto@Sun.COM int 63639585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet) 63649585STim.Szeto@Sun.COM { 63659585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 63669585STim.Szeto@Sun.COM int oldPersist; 63679585STim.Szeto@Sun.COM 63689585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 63699585STim.Szeto@Sun.COM oldPersist = iPersistType; 63709585STim.Szeto@Sun.COM if (persistType == STMF_PERSIST_NONE || 63719585STim.Szeto@Sun.COM persistType == STMF_PERSIST_SMF) { 63729585STim.Szeto@Sun.COM iLibSetPersist = B_TRUE; 63739585STim.Szeto@Sun.COM iPersistType = persistType; 63749585STim.Szeto@Sun.COM } else { 63759585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 63769585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 63779585STim.Szeto@Sun.COM } 63789585STim.Szeto@Sun.COM /* Is this for this library open or in SMF */ 63799585STim.Szeto@Sun.COM if (serviceSet == B_TRUE) { 63809585STim.Szeto@Sun.COM ret = psSetServicePersist(persistType); 63819585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 63829585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 63839585STim.Szeto@Sun.COM /* Set to old value */ 63849585STim.Szeto@Sun.COM iPersistType = oldPersist; 63859585STim.Szeto@Sun.COM } 63869585STim.Szeto@Sun.COM } 63879585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 63889585STim.Szeto@Sun.COM 63899585STim.Szeto@Sun.COM return (ret); 63909585STim.Szeto@Sun.COM } 63919585STim.Szeto@Sun.COM 63929585STim.Szeto@Sun.COM /* 63939585STim.Szeto@Sun.COM * Only returns internal state for persist. If unset, goes to ps. If that 63949585STim.Szeto@Sun.COM * fails, returns default setting 63959585STim.Szeto@Sun.COM */ 63969585STim.Szeto@Sun.COM static uint8_t 63979585STim.Szeto@Sun.COM iGetPersistMethod() 63989585STim.Szeto@Sun.COM { 63999585STim.Szeto@Sun.COM 64009585STim.Szeto@Sun.COM uint8_t persistType = 0; 64019585STim.Szeto@Sun.COM 64029585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 64039585STim.Szeto@Sun.COM if (iLibSetPersist) { 64049585STim.Szeto@Sun.COM persistType = iPersistType; 64059585STim.Szeto@Sun.COM } else { 64069585STim.Szeto@Sun.COM int ret; 64079585STim.Szeto@Sun.COM ret = psGetServicePersist(&persistType); 64089585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 64099585STim.Szeto@Sun.COM /* set to default */ 64109585STim.Szeto@Sun.COM persistType = STMF_DEFAULT_PERSIST; 64119585STim.Szeto@Sun.COM } 64129585STim.Szeto@Sun.COM } 64139585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 64149585STim.Szeto@Sun.COM return (persistType); 64159585STim.Szeto@Sun.COM } 64169585STim.Szeto@Sun.COM 64179585STim.Szeto@Sun.COM /* 64189585STim.Szeto@Sun.COM * Returns either library state or persistent config state depending on 64199585STim.Szeto@Sun.COM * serviceState 64209585STim.Szeto@Sun.COM */ 64219585STim.Szeto@Sun.COM int 64229585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState) 64239585STim.Szeto@Sun.COM { 64249585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 64259585STim.Szeto@Sun.COM 64269585STim.Szeto@Sun.COM if (persistType == NULL) { 64279585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 64289585STim.Szeto@Sun.COM } 64299585STim.Szeto@Sun.COM if (serviceState) { 64309585STim.Szeto@Sun.COM ret = psGetServicePersist(persistType); 64319585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 64329585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 64339585STim.Szeto@Sun.COM } 64349585STim.Szeto@Sun.COM } else { 64359585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 64369585STim.Szeto@Sun.COM if (iLibSetPersist) { 64379585STim.Szeto@Sun.COM *persistType = iPersistType; 64389585STim.Szeto@Sun.COM } else { 64399585STim.Szeto@Sun.COM *persistType = STMF_DEFAULT_PERSIST; 64409585STim.Szeto@Sun.COM } 64419585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 64429585STim.Szeto@Sun.COM } 64439585STim.Szeto@Sun.COM 64449585STim.Szeto@Sun.COM return (ret); 64459585STim.Szeto@Sun.COM } 644610691STim.Szeto@Sun.COM 644710691STim.Szeto@Sun.COM /* 644810725SJohn.Forte@Sun.COM * stmfPostProxyMsg 644910725SJohn.Forte@Sun.COM * 645010725SJohn.Forte@Sun.COM * Purpose: Post a message to the proxy port provider 645110725SJohn.Forte@Sun.COM * 645210725SJohn.Forte@Sun.COM * buf - buffer containing message to post 645310725SJohn.Forte@Sun.COM * buflen - buffer length 645410725SJohn.Forte@Sun.COM */ 645510725SJohn.Forte@Sun.COM int 645610725SJohn.Forte@Sun.COM stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen) 645710725SJohn.Forte@Sun.COM { 645810725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 645910725SJohn.Forte@Sun.COM int ioctlRet; 646010725SJohn.Forte@Sun.COM pppt_iocdata_t ppptIoctl = {0}; 646110725SJohn.Forte@Sun.COM 646210725SJohn.Forte@Sun.COM if (buf == NULL) { 646310725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 646410725SJohn.Forte@Sun.COM } 646510725SJohn.Forte@Sun.COM 646610725SJohn.Forte@Sun.COM /* 646710725SJohn.Forte@Sun.COM * Issue ioctl to post the message 646810725SJohn.Forte@Sun.COM */ 646910725SJohn.Forte@Sun.COM ppptIoctl.pppt_version = PPPT_VERSION_1; 647010725SJohn.Forte@Sun.COM ppptIoctl.pppt_buf_size = buflen; 647110725SJohn.Forte@Sun.COM ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf; 647210725SJohn.Forte@Sun.COM ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl); 647310725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 647410725SJohn.Forte@Sun.COM switch (errno) { 647510725SJohn.Forte@Sun.COM case EPERM: 647610725SJohn.Forte@Sun.COM case EACCES: 647710725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 647810725SJohn.Forte@Sun.COM break; 647910725SJohn.Forte@Sun.COM default: 648010725SJohn.Forte@Sun.COM ret = STMF_ERROR_POST_MSG_FAILED; 648110725SJohn.Forte@Sun.COM break; 648210725SJohn.Forte@Sun.COM } 648310725SJohn.Forte@Sun.COM } 648410725SJohn.Forte@Sun.COM 648510725SJohn.Forte@Sun.COM return (ret); 648610725SJohn.Forte@Sun.COM } 648710725SJohn.Forte@Sun.COM 648810725SJohn.Forte@Sun.COM /* 648910725SJohn.Forte@Sun.COM * stmfInitProxyDoor 649010725SJohn.Forte@Sun.COM * 649110725SJohn.Forte@Sun.COM * Purpose: Install door in proxy 649210725SJohn.Forte@Sun.COM * 649310725SJohn.Forte@Sun.COM * hdl - pointer to returned handle 649410725SJohn.Forte@Sun.COM * fd - door from door_create() 649510725SJohn.Forte@Sun.COM */ 649610725SJohn.Forte@Sun.COM int 649710725SJohn.Forte@Sun.COM stmfInitProxyDoor(int *hdl, int door) 649810725SJohn.Forte@Sun.COM { 649910725SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 650010725SJohn.Forte@Sun.COM int ioctlRet; 650110725SJohn.Forte@Sun.COM int fd; 650210725SJohn.Forte@Sun.COM pppt_iocdata_t ppptIoctl = {0}; 650310725SJohn.Forte@Sun.COM 650410725SJohn.Forte@Sun.COM if (hdl == NULL) { 650510725SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 650610725SJohn.Forte@Sun.COM } 650710725SJohn.Forte@Sun.COM 650810725SJohn.Forte@Sun.COM /* 650910725SJohn.Forte@Sun.COM * Open control node for pppt 651010725SJohn.Forte@Sun.COM */ 651110725SJohn.Forte@Sun.COM if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) { 651210725SJohn.Forte@Sun.COM return (ret); 651310725SJohn.Forte@Sun.COM } 651410725SJohn.Forte@Sun.COM 651510725SJohn.Forte@Sun.COM /* 651610725SJohn.Forte@Sun.COM * Issue ioctl to install the door 651710725SJohn.Forte@Sun.COM */ 651810725SJohn.Forte@Sun.COM ppptIoctl.pppt_version = PPPT_VERSION_1; 651910725SJohn.Forte@Sun.COM ppptIoctl.pppt_door_fd = (uint32_t)door; 652010725SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl); 652110725SJohn.Forte@Sun.COM if (ioctlRet != 0) { 652210725SJohn.Forte@Sun.COM switch (errno) { 652310725SJohn.Forte@Sun.COM case EPERM: 652410725SJohn.Forte@Sun.COM case EACCES: 652510725SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 652610725SJohn.Forte@Sun.COM break; 652710725SJohn.Forte@Sun.COM case EINVAL: 652810725SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 652910725SJohn.Forte@Sun.COM break; 653010725SJohn.Forte@Sun.COM case EBUSY: 653110725SJohn.Forte@Sun.COM ret = STMF_ERROR_DOOR_INSTALLED; 653210725SJohn.Forte@Sun.COM break; 653310725SJohn.Forte@Sun.COM default: 653410725SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 653510725SJohn.Forte@Sun.COM break; 653610725SJohn.Forte@Sun.COM } 653710725SJohn.Forte@Sun.COM } 653810725SJohn.Forte@Sun.COM 653910725SJohn.Forte@Sun.COM /* return driver fd to caller */ 654010725SJohn.Forte@Sun.COM *hdl = fd; 654110725SJohn.Forte@Sun.COM return (ret); 654210725SJohn.Forte@Sun.COM } 654310725SJohn.Forte@Sun.COM 654410725SJohn.Forte@Sun.COM void 654510725SJohn.Forte@Sun.COM stmfDestroyProxyDoor(int hdl) 654610725SJohn.Forte@Sun.COM { 654710725SJohn.Forte@Sun.COM (void) close(hdl); 654810725SJohn.Forte@Sun.COM } 654910725SJohn.Forte@Sun.COM 655010725SJohn.Forte@Sun.COM /* 655110691STim.Szeto@Sun.COM * validateLunNumIoctl 655210691STim.Szeto@Sun.COM * 655310691STim.Szeto@Sun.COM * Purpose: Issues ioctl to check and get available lun# in view entry 655410691STim.Szeto@Sun.COM * 655510691STim.Szeto@Sun.COM * viewEntry - view entry to use 655610691STim.Szeto@Sun.COM */ 655710691STim.Szeto@Sun.COM static int 655810691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry) 655910691STim.Szeto@Sun.COM { 656010691STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 656110691STim.Szeto@Sun.COM int ioctlRet; 656210691STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 656310691STim.Szeto@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 656410691STim.Szeto@Sun.COM 656510691STim.Szeto@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 656610691STim.Szeto@Sun.COM /* 656710691STim.Szeto@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 656810691STim.Szeto@Sun.COM * false on input 656910691STim.Szeto@Sun.COM */ 657010691STim.Szeto@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 657110691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 657210691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 657310691STim.Szeto@Sun.COM 657410691STim.Szeto@Sun.COM if (viewEntry->allHosts == B_FALSE) { 657510691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 657610691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 657710691STim.Szeto@Sun.COM ioctlViewEntry.ve_host_group.name_size = 657810691STim.Szeto@Sun.COM strlen((char *)viewEntry->hostGroup); 657910691STim.Szeto@Sun.COM } 658010691STim.Szeto@Sun.COM if (viewEntry->allTargets == B_FALSE) { 658110691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, 658210691STim.Szeto@Sun.COM &ioctlViewEntry.ve_target_group.name, 658310691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 658410691STim.Szeto@Sun.COM ioctlViewEntry.ve_target_group.name_size = 658510691STim.Szeto@Sun.COM strlen((char *)viewEntry->targetGroup); 658610691STim.Szeto@Sun.COM } 658710691STim.Szeto@Sun.COM /* Validating the lun number */ 658810691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 658910691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 659010691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 659110691STim.Szeto@Sun.COM } 659210691STim.Szeto@Sun.COM 659310691STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 659410691STim.Szeto@Sun.COM /* 659510691STim.Szeto@Sun.COM * Issue ioctl to validate lun# in the view entry 659610691STim.Szeto@Sun.COM */ 659710691STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 659810691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 659910691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 660010691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 660110691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 660210691STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl); 660310691STim.Szeto@Sun.COM 660410691STim.Szeto@Sun.COM /* save available lun number */ 660510691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 660610691STim.Szeto@Sun.COM bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 660710691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 660810691STim.Szeto@Sun.COM } 660910691STim.Szeto@Sun.COM if (ioctlRet != 0) { 661010691STim.Szeto@Sun.COM switch (errno) { 661110691STim.Szeto@Sun.COM case EBUSY: 661210691STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 661310691STim.Szeto@Sun.COM break; 661410691STim.Szeto@Sun.COM case EPERM: 661510691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 661610691STim.Szeto@Sun.COM break; 661710691STim.Szeto@Sun.COM case EACCES: 661810691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 661910691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 662010691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 662110691STim.Szeto@Sun.COM break; 662210691STim.Szeto@Sun.COM default: 662310691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 662410691STim.Szeto@Sun.COM break; 662510691STim.Szeto@Sun.COM } 662610691STim.Szeto@Sun.COM break; 662710691STim.Szeto@Sun.COM default: 662810691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 662910691STim.Szeto@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 663010691STim.Szeto@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 663110691STim.Szeto@Sun.COM break; 663210691STim.Szeto@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 663310691STim.Szeto@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 663410691STim.Szeto@Sun.COM break; 663510691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 663610691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 663710691STim.Szeto@Sun.COM break; 663810691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_HG: 663910691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_HG; 664010691STim.Szeto@Sun.COM break; 664110691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_TG: 664210691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_TG; 664310691STim.Szeto@Sun.COM break; 664410691STim.Szeto@Sun.COM default: 664510691STim.Szeto@Sun.COM syslog(LOG_DEBUG, 664610691STim.Szeto@Sun.COM "addViewEntryIoctl" 664710691STim.Szeto@Sun.COM ":error(%d)", 664810691STim.Szeto@Sun.COM stmfIoctl.stmf_error); 664910691STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 665010691STim.Szeto@Sun.COM break; 665110691STim.Szeto@Sun.COM } 665210691STim.Szeto@Sun.COM break; 665310691STim.Szeto@Sun.COM } 665410691STim.Szeto@Sun.COM } 665510691STim.Szeto@Sun.COM return (ret); 665610691STim.Szeto@Sun.COM } 665710691STim.Szeto@Sun.COM 665810691STim.Szeto@Sun.COM /* 665910691STim.Szeto@Sun.COM * stmfValidateView 666010691STim.Szeto@Sun.COM * 666110691STim.Szeto@Sun.COM * Purpose: Validate or get lun # base on TG, HG of view entry 666210691STim.Szeto@Sun.COM * 666310691STim.Szeto@Sun.COM * viewEntry - view entry structure to use 666410691STim.Szeto@Sun.COM */ 666510691STim.Szeto@Sun.COM int 666610691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry) 666710691STim.Szeto@Sun.COM { 666810691STim.Szeto@Sun.COM int ret; 666910691STim.Szeto@Sun.COM int fd; 667010691STim.Szeto@Sun.COM stmfViewEntry iViewEntry; 667110691STim.Szeto@Sun.COM 667210691STim.Szeto@Sun.COM if (viewEntry == NULL) { 667310691STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 667410691STim.Szeto@Sun.COM } 667510691STim.Szeto@Sun.COM 667610691STim.Szeto@Sun.COM /* initialize and set internal view entry */ 667710691STim.Szeto@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 667810691STim.Szeto@Sun.COM 667910691STim.Szeto@Sun.COM if (!viewEntry->allHosts) { 668010691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 668110691STim.Szeto@Sun.COM sizeof (iViewEntry.hostGroup)); 668210691STim.Szeto@Sun.COM } else { 668310691STim.Szeto@Sun.COM iViewEntry.allHosts = B_TRUE; 668410691STim.Szeto@Sun.COM } 668510691STim.Szeto@Sun.COM 668610691STim.Szeto@Sun.COM if (!viewEntry->allTargets) { 668710691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 668810691STim.Szeto@Sun.COM sizeof (iViewEntry.targetGroup)); 668910691STim.Szeto@Sun.COM } else { 669010691STim.Szeto@Sun.COM iViewEntry.allTargets = B_TRUE; 669110691STim.Szeto@Sun.COM } 669210691STim.Szeto@Sun.COM 669310691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 669410691STim.Szeto@Sun.COM iViewEntry.luNbrValid = B_TRUE; 669510691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 669610691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 669710691STim.Szeto@Sun.COM } 669810691STim.Szeto@Sun.COM 669910691STim.Szeto@Sun.COM /* 670010691STim.Szeto@Sun.COM * set users return view entry index valid flag to false 670110691STim.Szeto@Sun.COM * in case of failure 670210691STim.Szeto@Sun.COM */ 670310691STim.Szeto@Sun.COM viewEntry->veIndexValid = B_FALSE; 670410691STim.Szeto@Sun.COM 670510691STim.Szeto@Sun.COM /* Check to ensure service exists */ 670610691STim.Szeto@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 670710691STim.Szeto@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 670810691STim.Szeto@Sun.COM } 670910691STim.Szeto@Sun.COM 671010691STim.Szeto@Sun.COM /* call init */ 671110691STim.Szeto@Sun.COM ret = initializeConfig(); 671210691STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 671310691STim.Szeto@Sun.COM return (ret); 671410691STim.Szeto@Sun.COM } 671510691STim.Szeto@Sun.COM 671610691STim.Szeto@Sun.COM /* 671710691STim.Szeto@Sun.COM * Open control node for stmf 671810691STim.Szeto@Sun.COM */ 671910691STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 672010691STim.Szeto@Sun.COM return (ret); 672110691STim.Szeto@Sun.COM 672210691STim.Szeto@Sun.COM /* 672310691STim.Szeto@Sun.COM * Validate lun# in the view entry from the driver 672410691STim.Szeto@Sun.COM */ 672510691STim.Szeto@Sun.COM ret = validateLunNumIoctl(fd, &iViewEntry); 672610691STim.Szeto@Sun.COM (void) close(fd); 672710691STim.Szeto@Sun.COM 672810691STim.Szeto@Sun.COM /* save available lun number */ 672910691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 673010691STim.Szeto@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 673110691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 673210691STim.Szeto@Sun.COM } 673310691STim.Szeto@Sun.COM 673410691STim.Szeto@Sun.COM return (ret); 673510691STim.Szeto@Sun.COM } 6736