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> 507836SJohn.Forte@Sun.COM 517836SJohn.Forte@Sun.COM #define STMF_PATH "/devices/pseudo/stmf@0:admin" 529585STim.Szeto@Sun.COM #define SBD_PATH "/devices/pseudo/stmf_sbd@0:admin" 537836SJohn.Forte@Sun.COM 547836SJohn.Forte@Sun.COM #define EUI "eui." 557836SJohn.Forte@Sun.COM #define WWN "wwn." 567836SJohn.Forte@Sun.COM #define IQN "iqn." 579585STim.Szeto@Sun.COM #define LU_ASCII_GUID_SIZE 32 589585STim.Szeto@Sun.COM #define LU_GUID_SIZE 16 599585STim.Szeto@Sun.COM #define OUI_ASCII_SIZE 6 609585STim.Szeto@Sun.COM #define OUI_SIZE 3 617836SJohn.Forte@Sun.COM #define IDENT_LENGTH_BYTE 3 627836SJohn.Forte@Sun.COM 639585STim.Szeto@Sun.COM /* various initial allocation values */ 649585STim.Szeto@Sun.COM #define ALLOC_LU 8192 659585STim.Szeto@Sun.COM #define ALLOC_TARGET_PORT 2048 669585STim.Szeto@Sun.COM #define ALLOC_PROVIDER 64 679585STim.Szeto@Sun.COM #define ALLOC_GROUP 2048 689585STim.Szeto@Sun.COM #define ALLOC_SESSION 2048 699585STim.Szeto@Sun.COM #define ALLOC_VE 256 709585STim.Szeto@Sun.COM #define ALLOC_PP_DATA_SIZE 128*1024 719585STim.Szeto@Sun.COM #define ALLOC_GRP_MEMBER 256 729585STim.Szeto@Sun.COM 737836SJohn.Forte@Sun.COM #define MAX_ISCSI_NAME 223 749585STim.Szeto@Sun.COM #define MAX_SERIAL_SIZE 252 + 1 759585STim.Szeto@Sun.COM #define MAX_LU_ALIAS_SIZE 256 769585STim.Szeto@Sun.COM #define MAX_SBD_PROPS MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE 777836SJohn.Forte@Sun.COM 787836SJohn.Forte@Sun.COM #define OPEN_STMF 0 797836SJohn.Forte@Sun.COM #define OPEN_EXCL_STMF O_EXCL 807836SJohn.Forte@Sun.COM 819585STim.Szeto@Sun.COM #define OPEN_SBD 0 829585STim.Szeto@Sun.COM #define OPEN_EXCL_SBD O_EXCL 839585STim.Szeto@Sun.COM 847836SJohn.Forte@Sun.COM #define LOGICAL_UNIT_TYPE 0 857836SJohn.Forte@Sun.COM #define TARGET_TYPE 1 867836SJohn.Forte@Sun.COM #define STMF_SERVICE_TYPE 2 877836SJohn.Forte@Sun.COM 889585STim.Szeto@Sun.COM #define HOST_GROUP 1 899585STim.Szeto@Sun.COM #define TARGET_GROUP 2 909585STim.Szeto@Sun.COM 919585STim.Szeto@Sun.COM /* set default persistence here */ 929585STim.Szeto@Sun.COM #define STMF_DEFAULT_PERSIST STMF_PERSIST_SMF 939585STim.Szeto@Sun.COM 949585STim.Szeto@Sun.COM #define MAX_PROVIDER_RETRY 30 959585STim.Szeto@Sun.COM 967836SJohn.Forte@Sun.COM static int openStmf(int, int *fd); 979585STim.Szeto@Sun.COM static int openSbd(int, int *fd); 987836SJohn.Forte@Sun.COM static int groupIoctl(int fd, int cmd, stmfGroupName *); 997836SJohn.Forte@Sun.COM static int loadStore(int fd); 1007836SJohn.Forte@Sun.COM static int initializeConfig(); 1017836SJohn.Forte@Sun.COM static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *); 1027836SJohn.Forte@Sun.COM static int guidCompare(const void *, const void *); 1037836SJohn.Forte@Sun.COM static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *); 1047836SJohn.Forte@Sun.COM static int loadHostGroups(int fd, stmfGroupList *); 1057836SJohn.Forte@Sun.COM static int loadTargetGroups(int fd, stmfGroupList *); 1067836SJohn.Forte@Sun.COM static int getStmfState(stmf_state_desc_t *); 1077836SJohn.Forte@Sun.COM static int setStmfState(int fd, stmf_state_desc_t *, int); 1089585STim.Szeto@Sun.COM static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *); 1099585STim.Szeto@Sun.COM static int createDiskResource(luResourceImpl *); 1109585STim.Szeto@Sun.COM static int createDiskLu(diskResource *, stmfGuid *); 1119585STim.Szeto@Sun.COM static int deleteDiskLu(stmfGuid *luGuid); 1129585STim.Szeto@Sun.COM static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *); 1139585STim.Szeto@Sun.COM static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl); 1149585STim.Szeto@Sun.COM static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *); 1159585STim.Szeto@Sun.COM static int removeGuidFromDiskStore(stmfGuid *); 1169585STim.Szeto@Sun.COM static int addGuidToDiskStore(stmfGuid *, char *); 1179585STim.Szeto@Sun.COM static int persistDiskGuid(stmfGuid *, char *, boolean_t); 1189585STim.Szeto@Sun.COM static int setDiskProp(luResourceImpl *, uint32_t, const char *); 1199585STim.Szeto@Sun.COM static int checkHexUpper(char *); 1209585STim.Szeto@Sun.COM static int strToShift(const char *); 1219585STim.Szeto@Sun.COM static int niceStrToNum(const char *, uint64_t *); 1229585STim.Szeto@Sun.COM static void diskError(uint32_t, int *); 1239585STim.Szeto@Sun.COM static int importDiskLu(char *fname, stmfGuid *); 1249585STim.Szeto@Sun.COM static int modifyDiskLu(diskResource *, stmfGuid *, const char *); 1259585STim.Szeto@Sun.COM static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *); 1269585STim.Szeto@Sun.COM static int validateModifyDiskProp(uint32_t); 1279585STim.Szeto@Sun.COM static uint8_t iGetPersistMethod(); 1289585STim.Szeto@Sun.COM static int groupListIoctl(stmfGroupList **, int); 1299585STim.Szeto@Sun.COM static int iLoadGroupFromPs(stmfGroupList **, int); 1309585STim.Szeto@Sun.COM static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int); 1319585STim.Szeto@Sun.COM static int getProviderData(char *, nvlist_t **, int, uint64_t *); 1329585STim.Szeto@Sun.COM static int viewEntryCompare(const void *, const void *); 1339585STim.Szeto@Sun.COM 1349585STim.Szeto@Sun.COM static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER; 1359585STim.Szeto@Sun.COM static int iPersistType = 0; 1369585STim.Szeto@Sun.COM /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */ 1379585STim.Szeto@Sun.COM static boolean_t iLibSetPersist = B_FALSE; 1387836SJohn.Forte@Sun.COM 1397836SJohn.Forte@Sun.COM /* 1407836SJohn.Forte@Sun.COM * Open for stmf module 1417836SJohn.Forte@Sun.COM * 1427836SJohn.Forte@Sun.COM * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF) 1437836SJohn.Forte@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1447836SJohn.Forte@Sun.COM */ 1457836SJohn.Forte@Sun.COM static int 1467836SJohn.Forte@Sun.COM openStmf(int flag, int *fd) 1477836SJohn.Forte@Sun.COM { 1487836SJohn.Forte@Sun.COM int ret = STMF_STATUS_ERROR; 1497836SJohn.Forte@Sun.COM 1507836SJohn.Forte@Sun.COM if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1517836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 1527836SJohn.Forte@Sun.COM } else { 1537836SJohn.Forte@Sun.COM if (errno == EBUSY) { 1547836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 1559585STim.Szeto@Sun.COM } else if (errno == EACCES) { 1569585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1577836SJohn.Forte@Sun.COM } else { 1587836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 1597836SJohn.Forte@Sun.COM } 1607836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)", 1617836SJohn.Forte@Sun.COM STMF_PATH, errno); 1627836SJohn.Forte@Sun.COM } 1637836SJohn.Forte@Sun.COM 1647836SJohn.Forte@Sun.COM return (ret); 1657836SJohn.Forte@Sun.COM } 1667836SJohn.Forte@Sun.COM 1677836SJohn.Forte@Sun.COM /* 1689585STim.Szeto@Sun.COM * Open for sbd module 1699585STim.Szeto@Sun.COM * 1709585STim.Szeto@Sun.COM * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF) 1719585STim.Szeto@Sun.COM * fd - pointer to integer. On success, contains the stmf file descriptor 1729585STim.Szeto@Sun.COM */ 1739585STim.Szeto@Sun.COM static int 1749585STim.Szeto@Sun.COM openSbd(int flag, int *fd) 1759585STim.Szeto@Sun.COM { 1769585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 1779585STim.Szeto@Sun.COM 1789585STim.Szeto@Sun.COM if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) { 1799585STim.Szeto@Sun.COM ret = STMF_STATUS_SUCCESS; 1809585STim.Szeto@Sun.COM } else { 1819585STim.Szeto@Sun.COM if (errno == EBUSY) { 1829585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 1839585STim.Szeto@Sun.COM } else if (errno == EACCES) { 1849585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 1859585STim.Szeto@Sun.COM } else { 1869585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 1879585STim.Szeto@Sun.COM } 1889585STim.Szeto@Sun.COM syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)", 1899585STim.Szeto@Sun.COM SBD_PATH, errno); 1909585STim.Szeto@Sun.COM } 1919585STim.Szeto@Sun.COM 1929585STim.Szeto@Sun.COM return (ret); 1939585STim.Szeto@Sun.COM } 1949585STim.Szeto@Sun.COM 1959585STim.Szeto@Sun.COM /* 1967836SJohn.Forte@Sun.COM * initializeConfig 1977836SJohn.Forte@Sun.COM * 1987836SJohn.Forte@Sun.COM * This routine should be called before any ioctl requiring initialization 1997836SJohn.Forte@Sun.COM * which is basically everything except stmfGetState(), setStmfState() and 2007836SJohn.Forte@Sun.COM * stmfLoadConfig(). 2017836SJohn.Forte@Sun.COM */ 2027836SJohn.Forte@Sun.COM static int 2037836SJohn.Forte@Sun.COM initializeConfig() 2047836SJohn.Forte@Sun.COM { 2057836SJohn.Forte@Sun.COM int ret; 2067836SJohn.Forte@Sun.COM stmfState state; 2077836SJohn.Forte@Sun.COM 2087836SJohn.Forte@Sun.COM 2097836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2107836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2117836SJohn.Forte@Sun.COM return (ret); 2127836SJohn.Forte@Sun.COM } 2137836SJohn.Forte@Sun.COM 2147836SJohn.Forte@Sun.COM /* if we've already initialized or in the process, return success */ 2157836SJohn.Forte@Sun.COM if (state.configState == STMF_CONFIG_STATE_INIT_DONE || 2167836SJohn.Forte@Sun.COM state.configState == STMF_CONFIG_STATE_INIT) { 2177836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 2187836SJohn.Forte@Sun.COM } 2197836SJohn.Forte@Sun.COM 2207836SJohn.Forte@Sun.COM ret = stmfLoadConfig(); 2217836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2227836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2237836SJohn.Forte@Sun.COM "initializeConfig:stmfLoadConfig:error(%d)", ret); 2247836SJohn.Forte@Sun.COM return (ret); 2257836SJohn.Forte@Sun.COM } 2267836SJohn.Forte@Sun.COM 2277836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 2287836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 2297836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2307836SJohn.Forte@Sun.COM "initializeConfig:stmfGetState:error(%d)", ret); 2317836SJohn.Forte@Sun.COM return (ret); 2327836SJohn.Forte@Sun.COM } 2337836SJohn.Forte@Sun.COM 2347836SJohn.Forte@Sun.COM if (state.configState != STMF_CONFIG_STATE_INIT_DONE) { 2357836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)", 2367836SJohn.Forte@Sun.COM state.configState); 2377836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 2387836SJohn.Forte@Sun.COM } 2397836SJohn.Forte@Sun.COM 2407836SJohn.Forte@Sun.COM return (ret); 2417836SJohn.Forte@Sun.COM } 2427836SJohn.Forte@Sun.COM 2437836SJohn.Forte@Sun.COM 2447836SJohn.Forte@Sun.COM /* 2457836SJohn.Forte@Sun.COM * groupIoctl 2467836SJohn.Forte@Sun.COM * 2477836SJohn.Forte@Sun.COM * Purpose: issue ioctl for create/delete on group 2487836SJohn.Forte@Sun.COM * 2497836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group cmd 2507836SJohn.Forte@Sun.COM * groupName - groupName to create or delete 2517836SJohn.Forte@Sun.COM */ 2527836SJohn.Forte@Sun.COM static int 2537836SJohn.Forte@Sun.COM groupIoctl(int fd, int cmd, stmfGroupName *groupName) 2547836SJohn.Forte@Sun.COM { 2557836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 2567836SJohn.Forte@Sun.COM int ioctlRet; 2577836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 2587836SJohn.Forte@Sun.COM stmf_group_name_t iGroupName; 2597836SJohn.Forte@Sun.COM 2607836SJohn.Forte@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 2617836SJohn.Forte@Sun.COM 2627836SJohn.Forte@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 2637836SJohn.Forte@Sun.COM 2647836SJohn.Forte@Sun.COM iGroupName.name_size = strlen((char *)groupName); 2657836SJohn.Forte@Sun.COM 2667836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 2677836SJohn.Forte@Sun.COM /* 2687836SJohn.Forte@Sun.COM * Issue ioctl to create the host group 2697836SJohn.Forte@Sun.COM */ 2707836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 2717836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (iGroupName); 2727836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 2737836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 2747836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 2757836SJohn.Forte@Sun.COM switch (errno) { 2769585STim.Szeto@Sun.COM case EPERM: 2777836SJohn.Forte@Sun.COM case EACCES: 2787836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 2797836SJohn.Forte@Sun.COM break; 2807836SJohn.Forte@Sun.COM default: 2817836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 2827836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_EXISTS: 2837836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_EXISTS: 2847836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 2857836SJohn.Forte@Sun.COM break; 2867836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_IN_USE: 2877836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_IN_USE: 2887836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_IN_USE; 2897836SJohn.Forte@Sun.COM break; 2907836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 2917836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 2927836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 2937836SJohn.Forte@Sun.COM break; 2947836SJohn.Forte@Sun.COM default: 2957836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 2967836SJohn.Forte@Sun.COM "groupIoctl:error(%d)", 2977836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 2987836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 2997836SJohn.Forte@Sun.COM break; 3007836SJohn.Forte@Sun.COM } 3017836SJohn.Forte@Sun.COM break; 3027836SJohn.Forte@Sun.COM } 3037836SJohn.Forte@Sun.COM } 3047836SJohn.Forte@Sun.COM done: 3057836SJohn.Forte@Sun.COM return (ret); 3067836SJohn.Forte@Sun.COM } 3077836SJohn.Forte@Sun.COM 3087836SJohn.Forte@Sun.COM /* 3099585STim.Szeto@Sun.COM * groupMemberIoctl 3107836SJohn.Forte@Sun.COM * 3117836SJohn.Forte@Sun.COM * Purpose: issue ioctl for add/remove member on group 3127836SJohn.Forte@Sun.COM * 3137836SJohn.Forte@Sun.COM * cmd - valid STMF ioctl group member cmd 3147836SJohn.Forte@Sun.COM * groupName - groupName to add to or remove from 3157836SJohn.Forte@Sun.COM * devid - group member to add or remove 3167836SJohn.Forte@Sun.COM */ 3177836SJohn.Forte@Sun.COM static int 3187836SJohn.Forte@Sun.COM groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid) 3197836SJohn.Forte@Sun.COM { 3207836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 3217836SJohn.Forte@Sun.COM int ioctlRet; 3227836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 3237836SJohn.Forte@Sun.COM stmf_group_op_data_t stmfGroupData; 3247836SJohn.Forte@Sun.COM 3257836SJohn.Forte@Sun.COM bzero(&stmfGroupData, sizeof (stmfGroupData)); 3267836SJohn.Forte@Sun.COM 3277836SJohn.Forte@Sun.COM bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName)); 3287836SJohn.Forte@Sun.COM 3297836SJohn.Forte@Sun.COM stmfGroupData.group.name_size = strlen((char *)groupName); 3307836SJohn.Forte@Sun.COM stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength; 3317836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1], 3327836SJohn.Forte@Sun.COM devid->identLength); 3337836SJohn.Forte@Sun.COM 3347836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 3357836SJohn.Forte@Sun.COM /* 3367836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 3377836SJohn.Forte@Sun.COM */ 3387836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 3397836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData); 3407836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData; 3417836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 3427836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 3437836SJohn.Forte@Sun.COM switch (errno) { 3447836SJohn.Forte@Sun.COM case EBUSY: 345*9884STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 346*9884STim.Szeto@Sun.COM case STMF_IOCERR_TG_NEED_TG_OFFLINE: 347*9884STim.Szeto@Sun.COM ret = STMF_ERROR_TG_ONLINE; 348*9884STim.Szeto@Sun.COM break; 349*9884STim.Szeto@Sun.COM default: 350*9884STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 351*9884STim.Szeto@Sun.COM break; 352*9884STim.Szeto@Sun.COM } 3537836SJohn.Forte@Sun.COM break; 3549585STim.Szeto@Sun.COM case EPERM: 3557836SJohn.Forte@Sun.COM case EACCES: 3567836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 3577836SJohn.Forte@Sun.COM break; 3587836SJohn.Forte@Sun.COM default: 3597836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 3607836SJohn.Forte@Sun.COM case STMF_IOCERR_TG_ENTRY_EXISTS: 3617836SJohn.Forte@Sun.COM case STMF_IOCERR_HG_ENTRY_EXISTS: 3627836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 3637836SJohn.Forte@Sun.COM break; 3647836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG_ENTRY: 3657836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG_ENTRY: 3667836SJohn.Forte@Sun.COM ret = 3677836SJohn.Forte@Sun.COM STMF_ERROR_MEMBER_NOT_FOUND; 3687836SJohn.Forte@Sun.COM break; 3697836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 3707836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 3717836SJohn.Forte@Sun.COM ret = 3727836SJohn.Forte@Sun.COM STMF_ERROR_GROUP_NOT_FOUND; 3737836SJohn.Forte@Sun.COM break; 3747836SJohn.Forte@Sun.COM default: 3757836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 3767836SJohn.Forte@Sun.COM "groupMemberIoctl:error" 3777836SJohn.Forte@Sun.COM "(%d)", 3787836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 3797836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 3807836SJohn.Forte@Sun.COM break; 3817836SJohn.Forte@Sun.COM } 3827836SJohn.Forte@Sun.COM break; 3837836SJohn.Forte@Sun.COM } 3847836SJohn.Forte@Sun.COM } 3857836SJohn.Forte@Sun.COM done: 3867836SJohn.Forte@Sun.COM return (ret); 3877836SJohn.Forte@Sun.COM } 3887836SJohn.Forte@Sun.COM 3897836SJohn.Forte@Sun.COM /* 3909585STim.Szeto@Sun.COM * qsort function 3919585STim.Szeto@Sun.COM * sort on veIndex 3929585STim.Szeto@Sun.COM */ 3939585STim.Szeto@Sun.COM static int 3949585STim.Szeto@Sun.COM viewEntryCompare(const void *p1, const void *p2) 3959585STim.Szeto@Sun.COM { 3969585STim.Szeto@Sun.COM 3979585STim.Szeto@Sun.COM stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2; 3989585STim.Szeto@Sun.COM if (v1->veIndex > v2->veIndex) 3999585STim.Szeto@Sun.COM return (1); 4009585STim.Szeto@Sun.COM if (v1->veIndex < v2->veIndex) 4019585STim.Szeto@Sun.COM return (-1); 4029585STim.Szeto@Sun.COM return (0); 4039585STim.Szeto@Sun.COM } 4049585STim.Szeto@Sun.COM 4059585STim.Szeto@Sun.COM /* 4067836SJohn.Forte@Sun.COM * guidCompare 4077836SJohn.Forte@Sun.COM * 4087836SJohn.Forte@Sun.COM * qsort function 4097836SJohn.Forte@Sun.COM * sort on guid 4107836SJohn.Forte@Sun.COM */ 4117836SJohn.Forte@Sun.COM static int 4127836SJohn.Forte@Sun.COM guidCompare(const void *p1, const void *p2) 4137836SJohn.Forte@Sun.COM { 4147836SJohn.Forte@Sun.COM 4157836SJohn.Forte@Sun.COM stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2; 4167836SJohn.Forte@Sun.COM int i; 4177836SJohn.Forte@Sun.COM 4187836SJohn.Forte@Sun.COM for (i = 0; i < sizeof (stmfGuid); i++) { 4197836SJohn.Forte@Sun.COM if (g1->guid[i] > g2->guid[i]) 4207836SJohn.Forte@Sun.COM return (1); 4217836SJohn.Forte@Sun.COM if (g1->guid[i] < g2->guid[i]) 4227836SJohn.Forte@Sun.COM return (-1); 4237836SJohn.Forte@Sun.COM } 4247836SJohn.Forte@Sun.COM 4257836SJohn.Forte@Sun.COM return (0); 4267836SJohn.Forte@Sun.COM } 4277836SJohn.Forte@Sun.COM 4287836SJohn.Forte@Sun.COM /* 4297836SJohn.Forte@Sun.COM * stmfAddToHostGroup 4307836SJohn.Forte@Sun.COM * 4317836SJohn.Forte@Sun.COM * Purpose: Adds an initiator to an existing host group 4327836SJohn.Forte@Sun.COM * 4337836SJohn.Forte@Sun.COM * hostGroupName - name of an existing host group 4347836SJohn.Forte@Sun.COM * hostName - name of initiator to add 4357836SJohn.Forte@Sun.COM */ 4367836SJohn.Forte@Sun.COM int 4377836SJohn.Forte@Sun.COM stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 4387836SJohn.Forte@Sun.COM { 4397836SJohn.Forte@Sun.COM int ret; 4407836SJohn.Forte@Sun.COM int fd; 4417836SJohn.Forte@Sun.COM 4427836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 4437836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 4447836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 4457836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 4467836SJohn.Forte@Sun.COM } 4477836SJohn.Forte@Sun.COM 4487836SJohn.Forte@Sun.COM /* call init */ 4497836SJohn.Forte@Sun.COM ret = initializeConfig(); 4507836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 4517836SJohn.Forte@Sun.COM return (ret); 4527836SJohn.Forte@Sun.COM } 4537836SJohn.Forte@Sun.COM 4547836SJohn.Forte@Sun.COM /* 4557836SJohn.Forte@Sun.COM * Open control node for stmf 4567836SJohn.Forte@Sun.COM */ 4577836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 4587836SJohn.Forte@Sun.COM return (ret); 4597836SJohn.Forte@Sun.COM 4607836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName, 4617836SJohn.Forte@Sun.COM hostName)) != STMF_STATUS_SUCCESS) { 4627836SJohn.Forte@Sun.COM goto done; 4637836SJohn.Forte@Sun.COM } 4647836SJohn.Forte@Sun.COM 4659585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 4669585STim.Szeto@Sun.COM goto done; 4679585STim.Szeto@Sun.COM } 4689585STim.Szeto@Sun.COM 4697836SJohn.Forte@Sun.COM ret = psAddHostGroupMember((char *)hostGroupName, 4707836SJohn.Forte@Sun.COM (char *)hostName->ident); 4717836SJohn.Forte@Sun.COM switch (ret) { 4727836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 4737836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 4747836SJohn.Forte@Sun.COM break; 4757836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 4767836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 4777836SJohn.Forte@Sun.COM break; 4787836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 4797836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 4807836SJohn.Forte@Sun.COM break; 4817836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 4827836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 4837836SJohn.Forte@Sun.COM break; 4847836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 4857836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 4867836SJohn.Forte@Sun.COM break; 4877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 4887836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 4897836SJohn.Forte@Sun.COM break; 4907836SJohn.Forte@Sun.COM default: 4917836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 4927836SJohn.Forte@Sun.COM "stmfAddToHostGroup:psAddHostGroupMember:error(%d)", 4937836SJohn.Forte@Sun.COM ret); 4947836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 4957836SJohn.Forte@Sun.COM break; 4967836SJohn.Forte@Sun.COM } 4977836SJohn.Forte@Sun.COM 4987836SJohn.Forte@Sun.COM done: 4997836SJohn.Forte@Sun.COM (void) close(fd); 5007836SJohn.Forte@Sun.COM return (ret); 5017836SJohn.Forte@Sun.COM } 5027836SJohn.Forte@Sun.COM 5037836SJohn.Forte@Sun.COM /* 5047836SJohn.Forte@Sun.COM * stmfAddToTargetGroup 5057836SJohn.Forte@Sun.COM * 5067836SJohn.Forte@Sun.COM * Purpose: Adds a local port to an existing target group 5077836SJohn.Forte@Sun.COM * 5087836SJohn.Forte@Sun.COM * targetGroupName - name of an existing target group 5097836SJohn.Forte@Sun.COM * targetName - name of target to add 5107836SJohn.Forte@Sun.COM */ 5117836SJohn.Forte@Sun.COM int 5127836SJohn.Forte@Sun.COM stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 5137836SJohn.Forte@Sun.COM { 5147836SJohn.Forte@Sun.COM int ret; 5157836SJohn.Forte@Sun.COM int fd; 5167836SJohn.Forte@Sun.COM 5177836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 5187836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 5197836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 5207836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 5217836SJohn.Forte@Sun.COM } 5227836SJohn.Forte@Sun.COM 5237836SJohn.Forte@Sun.COM /* call init */ 5247836SJohn.Forte@Sun.COM ret = initializeConfig(); 5257836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 5267836SJohn.Forte@Sun.COM return (ret); 5277836SJohn.Forte@Sun.COM } 5287836SJohn.Forte@Sun.COM 5297836SJohn.Forte@Sun.COM /* 5307836SJohn.Forte@Sun.COM * Open control node for stmf 5317836SJohn.Forte@Sun.COM */ 5327836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 5337836SJohn.Forte@Sun.COM return (ret); 5347836SJohn.Forte@Sun.COM 5357836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 5367836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 5377836SJohn.Forte@Sun.COM goto done; 5387836SJohn.Forte@Sun.COM } 5397836SJohn.Forte@Sun.COM 5409585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 5419585STim.Szeto@Sun.COM goto done; 5429585STim.Szeto@Sun.COM } 5439585STim.Szeto@Sun.COM 5447836SJohn.Forte@Sun.COM ret = psAddTargetGroupMember((char *)targetGroupName, 5457836SJohn.Forte@Sun.COM (char *)targetName->ident); 5467836SJohn.Forte@Sun.COM switch (ret) { 5477836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 5487836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 5497836SJohn.Forte@Sun.COM break; 5507836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 5517836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 5527836SJohn.Forte@Sun.COM break; 5537836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 5547836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 5557836SJohn.Forte@Sun.COM break; 5567836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 5577836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 5587836SJohn.Forte@Sun.COM break; 5597836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 5607836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 5617836SJohn.Forte@Sun.COM break; 5627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 5637836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 5647836SJohn.Forte@Sun.COM break; 5657836SJohn.Forte@Sun.COM default: 5667836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 5677836SJohn.Forte@Sun.COM "stmfAddToTargetGroup:psAddTargetGroupMember:" 5687836SJohn.Forte@Sun.COM "error(%d)", ret); 5697836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 5707836SJohn.Forte@Sun.COM break; 5717836SJohn.Forte@Sun.COM } 5727836SJohn.Forte@Sun.COM 5737836SJohn.Forte@Sun.COM done: 5747836SJohn.Forte@Sun.COM (void) close(fd); 5757836SJohn.Forte@Sun.COM return (ret); 5767836SJohn.Forte@Sun.COM } 5777836SJohn.Forte@Sun.COM 5787836SJohn.Forte@Sun.COM /* 5797836SJohn.Forte@Sun.COM * addViewEntryIoctl 5807836SJohn.Forte@Sun.COM * 5817836SJohn.Forte@Sun.COM * Purpose: Issues ioctl to add a view entry 5827836SJohn.Forte@Sun.COM * 5837836SJohn.Forte@Sun.COM * lu - Logical Unit identifier to which the view entry is added 5847836SJohn.Forte@Sun.COM * viewEntry - view entry to add 5857836SJohn.Forte@Sun.COM * init - When set to B_TRUE, we are in the init state, i.e. don't call open 5867836SJohn.Forte@Sun.COM */ 5877836SJohn.Forte@Sun.COM static int 5887836SJohn.Forte@Sun.COM addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry) 5897836SJohn.Forte@Sun.COM { 5907836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 5917836SJohn.Forte@Sun.COM int ioctlRet; 5927836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 5937836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 5947836SJohn.Forte@Sun.COM 5957836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 5967836SJohn.Forte@Sun.COM /* 5977836SJohn.Forte@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 5987836SJohn.Forte@Sun.COM * false on input 5997836SJohn.Forte@Sun.COM */ 6007836SJohn.Forte@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 6017836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 6027836SJohn.Forte@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 6037836SJohn.Forte@Sun.COM 6047836SJohn.Forte@Sun.COM if (viewEntry->allHosts == B_FALSE) { 6057836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 6067836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6077836SJohn.Forte@Sun.COM ioctlViewEntry.ve_host_group.name_size = 6087836SJohn.Forte@Sun.COM strlen((char *)viewEntry->hostGroup); 6097836SJohn.Forte@Sun.COM } 6107836SJohn.Forte@Sun.COM if (viewEntry->allTargets == B_FALSE) { 6117836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, 6127836SJohn.Forte@Sun.COM &ioctlViewEntry.ve_target_group.name, 6137836SJohn.Forte@Sun.COM sizeof (stmfGroupName)); 6147836SJohn.Forte@Sun.COM ioctlViewEntry.ve_target_group.name_size = 6157836SJohn.Forte@Sun.COM strlen((char *)viewEntry->targetGroup); 6167836SJohn.Forte@Sun.COM } 6177836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 6187836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 6197836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 6207836SJohn.Forte@Sun.COM } 6217836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 6227836SJohn.Forte@Sun.COM 6237836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 6247836SJohn.Forte@Sun.COM /* 6257836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 6267836SJohn.Forte@Sun.COM */ 6277836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 6287836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 6297836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6307836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 6317836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 6327836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl); 6337836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 6347836SJohn.Forte@Sun.COM switch (errno) { 6357836SJohn.Forte@Sun.COM case EBUSY: 6367836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 6377836SJohn.Forte@Sun.COM break; 6389585STim.Szeto@Sun.COM case EPERM: 6399585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 6409585STim.Szeto@Sun.COM break; 6417836SJohn.Forte@Sun.COM case EACCES: 6427836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6437836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6447836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6457836SJohn.Forte@Sun.COM break; 6467836SJohn.Forte@Sun.COM default: 6477836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 6487836SJohn.Forte@Sun.COM break; 6497836SJohn.Forte@Sun.COM } 6507836SJohn.Forte@Sun.COM break; 6517836SJohn.Forte@Sun.COM default: 6527836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 6537836SJohn.Forte@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 6547836SJohn.Forte@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 6557836SJohn.Forte@Sun.COM break; 6567836SJohn.Forte@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 6577836SJohn.Forte@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 6587836SJohn.Forte@Sun.COM break; 6597836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 6607836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 6617836SJohn.Forte@Sun.COM break; 6627836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_HG: 6637836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_HG; 6647836SJohn.Forte@Sun.COM break; 6657836SJohn.Forte@Sun.COM case STMF_IOCERR_INVALID_TG: 6667836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_TG; 6677836SJohn.Forte@Sun.COM break; 6687836SJohn.Forte@Sun.COM default: 6697836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 6707836SJohn.Forte@Sun.COM "addViewEntryIoctl" 6717836SJohn.Forte@Sun.COM ":error(%d)", 6727836SJohn.Forte@Sun.COM stmfIoctl.stmf_error); 6737836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 6747836SJohn.Forte@Sun.COM break; 6757836SJohn.Forte@Sun.COM } 6767836SJohn.Forte@Sun.COM break; 6777836SJohn.Forte@Sun.COM } 6787836SJohn.Forte@Sun.COM goto done; 6797836SJohn.Forte@Sun.COM } 6807836SJohn.Forte@Sun.COM 6817836SJohn.Forte@Sun.COM /* copy lu nbr back to caller's view entry on success */ 6827836SJohn.Forte@Sun.COM viewEntry->veIndex = ioctlViewEntry.ve_ndx; 6837836SJohn.Forte@Sun.COM if (ioctlViewEntry.ve_lu_number_valid) { 6847836SJohn.Forte@Sun.COM bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 6857836SJohn.Forte@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 6867836SJohn.Forte@Sun.COM } 6877836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 6887836SJohn.Forte@Sun.COM 6897836SJohn.Forte@Sun.COM done: 6907836SJohn.Forte@Sun.COM return (ret); 6917836SJohn.Forte@Sun.COM } 6927836SJohn.Forte@Sun.COM 6937836SJohn.Forte@Sun.COM /* 6947836SJohn.Forte@Sun.COM * stmfAddViewEntry 6957836SJohn.Forte@Sun.COM * 6967836SJohn.Forte@Sun.COM * Purpose: Adds a view entry to a logical unit 6977836SJohn.Forte@Sun.COM * 6987836SJohn.Forte@Sun.COM * lu - guid of the logical unit to which the view entry is added 6997836SJohn.Forte@Sun.COM * viewEntry - view entry structure to add 7007836SJohn.Forte@Sun.COM */ 7017836SJohn.Forte@Sun.COM int 7027836SJohn.Forte@Sun.COM stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry) 7037836SJohn.Forte@Sun.COM { 7047836SJohn.Forte@Sun.COM int ret; 7057836SJohn.Forte@Sun.COM int fd; 7067836SJohn.Forte@Sun.COM stmfViewEntry iViewEntry; 7077836SJohn.Forte@Sun.COM 7087836SJohn.Forte@Sun.COM if (lu == NULL || viewEntry == NULL) { 7097836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 7107836SJohn.Forte@Sun.COM } 7117836SJohn.Forte@Sun.COM 7127836SJohn.Forte@Sun.COM /* initialize and set internal view entry */ 7137836SJohn.Forte@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 7147836SJohn.Forte@Sun.COM 7157836SJohn.Forte@Sun.COM if (!viewEntry->allHosts) { 7167836SJohn.Forte@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 7177836SJohn.Forte@Sun.COM sizeof (iViewEntry.hostGroup)); 7187836SJohn.Forte@Sun.COM } else { 7197836SJohn.Forte@Sun.COM iViewEntry.allHosts = B_TRUE; 7207836SJohn.Forte@Sun.COM } 7217836SJohn.Forte@Sun.COM 7227836SJohn.Forte@Sun.COM if (!viewEntry->allTargets) { 7237836SJohn.Forte@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 7247836SJohn.Forte@Sun.COM sizeof (iViewEntry.targetGroup)); 7257836SJohn.Forte@Sun.COM } else { 7267836SJohn.Forte@Sun.COM iViewEntry.allTargets = B_TRUE; 7277836SJohn.Forte@Sun.COM } 7287836SJohn.Forte@Sun.COM 7297836SJohn.Forte@Sun.COM if (viewEntry->luNbrValid) { 7307836SJohn.Forte@Sun.COM iViewEntry.luNbrValid = B_TRUE; 7317836SJohn.Forte@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 7327836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 7337836SJohn.Forte@Sun.COM } 7347836SJohn.Forte@Sun.COM 7357836SJohn.Forte@Sun.COM /* 7367836SJohn.Forte@Sun.COM * set users return view entry index valid flag to false 7377836SJohn.Forte@Sun.COM * in case of failure 7387836SJohn.Forte@Sun.COM */ 7397836SJohn.Forte@Sun.COM viewEntry->veIndexValid = B_FALSE; 7407836SJohn.Forte@Sun.COM 7417836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 7427836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 7437836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 7447836SJohn.Forte@Sun.COM } 7457836SJohn.Forte@Sun.COM 7467836SJohn.Forte@Sun.COM /* call init */ 7477836SJohn.Forte@Sun.COM ret = initializeConfig(); 7487836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7497836SJohn.Forte@Sun.COM return (ret); 7507836SJohn.Forte@Sun.COM } 7517836SJohn.Forte@Sun.COM 7527836SJohn.Forte@Sun.COM /* 7537836SJohn.Forte@Sun.COM * Open control node for stmf 7547836SJohn.Forte@Sun.COM */ 7557836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 7567836SJohn.Forte@Sun.COM return (ret); 7577836SJohn.Forte@Sun.COM 7587836SJohn.Forte@Sun.COM /* 7597836SJohn.Forte@Sun.COM * First add the view entry to the driver 7607836SJohn.Forte@Sun.COM */ 7617836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, lu, &iViewEntry); 7627836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 7637836SJohn.Forte@Sun.COM goto done; 7647836SJohn.Forte@Sun.COM } 7657836SJohn.Forte@Sun.COM 7669585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 7679585STim.Szeto@Sun.COM goto done; 7689585STim.Szeto@Sun.COM } 7699585STim.Szeto@Sun.COM 7707836SJohn.Forte@Sun.COM /* 7717836SJohn.Forte@Sun.COM * If the add to driver was successful, add it to the persistent 7727836SJohn.Forte@Sun.COM * store. 7737836SJohn.Forte@Sun.COM */ 7747836SJohn.Forte@Sun.COM ret = psAddViewEntry(lu, &iViewEntry); 7757836SJohn.Forte@Sun.COM switch (ret) { 7767836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 7777836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 7787836SJohn.Forte@Sun.COM break; 7797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 7807836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 7817836SJohn.Forte@Sun.COM break; 7827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 7837836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 7847836SJohn.Forte@Sun.COM break; 7857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 7867836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 7877836SJohn.Forte@Sun.COM break; 7887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 7897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 7907836SJohn.Forte@Sun.COM break; 7917836SJohn.Forte@Sun.COM default: 7927836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 7937836SJohn.Forte@Sun.COM "stmfAddViewEntry:psAddViewEntry:error(%d)", ret); 7947836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 7957836SJohn.Forte@Sun.COM break; 7967836SJohn.Forte@Sun.COM } 7977836SJohn.Forte@Sun.COM 7987836SJohn.Forte@Sun.COM done: 7997836SJohn.Forte@Sun.COM (void) close(fd); 8007836SJohn.Forte@Sun.COM 8017836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 8027836SJohn.Forte@Sun.COM /* set caller's view entry on success */ 8037836SJohn.Forte@Sun.COM viewEntry->veIndexValid = iViewEntry.veIndexValid; 8047836SJohn.Forte@Sun.COM viewEntry->veIndex = iViewEntry.veIndex; 8057836SJohn.Forte@Sun.COM viewEntry->luNbrValid = B_TRUE; 8067836SJohn.Forte@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 8077836SJohn.Forte@Sun.COM sizeof (iViewEntry.luNbr)); 8087836SJohn.Forte@Sun.COM } 8097836SJohn.Forte@Sun.COM return (ret); 8107836SJohn.Forte@Sun.COM } 8117836SJohn.Forte@Sun.COM 8127836SJohn.Forte@Sun.COM /* 8137836SJohn.Forte@Sun.COM * stmfClearProviderData 8147836SJohn.Forte@Sun.COM * 8157836SJohn.Forte@Sun.COM * Purpose: delete all provider data for specified provider 8167836SJohn.Forte@Sun.COM * 8177836SJohn.Forte@Sun.COM * providerName - name of provider for which data should be deleted 8187836SJohn.Forte@Sun.COM */ 8197836SJohn.Forte@Sun.COM int 8207836SJohn.Forte@Sun.COM stmfClearProviderData(char *providerName, int providerType) 8217836SJohn.Forte@Sun.COM { 8227836SJohn.Forte@Sun.COM int ret; 8237836SJohn.Forte@Sun.COM int fd; 8247836SJohn.Forte@Sun.COM int ioctlRet; 8257836SJohn.Forte@Sun.COM int savedErrno; 8267836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 8277836SJohn.Forte@Sun.COM stmf_ppioctl_data_t ppi; 8287836SJohn.Forte@Sun.COM 8297836SJohn.Forte@Sun.COM /* call init */ 8307836SJohn.Forte@Sun.COM ret = initializeConfig(); 8317836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 8327836SJohn.Forte@Sun.COM return (ret); 8337836SJohn.Forte@Sun.COM } 8347836SJohn.Forte@Sun.COM 8357836SJohn.Forte@Sun.COM if (providerName == NULL) { 8367836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8377836SJohn.Forte@Sun.COM } 8387836SJohn.Forte@Sun.COM 8397836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 8407836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 8417836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 8427836SJohn.Forte@Sun.COM } 8437836SJohn.Forte@Sun.COM 8447836SJohn.Forte@Sun.COM /* 8457836SJohn.Forte@Sun.COM * Open control node for stmf 8467836SJohn.Forte@Sun.COM */ 8477836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 8487836SJohn.Forte@Sun.COM return (ret); 8497836SJohn.Forte@Sun.COM 8507836SJohn.Forte@Sun.COM bzero(&ppi, sizeof (ppi)); 8517836SJohn.Forte@Sun.COM 8527836SJohn.Forte@Sun.COM (void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name)); 8537836SJohn.Forte@Sun.COM 8547836SJohn.Forte@Sun.COM switch (providerType) { 8557836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 8567836SJohn.Forte@Sun.COM ppi.ppi_lu_provider = 1; 8577836SJohn.Forte@Sun.COM break; 8587836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 8597836SJohn.Forte@Sun.COM ppi.ppi_port_provider = 1; 8607836SJohn.Forte@Sun.COM break; 8617836SJohn.Forte@Sun.COM default: 8627836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 8637836SJohn.Forte@Sun.COM goto done; 8647836SJohn.Forte@Sun.COM } 8657836SJohn.Forte@Sun.COM 8667836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 8677836SJohn.Forte@Sun.COM 8687836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 8697836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 8707836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 8717836SJohn.Forte@Sun.COM 8727836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl); 8737836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 8747836SJohn.Forte@Sun.COM savedErrno = errno; 8757836SJohn.Forte@Sun.COM switch (savedErrno) { 8767836SJohn.Forte@Sun.COM case EBUSY: 8777836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 8787836SJohn.Forte@Sun.COM break; 8799585STim.Szeto@Sun.COM case EPERM: 8807836SJohn.Forte@Sun.COM case EACCES: 8817836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 8827836SJohn.Forte@Sun.COM break; 8837836SJohn.Forte@Sun.COM default: 8847836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 8857836SJohn.Forte@Sun.COM "stmfClearProviderData:ioctl error(%d)", 8867836SJohn.Forte@Sun.COM ioctlRet); 8877836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 8887836SJohn.Forte@Sun.COM break; 8897836SJohn.Forte@Sun.COM } 8907836SJohn.Forte@Sun.COM if (savedErrno != ENOENT) { 8917836SJohn.Forte@Sun.COM goto done; 8927836SJohn.Forte@Sun.COM } 8937836SJohn.Forte@Sun.COM } 8947836SJohn.Forte@Sun.COM 8959585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 8969585STim.Szeto@Sun.COM goto done; 8979585STim.Szeto@Sun.COM } 8989585STim.Szeto@Sun.COM 8997836SJohn.Forte@Sun.COM ret = psClearProviderData(providerName, providerType); 9007836SJohn.Forte@Sun.COM switch (ret) { 9017836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 9027836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 9037836SJohn.Forte@Sun.COM break; 9047836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 9057836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 9067836SJohn.Forte@Sun.COM break; 9077836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 9087836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9097836SJohn.Forte@Sun.COM break; 9107836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 9117836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 9127836SJohn.Forte@Sun.COM break; 9137836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 9147836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 9157836SJohn.Forte@Sun.COM break; 9167836SJohn.Forte@Sun.COM default: 9177836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9187836SJohn.Forte@Sun.COM "stmfClearProviderData:psClearProviderData" 9197836SJohn.Forte@Sun.COM ":error(%d)", ret); 9207836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9217836SJohn.Forte@Sun.COM break; 9227836SJohn.Forte@Sun.COM } 9237836SJohn.Forte@Sun.COM 9247836SJohn.Forte@Sun.COM done: 9257836SJohn.Forte@Sun.COM (void) close(fd); 9267836SJohn.Forte@Sun.COM return (ret); 9277836SJohn.Forte@Sun.COM } 9287836SJohn.Forte@Sun.COM 9297836SJohn.Forte@Sun.COM /* 9307836SJohn.Forte@Sun.COM * stmfCreateHostGroup 9317836SJohn.Forte@Sun.COM * 9327836SJohn.Forte@Sun.COM * Purpose: Create a new initiator group 9337836SJohn.Forte@Sun.COM * 9347836SJohn.Forte@Sun.COM * hostGroupName - name of host group to create 9357836SJohn.Forte@Sun.COM */ 9367836SJohn.Forte@Sun.COM int 9377836SJohn.Forte@Sun.COM stmfCreateHostGroup(stmfGroupName *hostGroupName) 9387836SJohn.Forte@Sun.COM { 9397836SJohn.Forte@Sun.COM int ret; 9407836SJohn.Forte@Sun.COM int fd; 9417836SJohn.Forte@Sun.COM 9427836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 9437836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 9447836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 9457836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 9467836SJohn.Forte@Sun.COM } 9477836SJohn.Forte@Sun.COM 9487836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 9497836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 9507836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 9517836SJohn.Forte@Sun.COM } 9527836SJohn.Forte@Sun.COM 9537836SJohn.Forte@Sun.COM /* call init */ 9547836SJohn.Forte@Sun.COM ret = initializeConfig(); 9557836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 9567836SJohn.Forte@Sun.COM return (ret); 9577836SJohn.Forte@Sun.COM } 9587836SJohn.Forte@Sun.COM 9597836SJohn.Forte@Sun.COM /* 9607836SJohn.Forte@Sun.COM * Open control node for stmf 9617836SJohn.Forte@Sun.COM */ 9627836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 9637836SJohn.Forte@Sun.COM return (ret); 9647836SJohn.Forte@Sun.COM 9657836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 9667836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 9677836SJohn.Forte@Sun.COM goto done; 9687836SJohn.Forte@Sun.COM } 9697836SJohn.Forte@Sun.COM 9709585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 9719585STim.Szeto@Sun.COM goto done; 9729585STim.Szeto@Sun.COM } 9739585STim.Szeto@Sun.COM 9747836SJohn.Forte@Sun.COM ret = psCreateHostGroup((char *)hostGroupName); 9757836SJohn.Forte@Sun.COM switch (ret) { 9767836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 9777836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 9787836SJohn.Forte@Sun.COM break; 9797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 9807836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 9817836SJohn.Forte@Sun.COM break; 9827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 9837836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 9847836SJohn.Forte@Sun.COM break; 9857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 9867836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 9877836SJohn.Forte@Sun.COM break; 9887836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 9897836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 9907836SJohn.Forte@Sun.COM break; 9917836SJohn.Forte@Sun.COM default: 9927836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 9937836SJohn.Forte@Sun.COM "stmfCreateHostGroup:psCreateHostGroup:error(%d)", 9947836SJohn.Forte@Sun.COM ret); 9957836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 9967836SJohn.Forte@Sun.COM break; 9977836SJohn.Forte@Sun.COM } 9987836SJohn.Forte@Sun.COM 9997836SJohn.Forte@Sun.COM done: 10007836SJohn.Forte@Sun.COM (void) close(fd); 10017836SJohn.Forte@Sun.COM return (ret); 10027836SJohn.Forte@Sun.COM } 10037836SJohn.Forte@Sun.COM 10047836SJohn.Forte@Sun.COM /* 10059585STim.Szeto@Sun.COM * stmfCreateLu 10069585STim.Szeto@Sun.COM * 10079585STim.Szeto@Sun.COM * Purpose: Create a logical unit 10089585STim.Szeto@Sun.COM * 10099585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 10109585STim.Szeto@Sun.COM * 10119585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 10129585STim.Szeto@Sun.COM * unit 10139585STim.Szeto@Sun.COM */ 10149585STim.Szeto@Sun.COM int 10159585STim.Szeto@Sun.COM stmfCreateLu(luResource hdl, stmfGuid *luGuid) 10169585STim.Szeto@Sun.COM { 10179585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10189585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 10199585STim.Szeto@Sun.COM 10209585STim.Szeto@Sun.COM if (hdl == NULL) { 10219585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10229585STim.Szeto@Sun.COM } 10239585STim.Szeto@Sun.COM 10249585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 10259585STim.Szeto@Sun.COM ret = createDiskLu((diskResource *)luPropsHdl->resource, 10269585STim.Szeto@Sun.COM luGuid); 10279585STim.Szeto@Sun.COM } else { 10289585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10299585STim.Szeto@Sun.COM } 10309585STim.Szeto@Sun.COM 10319585STim.Szeto@Sun.COM return (ret); 10329585STim.Szeto@Sun.COM } 10339585STim.Szeto@Sun.COM 10349585STim.Szeto@Sun.COM /* 10359585STim.Szeto@Sun.COM * stmfCreateLuResource 10369585STim.Szeto@Sun.COM * 10379585STim.Szeto@Sun.COM * Purpose: Create resource handle for a logical unit 10389585STim.Szeto@Sun.COM * 10399585STim.Szeto@Sun.COM * dType - Type of logical unit resource to create 10409585STim.Szeto@Sun.COM * Can be: STMF_DISK 10419585STim.Szeto@Sun.COM * 10429585STim.Szeto@Sun.COM * hdl - pointer to luResource 10439585STim.Szeto@Sun.COM */ 10449585STim.Szeto@Sun.COM int 10459585STim.Szeto@Sun.COM stmfCreateLuResource(uint16_t dType, luResource *hdl) 10469585STim.Szeto@Sun.COM { 10479585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10489585STim.Szeto@Sun.COM 10499585STim.Szeto@Sun.COM if (dType != STMF_DISK || hdl == NULL) { 10509585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 10519585STim.Szeto@Sun.COM } 10529585STim.Szeto@Sun.COM 10539585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 10549585STim.Szeto@Sun.COM if (*hdl == NULL) { 10559585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 10569585STim.Szeto@Sun.COM } 10579585STim.Szeto@Sun.COM 10589585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 10599585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 10609585STim.Szeto@Sun.COM free(*hdl); 10619585STim.Szeto@Sun.COM return (ret); 10629585STim.Szeto@Sun.COM } 10639585STim.Szeto@Sun.COM 10649585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 10659585STim.Szeto@Sun.COM } 10669585STim.Szeto@Sun.COM 10679585STim.Szeto@Sun.COM /* 10689585STim.Szeto@Sun.COM * Creates a disk logical unit 10699585STim.Szeto@Sun.COM * 10709585STim.Szeto@Sun.COM * disk - pointer to diskResource structure that represents the properties 10719585STim.Szeto@Sun.COM * for the disk logical unit to be created. 10729585STim.Szeto@Sun.COM */ 10739585STim.Szeto@Sun.COM static int 10749585STim.Szeto@Sun.COM createDiskLu(diskResource *disk, stmfGuid *createdGuid) 10759585STim.Szeto@Sun.COM { 10769585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 10779585STim.Szeto@Sun.COM int dataFileNameLen = 0; 10789585STim.Szeto@Sun.COM int metaFileNameLen = 0; 10799585STim.Szeto@Sun.COM int serialNumLen = 0; 10809585STim.Szeto@Sun.COM int luAliasLen = 0; 10819585STim.Szeto@Sun.COM int sluBufSize = 0; 10829585STim.Szeto@Sun.COM int bufOffset = 0; 10839585STim.Szeto@Sun.COM int fd = 0; 10849585STim.Szeto@Sun.COM int ioctlRet; 10859585STim.Szeto@Sun.COM int savedErrno; 10869585STim.Szeto@Sun.COM stmfGuid guid; 10879585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 10889585STim.Szeto@Sun.COM 10899585STim.Szeto@Sun.COM sbd_create_and_reg_lu_t *sbdLu = NULL; 10909585STim.Szeto@Sun.COM 10919585STim.Szeto@Sun.COM /* 10929585STim.Szeto@Sun.COM * Open control node for sbd 10939585STim.Szeto@Sun.COM */ 10949585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 10959585STim.Szeto@Sun.COM return (ret); 10969585STim.Szeto@Sun.COM 10979585STim.Szeto@Sun.COM /* data file name must be specified */ 10989585STim.Szeto@Sun.COM if (disk->luDataFileNameValid) { 10999585STim.Szeto@Sun.COM dataFileNameLen = strlen(disk->luDataFileName); 11009585STim.Szeto@Sun.COM } else { 11019585STim.Szeto@Sun.COM (void) close(fd); 11029585STim.Szeto@Sun.COM return (STMF_ERROR_MISSING_PROP_VAL); 11039585STim.Szeto@Sun.COM } 11049585STim.Szeto@Sun.COM 11059585STim.Szeto@Sun.COM sluBufSize += dataFileNameLen + 1; 11069585STim.Szeto@Sun.COM 11079585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 11089585STim.Szeto@Sun.COM metaFileNameLen = strlen(disk->luMetaFileName); 11099585STim.Szeto@Sun.COM sluBufSize += metaFileNameLen + 1; 11109585STim.Szeto@Sun.COM } 11119585STim.Szeto@Sun.COM 11129585STim.Szeto@Sun.COM serialNumLen = strlen(disk->serialNum); 11139585STim.Szeto@Sun.COM sluBufSize += serialNumLen; 11149585STim.Szeto@Sun.COM 11159585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11169585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 11179585STim.Szeto@Sun.COM sluBufSize += luAliasLen + 1; 11189585STim.Szeto@Sun.COM } 11199585STim.Szeto@Sun.COM 11209585STim.Szeto@Sun.COM /* 11219585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 11229585STim.Szeto@Sun.COM * concatenation of variable length fields 11239585STim.Szeto@Sun.COM */ 11249585STim.Szeto@Sun.COM sbdLu = (sbd_create_and_reg_lu_t *)calloc(1, 11259585STim.Szeto@Sun.COM sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8); 11269585STim.Szeto@Sun.COM if (sbdLu == NULL) { 11279585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 11289585STim.Szeto@Sun.COM } 11299585STim.Szeto@Sun.COM 11309585STim.Szeto@Sun.COM sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) + 11319585STim.Szeto@Sun.COM sluBufSize - 8; 11329585STim.Szeto@Sun.COM 11339585STim.Szeto@Sun.COM if (metaFileNameLen) { 11349585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_valid = 1; 11359585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_off = bufOffset; 11369585STim.Szeto@Sun.COM bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]), 11379585STim.Szeto@Sun.COM metaFileNameLen + 1); 11389585STim.Szeto@Sun.COM bufOffset += metaFileNameLen + 1; 11399585STim.Szeto@Sun.COM } 11409585STim.Szeto@Sun.COM 11419585STim.Szeto@Sun.COM bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]), 11429585STim.Szeto@Sun.COM dataFileNameLen + 1); 11439585STim.Szeto@Sun.COM sbdLu->slu_data_fname_off = bufOffset; 11449585STim.Szeto@Sun.COM bufOffset += dataFileNameLen + 1; 11459585STim.Szeto@Sun.COM 11469585STim.Szeto@Sun.COM /* currently, serial # is not passed null terminated to the driver */ 11479585STim.Szeto@Sun.COM if (disk->serialNumValid) { 11489585STim.Szeto@Sun.COM sbdLu->slu_serial_valid = 1; 11499585STim.Szeto@Sun.COM sbdLu->slu_serial_off = bufOffset; 11509585STim.Szeto@Sun.COM sbdLu->slu_serial_size = serialNumLen; 11519585STim.Szeto@Sun.COM bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]), 11529585STim.Szeto@Sun.COM serialNumLen); 11539585STim.Szeto@Sun.COM bufOffset += serialNumLen; 11549585STim.Szeto@Sun.COM } 11559585STim.Szeto@Sun.COM 11569585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11579585STim.Szeto@Sun.COM sbdLu->slu_alias_valid = 1; 11589585STim.Szeto@Sun.COM sbdLu->slu_alias_off = bufOffset; 11599585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]), 11609585STim.Szeto@Sun.COM luAliasLen + 1); 11619585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 11629585STim.Szeto@Sun.COM } 11639585STim.Szeto@Sun.COM 11649585STim.Szeto@Sun.COM if (disk->luSizeValid) { 11659585STim.Szeto@Sun.COM sbdLu->slu_lu_size_valid = 1; 11669585STim.Szeto@Sun.COM sbdLu->slu_lu_size = disk->luSize; 11679585STim.Szeto@Sun.COM } 11689585STim.Szeto@Sun.COM 11699585STim.Szeto@Sun.COM if (disk->luGuidValid) { 11709585STim.Szeto@Sun.COM sbdLu->slu_guid_valid = 1; 11719585STim.Szeto@Sun.COM bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid)); 11729585STim.Szeto@Sun.COM } 11739585STim.Szeto@Sun.COM 11749585STim.Szeto@Sun.COM if (disk->vidValid) { 11759585STim.Szeto@Sun.COM sbdLu->slu_vid_valid = 1; 11769585STim.Szeto@Sun.COM bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid)); 11779585STim.Szeto@Sun.COM } 11789585STim.Szeto@Sun.COM 11799585STim.Szeto@Sun.COM if (disk->pidValid) { 11809585STim.Szeto@Sun.COM sbdLu->slu_pid_valid = 1; 11819585STim.Szeto@Sun.COM bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid)); 11829585STim.Szeto@Sun.COM } 11839585STim.Szeto@Sun.COM 11849585STim.Szeto@Sun.COM if (disk->revValid) { 11859585STim.Szeto@Sun.COM sbdLu->slu_rev_valid = 1; 11869585STim.Szeto@Sun.COM bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev)); 11879585STim.Szeto@Sun.COM } 11889585STim.Szeto@Sun.COM 11899585STim.Szeto@Sun.COM if (disk->companyIdValid) { 11909585STim.Szeto@Sun.COM sbdLu->slu_company_id_valid = 1; 11919585STim.Szeto@Sun.COM sbdLu->slu_company_id = disk->companyId; 11929585STim.Szeto@Sun.COM } 11939585STim.Szeto@Sun.COM 11949585STim.Szeto@Sun.COM if (disk->blkSizeValid) { 11959585STim.Szeto@Sun.COM sbdLu->slu_blksize_valid = 1; 11969585STim.Szeto@Sun.COM sbdLu->slu_blksize = disk->blkSize; 11979585STim.Szeto@Sun.COM } 11989585STim.Szeto@Sun.COM 11999585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 12009585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 12019585STim.Szeto@Sun.COM sbdLu->slu_write_protected = 1; 12029585STim.Szeto@Sun.COM } 12039585STim.Szeto@Sun.COM } 12049585STim.Szeto@Sun.COM 12059585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 12069585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable_valid = 1; 12079585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 12089585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable = 1; 12099585STim.Szeto@Sun.COM } 12109585STim.Szeto@Sun.COM } 12119585STim.Szeto@Sun.COM 12129585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 12139585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size; 12149585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 12159585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size; 12169585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 12179585STim.Szeto@Sun.COM 12189585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl); 12199585STim.Szeto@Sun.COM if (ioctlRet != 0) { 12209585STim.Szeto@Sun.COM savedErrno = errno; 12219585STim.Szeto@Sun.COM switch (savedErrno) { 12229585STim.Szeto@Sun.COM case EBUSY: 12239585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 12249585STim.Szeto@Sun.COM break; 12259585STim.Szeto@Sun.COM case EPERM: 12269585STim.Szeto@Sun.COM case EACCES: 12279585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 12289585STim.Szeto@Sun.COM break; 12299585STim.Szeto@Sun.COM default: 12309585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 12319585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 12329585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 12339585STim.Szeto@Sun.COM "createDiskLu:ioctl " 12349585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 12359585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 12369585STim.Szeto@Sun.COM } 12379585STim.Szeto@Sun.COM break; 12389585STim.Szeto@Sun.COM } 12399585STim.Szeto@Sun.COM } 12409585STim.Szeto@Sun.COM 12419585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 12429585STim.Szeto@Sun.COM goto done; 12439585STim.Szeto@Sun.COM } 12449585STim.Szeto@Sun.COM 12459585STim.Szeto@Sun.COM /* 12469585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 12479585STim.Szeto@Sun.COM * NULL 12489585STim.Szeto@Sun.COM */ 12499585STim.Szeto@Sun.COM if (createdGuid) { 12509585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, createdGuid->guid, 12519585STim.Szeto@Sun.COM sizeof (sbdLu->slu_guid)); 12529585STim.Szeto@Sun.COM } 12539585STim.Szeto@Sun.COM 12549585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid)); 12559585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 12569585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luMetaFileName); 12579585STim.Szeto@Sun.COM } else { 12589585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luDataFileName); 12599585STim.Szeto@Sun.COM } 12609585STim.Szeto@Sun.COM done: 12619585STim.Szeto@Sun.COM free(sbdLu); 12629585STim.Szeto@Sun.COM (void) close(fd); 12639585STim.Szeto@Sun.COM return (ret); 12649585STim.Szeto@Sun.COM } 12659585STim.Szeto@Sun.COM 12669585STim.Szeto@Sun.COM 12679585STim.Szeto@Sun.COM /* 12689585STim.Szeto@Sun.COM * stmfImportLu 12699585STim.Szeto@Sun.COM * 12709585STim.Szeto@Sun.COM * Purpose: Import a previously created logical unit 12719585STim.Szeto@Sun.COM * 12729585STim.Szeto@Sun.COM * dType - Type of logical unit 12739585STim.Szeto@Sun.COM * Can be: STMF_DISK 12749585STim.Szeto@Sun.COM * 12759585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the imported logical 12769585STim.Szeto@Sun.COM * unit 12779585STim.Szeto@Sun.COM * 12789585STim.Szeto@Sun.COM * fname - A file name where the metadata resides 12799585STim.Szeto@Sun.COM * 12809585STim.Szeto@Sun.COM */ 12819585STim.Szeto@Sun.COM int 12829585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid) 12839585STim.Szeto@Sun.COM { 12849585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 12859585STim.Szeto@Sun.COM 12869585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 12879585STim.Szeto@Sun.COM ret = importDiskLu(fname, luGuid); 12889585STim.Szeto@Sun.COM } else { 12899585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 12909585STim.Szeto@Sun.COM } 12919585STim.Szeto@Sun.COM 12929585STim.Szeto@Sun.COM return (ret); 12939585STim.Szeto@Sun.COM } 12949585STim.Szeto@Sun.COM 12959585STim.Szeto@Sun.COM /* 12969585STim.Szeto@Sun.COM * importDiskLu 12979585STim.Szeto@Sun.COM * 12989585STim.Szeto@Sun.COM * filename - filename to import 12999585STim.Szeto@Sun.COM * createdGuid - if not NULL, on success contains the imported guid 13009585STim.Szeto@Sun.COM * 13019585STim.Szeto@Sun.COM */ 13029585STim.Szeto@Sun.COM static int 13039585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid) 13049585STim.Szeto@Sun.COM { 13059585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 13069585STim.Szeto@Sun.COM int fd = 0; 13079585STim.Szeto@Sun.COM int ioctlRet; 13089585STim.Szeto@Sun.COM int savedErrno; 13099585STim.Szeto@Sun.COM int metaFileNameLen; 13109585STim.Szeto@Sun.COM stmfGuid iGuid; 13119585STim.Szeto@Sun.COM int iluBufSize = 0; 13129585STim.Szeto@Sun.COM sbd_import_lu_t *sbdLu = NULL; 13139585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 13149585STim.Szeto@Sun.COM 13159585STim.Szeto@Sun.COM if (fname == NULL) { 13169585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13179585STim.Szeto@Sun.COM } 13189585STim.Szeto@Sun.COM 13199585STim.Szeto@Sun.COM /* 13209585STim.Szeto@Sun.COM * Open control node for sbd 13219585STim.Szeto@Sun.COM */ 13229585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 13239585STim.Szeto@Sun.COM return (ret); 13249585STim.Szeto@Sun.COM 13259585STim.Szeto@Sun.COM metaFileNameLen = strlen(fname); 13269585STim.Szeto@Sun.COM iluBufSize += metaFileNameLen + 1; 13279585STim.Szeto@Sun.COM 13289585STim.Szeto@Sun.COM /* 13299585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 13309585STim.Szeto@Sun.COM * concatenation of variable length fields 13319585STim.Szeto@Sun.COM */ 13329585STim.Szeto@Sun.COM sbdLu = (sbd_import_lu_t *)calloc(1, 13339585STim.Szeto@Sun.COM sizeof (sbd_import_lu_t) + iluBufSize - 8); 13349585STim.Szeto@Sun.COM if (sbdLu == NULL) { 13359585STim.Szeto@Sun.COM (void) close(fd); 13369585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 13379585STim.Szeto@Sun.COM } 13389585STim.Szeto@Sun.COM 13399585STim.Szeto@Sun.COM /* 13409585STim.Szeto@Sun.COM * Accept either a data file or meta data file. 13419585STim.Szeto@Sun.COM * sbd will do the right thing here either way. 13429585STim.Szeto@Sun.COM * i.e. if it's a data file, it assumes that the 13439585STim.Szeto@Sun.COM * meta data is shared with the data. 13449585STim.Szeto@Sun.COM */ 13459585STim.Szeto@Sun.COM (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen); 13469585STim.Szeto@Sun.COM 13479585STim.Szeto@Sun.COM sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8; 13489585STim.Szeto@Sun.COM 13499585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 13509585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size; 13519585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 13529585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size; 13539585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 13549585STim.Szeto@Sun.COM 13559585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl); 13569585STim.Szeto@Sun.COM if (ioctlRet != 0) { 13579585STim.Szeto@Sun.COM savedErrno = errno; 13589585STim.Szeto@Sun.COM switch (savedErrno) { 13599585STim.Szeto@Sun.COM case EBUSY: 13609585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 13619585STim.Szeto@Sun.COM break; 13629585STim.Szeto@Sun.COM case EPERM: 13639585STim.Szeto@Sun.COM case EACCES: 13649585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 13659585STim.Szeto@Sun.COM break; 13669585STim.Szeto@Sun.COM default: 13679585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 13689585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 13699585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 13709585STim.Szeto@Sun.COM "importDiskLu:ioctl " 13719585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 13729585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 13739585STim.Szeto@Sun.COM } 13749585STim.Szeto@Sun.COM break; 13759585STim.Szeto@Sun.COM } 13769585STim.Szeto@Sun.COM } 13779585STim.Szeto@Sun.COM 13789585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 13799585STim.Szeto@Sun.COM goto done; 13809585STim.Szeto@Sun.COM } 13819585STim.Szeto@Sun.COM 13829585STim.Szeto@Sun.COM /* 13839585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 13849585STim.Szeto@Sun.COM * NULL and add it to the persistent store for sbd 13859585STim.Szeto@Sun.COM */ 13869585STim.Szeto@Sun.COM if (createdGuid) { 13879585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, createdGuid->guid, 13889585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 13899585STim.Szeto@Sun.COM ret = addGuidToDiskStore(createdGuid, fname); 13909585STim.Szeto@Sun.COM } else { 13919585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, iGuid.guid, 13929585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 13939585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&iGuid, fname); 13949585STim.Szeto@Sun.COM } 13959585STim.Szeto@Sun.COM done: 13969585STim.Szeto@Sun.COM free(sbdLu); 13979585STim.Szeto@Sun.COM (void) close(fd); 13989585STim.Szeto@Sun.COM return (ret); 13999585STim.Szeto@Sun.COM } 14009585STim.Szeto@Sun.COM 14019585STim.Szeto@Sun.COM /* 14029585STim.Szeto@Sun.COM * diskError 14039585STim.Szeto@Sun.COM * 14049585STim.Szeto@Sun.COM * Purpose: Translate sbd driver error 14059585STim.Szeto@Sun.COM */ 14069585STim.Szeto@Sun.COM static void 14079585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret) 14089585STim.Szeto@Sun.COM { 14099585STim.Szeto@Sun.COM switch (stmfError) { 14109585STim.Szeto@Sun.COM case SBD_RET_META_CREATION_FAILED: 14119585STim.Szeto@Sun.COM case SBD_RET_ZFS_META_CREATE_FAILED: 14129585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_CREATION; 14139585STim.Szeto@Sun.COM break; 14149585STim.Szeto@Sun.COM case SBD_RET_INVALID_BLKSIZE: 14159585STim.Szeto@Sun.COM *ret = STMF_ERROR_INVALID_BLKSIZE; 14169585STim.Szeto@Sun.COM break; 14179585STim.Szeto@Sun.COM case SBD_RET_FILE_ALREADY_REGISTERED: 14189585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_IN_USE; 14199585STim.Szeto@Sun.COM break; 14209585STim.Szeto@Sun.COM case SBD_RET_GUID_ALREADY_REGISTERED: 14219585STim.Szeto@Sun.COM *ret = STMF_ERROR_GUID_IN_USE; 14229585STim.Szeto@Sun.COM break; 14239585STim.Szeto@Sun.COM case SBD_RET_META_PATH_NOT_ABSOLUTE: 14249585STim.Szeto@Sun.COM case SBD_RET_META_FILE_LOOKUP_FAILED: 14259585STim.Szeto@Sun.COM case SBD_RET_META_FILE_OPEN_FAILED: 14269585STim.Szeto@Sun.COM case SBD_RET_META_FILE_GETATTR_FAILED: 14279585STim.Szeto@Sun.COM case SBD_RET_NO_META: 14289585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_FILE_NAME; 14299585STim.Szeto@Sun.COM break; 14309585STim.Szeto@Sun.COM case SBD_RET_DATA_PATH_NOT_ABSOLUTE: 14319585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_LOOKUP_FAILED: 14329585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_OPEN_FAILED: 14339585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_GETATTR_FAILED: 14349585STim.Szeto@Sun.COM *ret = STMF_ERROR_DATA_FILE_NAME; 14359585STim.Szeto@Sun.COM break; 14369585STim.Szeto@Sun.COM case SBD_RET_FILE_SIZE_ERROR: 14379585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_SIZE_INVALID; 14389585STim.Szeto@Sun.COM break; 14399585STim.Szeto@Sun.COM case SBD_RET_SIZE_OUT_OF_RANGE: 14409585STim.Szeto@Sun.COM *ret = STMF_ERROR_SIZE_OUT_OF_RANGE; 14419585STim.Szeto@Sun.COM break; 14429585STim.Szeto@Sun.COM case SBD_RET_LU_BUSY: 14439585STim.Szeto@Sun.COM *ret = STMF_ERROR_LU_BUSY; 14449585STim.Szeto@Sun.COM break; 14459585STim.Szeto@Sun.COM case SBD_RET_WRITE_CACHE_SET_FAILED: 14469585STim.Szeto@Sun.COM *ret = STMF_ERROR_WRITE_CACHE_SET; 14479585STim.Szeto@Sun.COM break; 14489585STim.Szeto@Sun.COM default: 14499585STim.Szeto@Sun.COM *ret = STMF_STATUS_ERROR; 14509585STim.Szeto@Sun.COM break; 14519585STim.Szeto@Sun.COM } 14529585STim.Szeto@Sun.COM } 14539585STim.Szeto@Sun.COM 14549585STim.Szeto@Sun.COM /* 14559585STim.Szeto@Sun.COM * Creates a logical unit resource of type STMF_DISK. 14569585STim.Szeto@Sun.COM * 14579585STim.Szeto@Sun.COM * No defaults should be set here as all defaults are derived from the 14589585STim.Szeto@Sun.COM * driver's default settings. 14599585STim.Szeto@Sun.COM */ 14609585STim.Szeto@Sun.COM static int 14619585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl) 14629585STim.Szeto@Sun.COM { 14639585STim.Szeto@Sun.COM hdl->type = STMF_DISK; 14649585STim.Szeto@Sun.COM 14659585STim.Szeto@Sun.COM hdl->resource = calloc(1, sizeof (diskResource)); 14669585STim.Szeto@Sun.COM if (hdl->resource == NULL) { 14679585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 14689585STim.Szeto@Sun.COM } 14699585STim.Szeto@Sun.COM 14709585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 14719585STim.Szeto@Sun.COM } 14729585STim.Szeto@Sun.COM 14739585STim.Szeto@Sun.COM /* 14749585STim.Szeto@Sun.COM * stmfDeleteLu 14759585STim.Szeto@Sun.COM * 14769585STim.Szeto@Sun.COM * Purpose: Delete a logical unit 14779585STim.Szeto@Sun.COM * 14789585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 14799585STim.Szeto@Sun.COM * 14809585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 14819585STim.Szeto@Sun.COM * unit 14829585STim.Szeto@Sun.COM */ 14839585STim.Szeto@Sun.COM int 14849585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid) 14859585STim.Szeto@Sun.COM { 14869585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 14879585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 14889585STim.Szeto@Sun.COM 14899585STim.Szeto@Sun.COM if (luGuid == NULL) { 14909585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 14919585STim.Szeto@Sun.COM } 14929585STim.Szeto@Sun.COM 14939585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 14949585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 14959585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 14969585STim.Szeto@Sun.COM return (ret); 14979585STim.Szeto@Sun.COM } else { 14989585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 14999585STim.Szeto@Sun.COM ret = deleteDiskLu(luGuid); 15009585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 15019585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 15029585STim.Szeto@Sun.COM } else { 15039585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15049585STim.Szeto@Sun.COM } 15059585STim.Szeto@Sun.COM } 15069585STim.Szeto@Sun.COM 15079585STim.Szeto@Sun.COM return (ret); 15089585STim.Szeto@Sun.COM } 15099585STim.Szeto@Sun.COM 15109585STim.Szeto@Sun.COM static int 15119585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid) 15129585STim.Szeto@Sun.COM { 15139585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15149585STim.Szeto@Sun.COM int fd; 15159585STim.Szeto@Sun.COM int savedErrno; 15169585STim.Szeto@Sun.COM int ioctlRet; 15179585STim.Szeto@Sun.COM sbd_delete_lu_t deleteLu = {0}; 15189585STim.Szeto@Sun.COM 15199585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 15209585STim.Szeto@Sun.COM 15219585STim.Szeto@Sun.COM /* 15229585STim.Szeto@Sun.COM * Open control node for sbd 15239585STim.Szeto@Sun.COM */ 15249585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 15259585STim.Szeto@Sun.COM return (ret); 15269585STim.Szeto@Sun.COM 15279585STim.Szeto@Sun.COM ret = removeGuidFromDiskStore(luGuid); 15289585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 15299585STim.Szeto@Sun.COM goto done; 15309585STim.Szeto@Sun.COM } 15319585STim.Szeto@Sun.COM 15329585STim.Szeto@Sun.COM bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid)); 15339585STim.Szeto@Sun.COM deleteLu.dlu_by_guid = 1; 15349585STim.Szeto@Sun.COM 15359585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 15369585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (deleteLu); 15379585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu; 15389585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl); 15399585STim.Szeto@Sun.COM if (ioctlRet != 0) { 15409585STim.Szeto@Sun.COM savedErrno = errno; 15419585STim.Szeto@Sun.COM switch (savedErrno) { 15429585STim.Szeto@Sun.COM case EBUSY: 15439585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 15449585STim.Szeto@Sun.COM break; 15459585STim.Szeto@Sun.COM case EPERM: 15469585STim.Szeto@Sun.COM case EACCES: 15479585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 15489585STim.Szeto@Sun.COM break; 15499585STim.Szeto@Sun.COM case ENOENT: 15509585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 15519585STim.Szeto@Sun.COM break; 15529585STim.Szeto@Sun.COM default: 15539585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 15549585STim.Szeto@Sun.COM "deleteDiskLu:ioctl error(%d) (%d) (%d)", 15559585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 15569585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 15579585STim.Szeto@Sun.COM break; 15589585STim.Szeto@Sun.COM } 15599585STim.Szeto@Sun.COM } 15609585STim.Szeto@Sun.COM 15619585STim.Szeto@Sun.COM done: 15629585STim.Szeto@Sun.COM (void) close(fd); 15639585STim.Szeto@Sun.COM return (ret); 15649585STim.Szeto@Sun.COM } 15659585STim.Szeto@Sun.COM 15669585STim.Szeto@Sun.COM /* 15679585STim.Szeto@Sun.COM * stmfModifyLu 15689585STim.Szeto@Sun.COM * 15699585STim.Szeto@Sun.COM * Purpose: Modify properties of a logical unit 15709585STim.Szeto@Sun.COM * 15719585STim.Szeto@Sun.COM * luGuid - guid of registered logical unit 15729585STim.Szeto@Sun.COM * prop - property to modify 15739585STim.Szeto@Sun.COM * propVal - property value to set 15749585STim.Szeto@Sun.COM * 15759585STim.Szeto@Sun.COM */ 15769585STim.Szeto@Sun.COM int 15779585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal) 15789585STim.Szeto@Sun.COM { 15799585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15809585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 15819585STim.Szeto@Sun.COM 15829585STim.Szeto@Sun.COM if (luGuid == NULL) { 15839585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15849585STim.Szeto@Sun.COM } 15859585STim.Szeto@Sun.COM 15869585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 15879585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 15889585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 15899585STim.Szeto@Sun.COM return (ret); 15909585STim.Szeto@Sun.COM } else { 15919585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 15929585STim.Szeto@Sun.COM ret = modifyDiskLuProp(luGuid, NULL, prop, propVal); 15939585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 15949585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 15959585STim.Szeto@Sun.COM } else { 15969585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15979585STim.Szeto@Sun.COM } 15989585STim.Szeto@Sun.COM } 15999585STim.Szeto@Sun.COM 16009585STim.Szeto@Sun.COM return (ret); 16019585STim.Szeto@Sun.COM } 16029585STim.Szeto@Sun.COM 16039585STim.Szeto@Sun.COM /* 16049585STim.Szeto@Sun.COM * stmfModifyLuByFname 16059585STim.Szeto@Sun.COM * 16069585STim.Szeto@Sun.COM * Purpose: Modify a device by filename. Device does not need to be registered. 16079585STim.Szeto@Sun.COM * 16089585STim.Szeto@Sun.COM * dType - type of device to modify 16099585STim.Szeto@Sun.COM * STMF_DISK 16109585STim.Szeto@Sun.COM * 16119585STim.Szeto@Sun.COM * fname - filename or meta filename 16129585STim.Szeto@Sun.COM * prop - valid property identifier 16139585STim.Szeto@Sun.COM * propVal - property value 16149585STim.Szeto@Sun.COM * 16159585STim.Szeto@Sun.COM */ 16169585STim.Szeto@Sun.COM int 16179585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop, 16189585STim.Szeto@Sun.COM const char *propVal) 16199585STim.Szeto@Sun.COM { 16209585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 16219585STim.Szeto@Sun.COM if (fname == NULL) { 16229585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 16239585STim.Szeto@Sun.COM } 16249585STim.Szeto@Sun.COM 16259585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 16269585STim.Szeto@Sun.COM ret = modifyDiskLuProp(NULL, fname, prop, propVal); 16279585STim.Szeto@Sun.COM } else { 16289585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 16299585STim.Szeto@Sun.COM } 16309585STim.Szeto@Sun.COM 16319585STim.Szeto@Sun.COM return (ret); 16329585STim.Szeto@Sun.COM } 16339585STim.Szeto@Sun.COM 16349585STim.Szeto@Sun.COM static int 16359585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop, 16369585STim.Szeto@Sun.COM const char *propVal) 16379585STim.Szeto@Sun.COM { 16389585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 16399585STim.Szeto@Sun.COM luResource hdl = NULL; 16409585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl; 16419585STim.Szeto@Sun.COM 16429585STim.Szeto@Sun.COM ret = stmfCreateLuResource(STMF_DISK, &hdl); 16439585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 16449585STim.Szeto@Sun.COM return (ret); 16459585STim.Szeto@Sun.COM } 16469585STim.Szeto@Sun.COM ret = validateModifyDiskProp(prop); 16479585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 16489585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 16499585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROP); 16509585STim.Szeto@Sun.COM } 16519585STim.Szeto@Sun.COM ret = stmfSetLuProp(hdl, prop, propVal); 16529585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 16539585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 16549585STim.Szeto@Sun.COM return (ret); 16559585STim.Szeto@Sun.COM } 16569585STim.Szeto@Sun.COM luPropsHdl = hdl; 16579585STim.Szeto@Sun.COM ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname); 16589585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 16599585STim.Szeto@Sun.COM return (ret); 16609585STim.Szeto@Sun.COM } 16619585STim.Szeto@Sun.COM 16629585STim.Szeto@Sun.COM static int 16639585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop) 16649585STim.Szeto@Sun.COM { 16659585STim.Szeto@Sun.COM switch (prop) { 16669585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 16679585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 16689585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 16699585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 16709585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 16719585STim.Szeto@Sun.COM break; 16729585STim.Szeto@Sun.COM default: 16739585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 16749585STim.Szeto@Sun.COM break; 16759585STim.Szeto@Sun.COM } 16769585STim.Szeto@Sun.COM } 16779585STim.Szeto@Sun.COM 16789585STim.Szeto@Sun.COM static int 16799585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname) 16809585STim.Szeto@Sun.COM { 16819585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 16829585STim.Szeto@Sun.COM int luAliasLen = 0; 16839585STim.Szeto@Sun.COM int mluBufSize = 0; 16849585STim.Szeto@Sun.COM int bufOffset = 0; 16859585STim.Szeto@Sun.COM int fd = 0; 16869585STim.Szeto@Sun.COM int ioctlRet; 16879585STim.Szeto@Sun.COM int savedErrno; 16889585STim.Szeto@Sun.COM int fnameSize = 0; 16899585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 16909585STim.Szeto@Sun.COM 16919585STim.Szeto@Sun.COM sbd_modify_lu_t *sbdLu = NULL; 16929585STim.Szeto@Sun.COM 16939585STim.Szeto@Sun.COM if (luGuid == NULL && fname == NULL) { 16949585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 16959585STim.Szeto@Sun.COM } 16969585STim.Szeto@Sun.COM 16979585STim.Szeto@Sun.COM if (fname) { 16989585STim.Szeto@Sun.COM fnameSize = strlen(fname) + 1; 16999585STim.Szeto@Sun.COM mluBufSize += fnameSize; 17009585STim.Szeto@Sun.COM } 17019585STim.Szeto@Sun.COM 17029585STim.Szeto@Sun.COM /* 17039585STim.Szeto@Sun.COM * Open control node for sbd 17049585STim.Szeto@Sun.COM */ 17059585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 17069585STim.Szeto@Sun.COM return (ret); 17079585STim.Szeto@Sun.COM 17089585STim.Szeto@Sun.COM if (disk->luAliasValid) { 17099585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 17109585STim.Szeto@Sun.COM mluBufSize += luAliasLen + 1; 17119585STim.Szeto@Sun.COM } 17129585STim.Szeto@Sun.COM 17139585STim.Szeto@Sun.COM /* 17149585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 17159585STim.Szeto@Sun.COM * concatenation of variable length fields 17169585STim.Szeto@Sun.COM */ 17179585STim.Szeto@Sun.COM sbdLu = (sbd_modify_lu_t *)calloc(1, 17189585STim.Szeto@Sun.COM sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize); 17199585STim.Szeto@Sun.COM if (sbdLu == NULL) { 17209585STim.Szeto@Sun.COM (void) close(fd); 17219585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 17229585STim.Szeto@Sun.COM } 17239585STim.Szeto@Sun.COM 17249585STim.Szeto@Sun.COM sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) + 17259585STim.Szeto@Sun.COM mluBufSize - 8 + fnameSize; 17269585STim.Szeto@Sun.COM 17279585STim.Szeto@Sun.COM if (disk->luAliasValid) { 17289585STim.Szeto@Sun.COM sbdLu->mlu_alias_valid = 1; 17299585STim.Szeto@Sun.COM sbdLu->mlu_alias_off = bufOffset; 17309585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]), 17319585STim.Szeto@Sun.COM luAliasLen + 1); 17329585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 17339585STim.Szeto@Sun.COM } 17349585STim.Szeto@Sun.COM 17359585STim.Szeto@Sun.COM if (disk->luSizeValid) { 17369585STim.Szeto@Sun.COM sbdLu->mlu_lu_size_valid = 1; 17379585STim.Szeto@Sun.COM sbdLu->mlu_lu_size = disk->luSize; 17389585STim.Szeto@Sun.COM } 17399585STim.Szeto@Sun.COM 17409585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 17419585STim.Szeto@Sun.COM sbdLu->mlu_write_protected_valid = 1; 17429585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 17439585STim.Szeto@Sun.COM sbdLu->mlu_write_protected = 1; 17449585STim.Szeto@Sun.COM } 17459585STim.Szeto@Sun.COM } 17469585STim.Szeto@Sun.COM 17479585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 17489585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable_valid = 1; 17499585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 17509585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable = 1; 17519585STim.Szeto@Sun.COM } 17529585STim.Szeto@Sun.COM } 17539585STim.Szeto@Sun.COM 17549585STim.Szeto@Sun.COM if (luGuid) { 17559585STim.Szeto@Sun.COM bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid)); 17569585STim.Szeto@Sun.COM sbdLu->mlu_by_guid = 1; 17579585STim.Szeto@Sun.COM } else { 17589585STim.Szeto@Sun.COM sbdLu->mlu_fname_off = bufOffset; 17599585STim.Szeto@Sun.COM bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1); 17609585STim.Szeto@Sun.COM sbdLu->mlu_by_fname = 1; 17619585STim.Szeto@Sun.COM } 17629585STim.Szeto@Sun.COM 17639585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 17649585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size; 17659585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 17669585STim.Szeto@Sun.COM 17679585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl); 17689585STim.Szeto@Sun.COM if (ioctlRet != 0) { 17699585STim.Szeto@Sun.COM savedErrno = errno; 17709585STim.Szeto@Sun.COM switch (savedErrno) { 17719585STim.Szeto@Sun.COM case EBUSY: 17729585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 17739585STim.Szeto@Sun.COM break; 17749585STim.Szeto@Sun.COM case EPERM: 17759585STim.Szeto@Sun.COM case EACCES: 17769585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 17779585STim.Szeto@Sun.COM break; 17789585STim.Szeto@Sun.COM default: 17799585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 17809585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 17819585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 17829585STim.Szeto@Sun.COM "modifyDiskLu:ioctl " 17839585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 17849585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 17859585STim.Szeto@Sun.COM } 17869585STim.Szeto@Sun.COM break; 17879585STim.Szeto@Sun.COM } 17889585STim.Szeto@Sun.COM } 17899585STim.Szeto@Sun.COM 17909585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 17919585STim.Szeto@Sun.COM goto done; 17929585STim.Szeto@Sun.COM } 17939585STim.Szeto@Sun.COM 17949585STim.Szeto@Sun.COM done: 17959585STim.Szeto@Sun.COM free(sbdLu); 17969585STim.Szeto@Sun.COM (void) close(fd); 17979585STim.Szeto@Sun.COM return (ret); 17989585STim.Szeto@Sun.COM } 17999585STim.Szeto@Sun.COM 18009585STim.Szeto@Sun.COM /* 18019585STim.Szeto@Sun.COM * removeGuidFromDiskStore 18029585STim.Szeto@Sun.COM * 18039585STim.Szeto@Sun.COM * Purpose: delete a logical unit from the sbd provider data 18049585STim.Szeto@Sun.COM */ 18059585STim.Szeto@Sun.COM static int 18069585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid) 18079585STim.Szeto@Sun.COM { 18089585STim.Szeto@Sun.COM return (persistDiskGuid(guid, NULL, B_FALSE)); 18099585STim.Szeto@Sun.COM } 18109585STim.Szeto@Sun.COM 18119585STim.Szeto@Sun.COM 18129585STim.Szeto@Sun.COM /* 18139585STim.Szeto@Sun.COM * addGuidToDiskStore 18149585STim.Szeto@Sun.COM * 18159585STim.Szeto@Sun.COM * Purpose: add a logical unit to the sbd provider data 18169585STim.Szeto@Sun.COM */ 18179585STim.Szeto@Sun.COM static int 18189585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename) 18199585STim.Szeto@Sun.COM { 18209585STim.Szeto@Sun.COM return (persistDiskGuid(guid, filename, B_TRUE)); 18219585STim.Szeto@Sun.COM } 18229585STim.Szeto@Sun.COM 18239585STim.Szeto@Sun.COM 18249585STim.Szeto@Sun.COM /* 18259585STim.Szeto@Sun.COM * persistDiskGuid 18269585STim.Szeto@Sun.COM * 18279585STim.Szeto@Sun.COM * Purpose: Persist or unpersist a guid for the sbd provider data 18289585STim.Szeto@Sun.COM * 18299585STim.Szeto@Sun.COM */ 18309585STim.Szeto@Sun.COM static int 18319585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist) 18329585STim.Szeto@Sun.COM { 18339585STim.Szeto@Sun.COM char guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0}; 18349585STim.Szeto@Sun.COM nvlist_t *nvl = NULL; 18359585STim.Szeto@Sun.COM 18369585STim.Szeto@Sun.COM uint64_t setToken; 18379585STim.Szeto@Sun.COM boolean_t retryGetProviderData = B_FALSE; 18389585STim.Szeto@Sun.COM boolean_t newData = B_FALSE; 18399585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 18409585STim.Szeto@Sun.COM int retryCnt = 0; 18419585STim.Szeto@Sun.COM int stmfRet; 18429585STim.Szeto@Sun.COM 18439585STim.Szeto@Sun.COM /* if we're persisting a guid, there must be a filename */ 18449585STim.Szeto@Sun.COM if (persist && !filename) { 18459585STim.Szeto@Sun.COM return (1); 18469585STim.Szeto@Sun.COM } 18479585STim.Szeto@Sun.COM 18489585STim.Szeto@Sun.COM /* guid is stored in lowercase ascii hex */ 18499585STim.Szeto@Sun.COM (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 18509585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" 18519585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x", 18529585STim.Szeto@Sun.COM guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3], 18539585STim.Szeto@Sun.COM guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7], 18549585STim.Szeto@Sun.COM guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11], 18559585STim.Szeto@Sun.COM guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]); 18569585STim.Szeto@Sun.COM 18579585STim.Szeto@Sun.COM 18589585STim.Szeto@Sun.COM do { 18599585STim.Szeto@Sun.COM retryGetProviderData = B_FALSE; 18609585STim.Szeto@Sun.COM stmfRet = stmfGetProviderDataProt("sbd", &nvl, 18619585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 18629585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 18639585STim.Szeto@Sun.COM if (persist && stmfRet == STMF_ERROR_NOT_FOUND) { 18649585STim.Szeto@Sun.COM ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); 18659585STim.Szeto@Sun.COM if (ret != 0) { 18669585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 18679585STim.Szeto@Sun.COM "unpersistGuid:nvlist_alloc(%d)", 18689585STim.Szeto@Sun.COM ret); 18699585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 18709585STim.Szeto@Sun.COM goto done; 18719585STim.Szeto@Sun.COM } 18729585STim.Szeto@Sun.COM newData = B_TRUE; 18739585STim.Szeto@Sun.COM } else { 18749585STim.Szeto@Sun.COM ret = stmfRet; 18759585STim.Szeto@Sun.COM goto done; 18769585STim.Szeto@Sun.COM } 18779585STim.Szeto@Sun.COM } 18789585STim.Szeto@Sun.COM if (persist) { 18799585STim.Szeto@Sun.COM ret = nvlist_add_string(nvl, guidAsciiBuf, filename); 18809585STim.Szeto@Sun.COM } else { 18819585STim.Szeto@Sun.COM ret = nvlist_remove(nvl, guidAsciiBuf, 18829585STim.Szeto@Sun.COM DATA_TYPE_STRING); 18839585STim.Szeto@Sun.COM if (ret == ENOENT) { 18849585STim.Szeto@Sun.COM ret = 0; 18859585STim.Szeto@Sun.COM } 18869585STim.Szeto@Sun.COM } 18879585STim.Szeto@Sun.COM if (ret == 0) { 18889585STim.Szeto@Sun.COM if (newData) { 18899585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 18909585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, NULL); 18919585STim.Szeto@Sun.COM } else { 18929585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 18939585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 18949585STim.Szeto@Sun.COM } 18959585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 18969585STim.Szeto@Sun.COM if (stmfRet == STMF_ERROR_BUSY) { 18979585STim.Szeto@Sun.COM /* get/set failed, try again */ 18989585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 18999585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 19009585STim.Szeto@Sun.COM ret = stmfRet; 19019585STim.Szeto@Sun.COM break; 19029585STim.Szeto@Sun.COM } 19039585STim.Szeto@Sun.COM continue; 19049585STim.Szeto@Sun.COM } else if (stmfRet == 19059585STim.Szeto@Sun.COM STMF_ERROR_PROV_DATA_STALE) { 19069585STim.Szeto@Sun.COM /* update failed, try again */ 19079585STim.Szeto@Sun.COM nvlist_free(nvl); 19089585STim.Szeto@Sun.COM nvl = NULL; 19099585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 19109585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 19119585STim.Szeto@Sun.COM ret = stmfRet; 19129585STim.Szeto@Sun.COM break; 19139585STim.Szeto@Sun.COM } 19149585STim.Szeto@Sun.COM continue; 19159585STim.Szeto@Sun.COM } else { 19169585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 19179585STim.Szeto@Sun.COM "unpersistGuid:error(%x)", stmfRet); 19189585STim.Szeto@Sun.COM ret = stmfRet; 19199585STim.Szeto@Sun.COM } 19209585STim.Szeto@Sun.COM break; 19219585STim.Szeto@Sun.COM } 19229585STim.Szeto@Sun.COM } else { 19239585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 19249585STim.Szeto@Sun.COM "unpersistGuid:error nvlist_add/remove(%d)", 19259585STim.Szeto@Sun.COM ret); 19269585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 19279585STim.Szeto@Sun.COM } 19289585STim.Szeto@Sun.COM } while (retryGetProviderData); 19299585STim.Szeto@Sun.COM 19309585STim.Szeto@Sun.COM done: 19319585STim.Szeto@Sun.COM nvlist_free(nvl); 19329585STim.Szeto@Sun.COM return (ret); 19339585STim.Szeto@Sun.COM } 19349585STim.Szeto@Sun.COM 19359585STim.Szeto@Sun.COM 19369585STim.Szeto@Sun.COM /* 19379585STim.Szeto@Sun.COM * stmfGetLuProp 19389585STim.Szeto@Sun.COM * 19399585STim.Szeto@Sun.COM * Purpose: Get current value for a resource property 19409585STim.Szeto@Sun.COM * 19419585STim.Szeto@Sun.COM * hdl - luResource from a previous call to stmfCreateLuResource 19429585STim.Szeto@Sun.COM * 19439585STim.Szeto@Sun.COM * resourceProp - a valid resource property type 19449585STim.Szeto@Sun.COM * 19459585STim.Szeto@Sun.COM * propVal - void pointer to a pointer of the value to be retrieved 19469585STim.Szeto@Sun.COM */ 19479585STim.Szeto@Sun.COM int 19489585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen) 19499585STim.Szeto@Sun.COM { 19509585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 19519585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 19529585STim.Szeto@Sun.COM if (hdl == NULL || propLen == NULL || propVal == NULL) { 19539585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 19549585STim.Szeto@Sun.COM } 19559585STim.Szeto@Sun.COM 19569585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 19579585STim.Szeto@Sun.COM ret = getDiskProp(luPropsHdl, prop, propVal, propLen); 19589585STim.Szeto@Sun.COM } else { 19599585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 19609585STim.Szeto@Sun.COM } 19619585STim.Szeto@Sun.COM 19629585STim.Szeto@Sun.COM return (ret); 19639585STim.Szeto@Sun.COM } 19649585STim.Szeto@Sun.COM 19659585STim.Szeto@Sun.COM /* 19669585STim.Szeto@Sun.COM * stmfGetLuResource 19679585STim.Szeto@Sun.COM * 19689585STim.Szeto@Sun.COM * Purpose: Get a logical unit resource handle for a given logical unit. 19699585STim.Szeto@Sun.COM * 19709585STim.Szeto@Sun.COM * hdl - pointer to luResource 19719585STim.Szeto@Sun.COM */ 19729585STim.Szeto@Sun.COM int 19739585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl) 19749585STim.Szeto@Sun.COM { 19759585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 19769585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 19779585STim.Szeto@Sun.COM 19789585STim.Szeto@Sun.COM 19799585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 19809585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 19819585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 19829585STim.Szeto@Sun.COM return (ret); 19839585STim.Szeto@Sun.COM } else { 19849585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 19859585STim.Szeto@Sun.COM ret = getDiskAllProps(luGuid, hdl); 19869585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 19879585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 19889585STim.Szeto@Sun.COM } else { 19899585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 19909585STim.Szeto@Sun.COM } 19919585STim.Szeto@Sun.COM } 19929585STim.Szeto@Sun.COM 19939585STim.Szeto@Sun.COM return (ret); 19949585STim.Szeto@Sun.COM } 19959585STim.Szeto@Sun.COM 19969585STim.Szeto@Sun.COM /* 19979585STim.Szeto@Sun.COM * getDiskAllProps 19989585STim.Szeto@Sun.COM * 19999585STim.Szeto@Sun.COM * Purpose: load all disk properties from sbd driver 20009585STim.Szeto@Sun.COM * 20019585STim.Szeto@Sun.COM * luGuid - guid of disk device for which properties are to be retrieved 20029585STim.Szeto@Sun.COM * hdl - allocated luResource into which properties are to be copied 20039585STim.Szeto@Sun.COM * 20049585STim.Szeto@Sun.COM */ 20059585STim.Szeto@Sun.COM static int 20069585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl) 20079585STim.Szeto@Sun.COM { 20089585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 20099585STim.Szeto@Sun.COM int fd; 20109585STim.Szeto@Sun.COM sbd_lu_props_t *sbdProps; 20119585STim.Szeto@Sun.COM int ioctlRet; 20129585STim.Szeto@Sun.COM int savedErrno; 20139585STim.Szeto@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 20149585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 20159585STim.Szeto@Sun.COM 20169585STim.Szeto@Sun.COM /* 20179585STim.Szeto@Sun.COM * Open control node for sbd 20189585STim.Szeto@Sun.COM */ 20199585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 20209585STim.Szeto@Sun.COM return (ret); 20219585STim.Szeto@Sun.COM 20229585STim.Szeto@Sun.COM 20239585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 20249585STim.Szeto@Sun.COM if (*hdl == NULL) { 20259585STim.Szeto@Sun.COM (void) close(fd); 20269585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 20279585STim.Szeto@Sun.COM } 20289585STim.Szeto@Sun.COM 20299585STim.Szeto@Sun.COM sbdProps = calloc(1, sbdPropsSize); 20309585STim.Szeto@Sun.COM if (sbdProps == NULL) { 20319585STim.Szeto@Sun.COM free(*hdl); 20329585STim.Szeto@Sun.COM (void) close(fd); 20339585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 20349585STim.Szeto@Sun.COM } 20359585STim.Szeto@Sun.COM 20369585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 20379585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 20389585STim.Szeto@Sun.COM free(*hdl); 20399585STim.Szeto@Sun.COM (void) close(fd); 20409585STim.Szeto@Sun.COM return (ret); 20419585STim.Szeto@Sun.COM } 20429585STim.Szeto@Sun.COM 20439585STim.Szeto@Sun.COM sbdProps->slp_input_guid = 1; 20449585STim.Szeto@Sun.COM bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid)); 20459585STim.Szeto@Sun.COM 20469585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 20479585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdPropsSize; 20489585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps; 20499585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 20509585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 20519585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl); 20529585STim.Szeto@Sun.COM if (ioctlRet != 0) { 20539585STim.Szeto@Sun.COM savedErrno = errno; 20549585STim.Szeto@Sun.COM switch (savedErrno) { 20559585STim.Szeto@Sun.COM case EBUSY: 20569585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 20579585STim.Szeto@Sun.COM break; 20589585STim.Szeto@Sun.COM case EPERM: 20599585STim.Szeto@Sun.COM case EACCES: 20609585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 20619585STim.Szeto@Sun.COM break; 20629585STim.Szeto@Sun.COM case ENOENT: 20639585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 20649585STim.Szeto@Sun.COM break; 20659585STim.Szeto@Sun.COM default: 20669585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20679585STim.Szeto@Sun.COM "getDiskAllProps:ioctl error(%d) (%d) (%d)", 20689585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 20699585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 20709585STim.Szeto@Sun.COM break; 20719585STim.Szeto@Sun.COM } 20729585STim.Szeto@Sun.COM } 20739585STim.Szeto@Sun.COM 20749585STim.Szeto@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 20759585STim.Szeto@Sun.COM ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps); 20769585STim.Szeto@Sun.COM } 20779585STim.Szeto@Sun.COM 20789585STim.Szeto@Sun.COM (void) close(fd); 20799585STim.Szeto@Sun.COM return (ret); 20809585STim.Szeto@Sun.COM } 20819585STim.Szeto@Sun.COM 20829585STim.Szeto@Sun.COM /* 20839585STim.Szeto@Sun.COM * loadDiskPropsFromDriver 20849585STim.Szeto@Sun.COM * 20859585STim.Szeto@Sun.COM * Purpose: Retrieve all disk type properties from sbd driver 20869585STim.Szeto@Sun.COM * 20879585STim.Szeto@Sun.COM * hdl - Allocated luResourceImpl 20889585STim.Szeto@Sun.COM * sbdProps - sbd_lu_props_t structure returned from sbd driver 20899585STim.Szeto@Sun.COM * 20909585STim.Szeto@Sun.COM */ 20919585STim.Szeto@Sun.COM static int 20929585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps) 20939585STim.Szeto@Sun.COM { 20949585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 20959585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 20969585STim.Szeto@Sun.COM /* copy guid */ 20979585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 20989585STim.Szeto@Sun.COM bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid)); 20999585STim.Szeto@Sun.COM 21009585STim.Szeto@Sun.COM if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) { 21019585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 21029585STim.Szeto@Sun.COM if (strlcpy(diskLu->luMetaFileName, 21039585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]), 21049585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) >= 21059585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 21069585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21079585STim.Szeto@Sun.COM } 21089585STim.Szeto@Sun.COM } 21099585STim.Szeto@Sun.COM 21109585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 21119585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 21129585STim.Szeto@Sun.COM if (strlcpy(diskLu->luDataFileName, 21139585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]), 21149585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) >= 21159585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 21169585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21179585STim.Szeto@Sun.COM } 21189585STim.Szeto@Sun.COM } 21199585STim.Szeto@Sun.COM 21209585STim.Szeto@Sun.COM if (sbdProps->slp_serial_valid) { 21219585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 21229585STim.Szeto@Sun.COM bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]), 21239585STim.Szeto@Sun.COM diskLu->serialNum, sbdProps->slp_serial_size); 21249585STim.Szeto@Sun.COM } 21259585STim.Szeto@Sun.COM 21269585STim.Szeto@Sun.COM if (sbdProps->slp_alias_valid) { 21279585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 21289585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 21299585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]), 21309585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 21319585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 21329585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21339585STim.Szeto@Sun.COM } 21349585STim.Szeto@Sun.COM } else { /* set alias to data filename if not set */ 21359585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 21369585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 21379585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 21389585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[ 21399585STim.Szeto@Sun.COM sbdProps->slp_data_fname_off]), 21409585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 21419585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 21429585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21439585STim.Szeto@Sun.COM } 21449585STim.Szeto@Sun.COM } 21459585STim.Szeto@Sun.COM } 21469585STim.Szeto@Sun.COM 21479585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 21489585STim.Szeto@Sun.COM bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid)); 21499585STim.Szeto@Sun.COM 21509585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 21519585STim.Szeto@Sun.COM bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid)); 21529585STim.Szeto@Sun.COM 21539585STim.Szeto@Sun.COM diskLu->revValid = B_TRUE; 21549585STim.Szeto@Sun.COM bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev)); 21559585STim.Szeto@Sun.COM 21569585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 21579585STim.Szeto@Sun.COM if (sbdProps->slp_write_protected) { 21589585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 21599585STim.Szeto@Sun.COM } 21609585STim.Szeto@Sun.COM 21619585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 21629585STim.Szeto@Sun.COM if (sbdProps->slp_writeback_cache_disable_cur) { 21639585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 21649585STim.Szeto@Sun.COM } 21659585STim.Szeto@Sun.COM 21669585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 21679585STim.Szeto@Sun.COM diskLu->blkSize = sbdProps->slp_blksize; 21689585STim.Szeto@Sun.COM 21699585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 21709585STim.Szeto@Sun.COM diskLu->luSize = sbdProps->slp_lu_size; 21719585STim.Szeto@Sun.COM 21729585STim.Szeto@Sun.COM return (ret); 21739585STim.Szeto@Sun.COM } 21749585STim.Szeto@Sun.COM 21759585STim.Szeto@Sun.COM 21769585STim.Szeto@Sun.COM /* 21779585STim.Szeto@Sun.COM * stmfSetLuProp 21789585STim.Szeto@Sun.COM * 21799585STim.Szeto@Sun.COM * Purpose: set a property on an luResource 21809585STim.Szeto@Sun.COM * 21819585STim.Szeto@Sun.COM * hdl - allocated luResource 21829585STim.Szeto@Sun.COM * prop - property identifier 21839585STim.Szeto@Sun.COM * propVal - property value to be set 21849585STim.Szeto@Sun.COM */ 21859585STim.Szeto@Sun.COM int 21869585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal) 21879585STim.Szeto@Sun.COM { 21889585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21899585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 21909585STim.Szeto@Sun.COM if (hdl == NULL) { 21919585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21929585STim.Szeto@Sun.COM } 21939585STim.Szeto@Sun.COM 21949585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 21959585STim.Szeto@Sun.COM ret = setDiskProp(luPropsHdl, prop, propVal); 21969585STim.Szeto@Sun.COM } else { 21979585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 21989585STim.Szeto@Sun.COM } 21999585STim.Szeto@Sun.COM 22009585STim.Szeto@Sun.COM return (ret); 22019585STim.Szeto@Sun.COM } 22029585STim.Szeto@Sun.COM 22039585STim.Szeto@Sun.COM /* 22049585STim.Szeto@Sun.COM * getDiskProp 22059585STim.Szeto@Sun.COM * 22069585STim.Szeto@Sun.COM * Purpose: retrieve a given property from a logical unit resource of type disk 22079585STim.Szeto@Sun.COM * 22089585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 22099585STim.Szeto@Sun.COM * prop - property identifier 22109585STim.Szeto@Sun.COM * propVal - pointer to character to contain the retrieved property value 22119585STim.Szeto@Sun.COM * propLen - On input this is the length of propVal. On failure, it contains the 22129585STim.Szeto@Sun.COM * number of bytes required for propVal 22139585STim.Szeto@Sun.COM */ 22149585STim.Szeto@Sun.COM static int 22159585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen) 22169585STim.Szeto@Sun.COM { 22179585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 22189585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 22199585STim.Szeto@Sun.COM size_t reqLen; 22209585STim.Szeto@Sun.COM 22219585STim.Szeto@Sun.COM switch (prop) { 22229585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 22239585STim.Szeto@Sun.COM if (diskLu->blkSizeValid == B_FALSE) { 22249585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22259585STim.Szeto@Sun.COM } 22269585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, "%llu", 22279585STim.Szeto@Sun.COM (u_longlong_t)diskLu->blkSize); 22289585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 22299585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22309585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22319585STim.Szeto@Sun.COM } 22329585STim.Szeto@Sun.COM break; 22339585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 22349585STim.Szeto@Sun.COM if (diskLu->luDataFileNameValid == B_FALSE) { 22359585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22369585STim.Szeto@Sun.COM } 22379585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luDataFileName, 22389585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 22399585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22409585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22419585STim.Szeto@Sun.COM } 22429585STim.Szeto@Sun.COM break; 22439585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 22449585STim.Szeto@Sun.COM if (diskLu->luMetaFileNameValid == B_FALSE) { 22459585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22469585STim.Szeto@Sun.COM } 22479585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName, 22489585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 22499585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22509585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22519585STim.Szeto@Sun.COM } 22529585STim.Szeto@Sun.COM break; 22539585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 22549585STim.Szeto@Sun.COM if (diskLu->luGuidValid == B_FALSE) { 22559585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22569585STim.Szeto@Sun.COM } 22579585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, 22589585STim.Szeto@Sun.COM "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 22599585STim.Szeto@Sun.COM "%02X%02X%02X%02X", 22609585STim.Szeto@Sun.COM diskLu->luGuid[0], diskLu->luGuid[1], 22619585STim.Szeto@Sun.COM diskLu->luGuid[2], diskLu->luGuid[3], 22629585STim.Szeto@Sun.COM diskLu->luGuid[4], diskLu->luGuid[5], 22639585STim.Szeto@Sun.COM diskLu->luGuid[6], diskLu->luGuid[7], 22649585STim.Szeto@Sun.COM diskLu->luGuid[8], diskLu->luGuid[9], 22659585STim.Szeto@Sun.COM diskLu->luGuid[10], diskLu->luGuid[11], 22669585STim.Szeto@Sun.COM diskLu->luGuid[12], diskLu->luGuid[13], 22679585STim.Szeto@Sun.COM diskLu->luGuid[14], diskLu->luGuid[15]); 22689585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 22699585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22709585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22719585STim.Szeto@Sun.COM } 22729585STim.Szeto@Sun.COM break; 22739585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 22749585STim.Szeto@Sun.COM if (diskLu->serialNumValid == B_FALSE) { 22759585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22769585STim.Szeto@Sun.COM } 22779585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->serialNum, 22789585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 22799585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22809585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22819585STim.Szeto@Sun.COM } 22829585STim.Szeto@Sun.COM break; 22839585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 22849585STim.Szeto@Sun.COM if (diskLu->luSizeValid == B_FALSE) { 22859585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22869585STim.Szeto@Sun.COM } 22879585STim.Szeto@Sun.COM (void) snprintf(propVal, *propLen, "%llu", 22889585STim.Szeto@Sun.COM (u_longlong_t)diskLu->luSize); 22899585STim.Szeto@Sun.COM break; 22909585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 22919585STim.Szeto@Sun.COM if (diskLu->luAliasValid == B_FALSE) { 22929585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22939585STim.Szeto@Sun.COM } 22949585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luAlias, 22959585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 22969585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22979585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22989585STim.Szeto@Sun.COM } 22999585STim.Szeto@Sun.COM break; 23009585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 23019585STim.Szeto@Sun.COM if (diskLu->vidValid == B_FALSE) { 23029585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23039585STim.Szeto@Sun.COM } 23049585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->vid)) { 23059585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23069585STim.Szeto@Sun.COM } 23079585STim.Szeto@Sun.COM bcopy(diskLu->vid, propVal, sizeof (diskLu->vid)); 23089585STim.Szeto@Sun.COM propVal[sizeof (diskLu->vid)] = 0; 23099585STim.Szeto@Sun.COM break; 23109585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 23119585STim.Szeto@Sun.COM if (diskLu->pidValid == B_FALSE) { 23129585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23139585STim.Szeto@Sun.COM } 23149585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->pid)) { 23159585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23169585STim.Szeto@Sun.COM } 23179585STim.Szeto@Sun.COM bcopy(diskLu->pid, propVal, sizeof (diskLu->pid)); 23189585STim.Szeto@Sun.COM propVal[sizeof (diskLu->pid)] = 0; 23199585STim.Szeto@Sun.COM break; 23209585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 23219585STim.Szeto@Sun.COM if (diskLu->writeProtectEnableValid == B_FALSE) { 23229585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23239585STim.Szeto@Sun.COM } 23249585STim.Szeto@Sun.COM if (diskLu->writeProtectEnable) { 23259585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 23269585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23279585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23289585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23299585STim.Szeto@Sun.COM } 23309585STim.Szeto@Sun.COM } else { 23319585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 23329585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23339585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23349585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23359585STim.Szeto@Sun.COM } 23369585STim.Szeto@Sun.COM } 23379585STim.Szeto@Sun.COM break; 23389585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 23399585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisableValid == B_FALSE) { 23409585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23419585STim.Szeto@Sun.COM } 23429585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisable) { 23439585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 23449585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23459585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23469585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23479585STim.Szeto@Sun.COM } 23489585STim.Szeto@Sun.COM } else { 23499585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 23509585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23519585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23529585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23539585STim.Szeto@Sun.COM } 23549585STim.Szeto@Sun.COM } 23559585STim.Szeto@Sun.COM break; 23569585STim.Szeto@Sun.COM default: 23579585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 23589585STim.Szeto@Sun.COM break; 23599585STim.Szeto@Sun.COM } 23609585STim.Szeto@Sun.COM 23619585STim.Szeto@Sun.COM return (ret); 23629585STim.Szeto@Sun.COM } 23639585STim.Szeto@Sun.COM 23649585STim.Szeto@Sun.COM /* 23659585STim.Szeto@Sun.COM * setDiskProp 23669585STim.Szeto@Sun.COM * 23679585STim.Szeto@Sun.COM * Purpose: set properties for resource of type disk 23689585STim.Szeto@Sun.COM * 23699585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 23709585STim.Szeto@Sun.COM * resourceProp - valid resource identifier 23719585STim.Szeto@Sun.COM * propVal - valid resource value 23729585STim.Szeto@Sun.COM */ 23739585STim.Szeto@Sun.COM static int 23749585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal) 23759585STim.Szeto@Sun.COM { 23769585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 23779585STim.Szeto@Sun.COM int i; 23789585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 23799585STim.Szeto@Sun.COM unsigned long long numericProp = 0; 23809585STim.Szeto@Sun.COM char guidProp[LU_ASCII_GUID_SIZE + 1]; 23819585STim.Szeto@Sun.COM char ouiProp[OUI_ASCII_SIZE + 1]; 23829585STim.Szeto@Sun.COM unsigned int oui[OUI_SIZE]; 23839585STim.Szeto@Sun.COM unsigned int guid[LU_GUID_SIZE]; 23849585STim.Szeto@Sun.COM int propSize; 23859585STim.Szeto@Sun.COM 23869585STim.Szeto@Sun.COM 23879585STim.Szeto@Sun.COM if (propVal == NULL) { 23889585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23899585STim.Szeto@Sun.COM } 23909585STim.Szeto@Sun.COM 23919585STim.Szeto@Sun.COM switch (resourceProp) { 23929585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 23939585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, propVal, 23949585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 23959585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 23969585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 23979585STim.Szeto@Sun.COM } 23989585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 23999585STim.Szeto@Sun.COM break; 24009585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 24019585STim.Szeto@Sun.COM (void) sscanf(propVal, "%llu", &numericProp); 24029585STim.Szeto@Sun.COM if (numericProp > UINT16_MAX) { 24039585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24049585STim.Szeto@Sun.COM } 24059585STim.Szeto@Sun.COM diskLu->blkSize = numericProp; 24069585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 24079585STim.Szeto@Sun.COM break; 24089585STim.Szeto@Sun.COM case STMF_LU_PROP_COMPANY_ID: 24099585STim.Szeto@Sun.COM if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >= 24109585STim.Szeto@Sun.COM sizeof (ouiProp)) { 24119585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24129585STim.Szeto@Sun.COM } 24139585STim.Szeto@Sun.COM if (checkHexUpper(ouiProp) != 0) { 24149585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24159585STim.Szeto@Sun.COM } 24169585STim.Szeto@Sun.COM (void) sscanf(ouiProp, "%2X%2X%2X", 24179585STim.Szeto@Sun.COM &oui[0], &oui[1], &oui[2]); 24189585STim.Szeto@Sun.COM 24199585STim.Szeto@Sun.COM diskLu->companyId = 0; 24209585STim.Szeto@Sun.COM diskLu->companyId += oui[0] << 16; 24219585STim.Szeto@Sun.COM diskLu->companyId += oui[1] << 8; 24229585STim.Szeto@Sun.COM diskLu->companyId += oui[2]; 24239585STim.Szeto@Sun.COM diskLu->companyIdValid = B_TRUE; 24249585STim.Szeto@Sun.COM break; 24259585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 24269585STim.Szeto@Sun.COM if (strlen(propVal) != LU_ASCII_GUID_SIZE) { 24279585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24289585STim.Szeto@Sun.COM } 24299585STim.Szeto@Sun.COM 24309585STim.Szeto@Sun.COM if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >= 24319585STim.Szeto@Sun.COM sizeof (guidProp)) { 24329585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24339585STim.Szeto@Sun.COM } 24349585STim.Szeto@Sun.COM 24359585STim.Szeto@Sun.COM if (checkHexUpper(guidProp) != 0) { 24369585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24379585STim.Szeto@Sun.COM } 24389585STim.Szeto@Sun.COM 24399585STim.Szeto@Sun.COM (void) sscanf(guidProp, 24409585STim.Szeto@Sun.COM "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X", 24419585STim.Szeto@Sun.COM &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], 24429585STim.Szeto@Sun.COM &guid[5], &guid[6], &guid[7], &guid[8], &guid[9], 24439585STim.Szeto@Sun.COM &guid[10], &guid[11], &guid[12], &guid[13], 24449585STim.Szeto@Sun.COM &guid[14], &guid[15]); 24459585STim.Szeto@Sun.COM for (i = 0; i < sizeof (diskLu->luGuid); i++) { 24469585STim.Szeto@Sun.COM diskLu->luGuid[i] = guid[i]; 24479585STim.Szeto@Sun.COM } 24489585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 24499585STim.Szeto@Sun.COM break; 24509585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 24519585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luDataFileName, propVal, 24529585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName))) >= 24539585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 24549585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24559585STim.Szeto@Sun.COM } 24569585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 24579585STim.Szeto@Sun.COM break; 24589585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 24599585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luMetaFileName, propVal, 24609585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName))) >= 24619585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 24629585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24639585STim.Szeto@Sun.COM } 24649585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 24659585STim.Szeto@Sun.COM break; 24669585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 24679585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 24689585STim.Szeto@Sun.COM sizeof (diskLu->pid)) { 24699585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24709585STim.Szeto@Sun.COM } 24719585STim.Szeto@Sun.COM (void) strncpy(diskLu->pid, propVal, propSize); 24729585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 24739585STim.Szeto@Sun.COM break; 24749585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 24759585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 24769585STim.Szeto@Sun.COM (sizeof (diskLu->serialNum) - 1)) { 24779585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24789585STim.Szeto@Sun.COM } 24799585STim.Szeto@Sun.COM (void) strncpy(diskLu->serialNum, propVal, propSize); 24809585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 24819585STim.Szeto@Sun.COM break; 24829585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 24839585STim.Szeto@Sun.COM if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) { 24849585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24859585STim.Szeto@Sun.COM } 24869585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 24879585STim.Szeto@Sun.COM break; 24889585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 24899585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 24909585STim.Szeto@Sun.COM sizeof (diskLu->vid)) { 24919585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24929585STim.Szeto@Sun.COM } 24939585STim.Szeto@Sun.COM (void) strncpy(diskLu->vid, propVal, propSize); 24949585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 24959585STim.Szeto@Sun.COM break; 24969585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 24979585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 24989585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 24999585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 25009585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_FALSE; 25019585STim.Szeto@Sun.COM } else { 25029585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25039585STim.Szeto@Sun.COM } 25049585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 25059585STim.Szeto@Sun.COM break; 25069585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 25079585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 25089585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 25099585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 25109585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_FALSE; 25119585STim.Szeto@Sun.COM } else { 25129585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25139585STim.Szeto@Sun.COM } 25149585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 25159585STim.Szeto@Sun.COM break; 25169585STim.Szeto@Sun.COM default: 25179585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 25189585STim.Szeto@Sun.COM break; 25199585STim.Szeto@Sun.COM } 25209585STim.Szeto@Sun.COM return (ret); 25219585STim.Szeto@Sun.COM } 25229585STim.Szeto@Sun.COM 25239585STim.Szeto@Sun.COM static int 25249585STim.Szeto@Sun.COM checkHexUpper(char *buf) 25259585STim.Szeto@Sun.COM { 25269585STim.Szeto@Sun.COM int i; 25279585STim.Szeto@Sun.COM 25289585STim.Szeto@Sun.COM for (i = 0; i < strlen(buf); i++) { 25299585STim.Szeto@Sun.COM if (isxdigit(buf[i])) { 25309585STim.Szeto@Sun.COM buf[i] = toupper(buf[i]); 25319585STim.Szeto@Sun.COM continue; 25329585STim.Szeto@Sun.COM } 25339585STim.Szeto@Sun.COM return (-1); 25349585STim.Szeto@Sun.COM } 25359585STim.Szeto@Sun.COM 25369585STim.Szeto@Sun.COM return (0); 25379585STim.Szeto@Sun.COM } 25389585STim.Szeto@Sun.COM 25399585STim.Szeto@Sun.COM /* 25409585STim.Szeto@Sun.COM * Given a numeric suffix, convert the value into a number of bits that the 25419585STim.Szeto@Sun.COM * resulting value must be shifted. 25429585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 25439585STim.Szeto@Sun.COM */ 25449585STim.Szeto@Sun.COM static int 25459585STim.Szeto@Sun.COM strToShift(const char *buf) 25469585STim.Szeto@Sun.COM { 25479585STim.Szeto@Sun.COM const char *ends = "BKMGTPE"; 25489585STim.Szeto@Sun.COM int i; 25499585STim.Szeto@Sun.COM 25509585STim.Szeto@Sun.COM if (buf[0] == '\0') 25519585STim.Szeto@Sun.COM return (0); 25529585STim.Szeto@Sun.COM 25539585STim.Szeto@Sun.COM for (i = 0; i < strlen(ends); i++) { 25549585STim.Szeto@Sun.COM if (toupper(buf[0]) == ends[i]) 25559585STim.Szeto@Sun.COM return (10*i); 25569585STim.Szeto@Sun.COM } 25579585STim.Szeto@Sun.COM 25589585STim.Szeto@Sun.COM return (-1); 25599585STim.Szeto@Sun.COM } 25609585STim.Szeto@Sun.COM 25619585STim.Szeto@Sun.COM int 25629585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl) 25639585STim.Szeto@Sun.COM { 25649585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 25659585STim.Szeto@Sun.COM if (hdl == NULL) { 25669585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25679585STim.Szeto@Sun.COM } 25689585STim.Szeto@Sun.COM 25699585STim.Szeto@Sun.COM luResourceImpl *hdlImpl = hdl; 25709585STim.Szeto@Sun.COM free(hdlImpl->resource); 25719585STim.Szeto@Sun.COM free(hdlImpl); 25729585STim.Szeto@Sun.COM return (ret); 25739585STim.Szeto@Sun.COM } 25749585STim.Szeto@Sun.COM 25759585STim.Szeto@Sun.COM /* 25769585STim.Szeto@Sun.COM * Convert a string of the form '100G' into a real number. Used when setting 25779585STim.Szeto@Sun.COM * the size of a logical unit. 25789585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 25799585STim.Szeto@Sun.COM */ 25809585STim.Szeto@Sun.COM static int 25819585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num) 25829585STim.Szeto@Sun.COM { 25839585STim.Szeto@Sun.COM char *end; 25849585STim.Szeto@Sun.COM int shift; 25859585STim.Szeto@Sun.COM 25869585STim.Szeto@Sun.COM *num = 0; 25879585STim.Szeto@Sun.COM 25889585STim.Szeto@Sun.COM /* Check to see if this looks like a number. */ 25899585STim.Szeto@Sun.COM if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 25909585STim.Szeto@Sun.COM return (-1); 25919585STim.Szeto@Sun.COM } 25929585STim.Szeto@Sun.COM 25939585STim.Szeto@Sun.COM /* Rely on stroull() to process the numeric portion. */ 25949585STim.Szeto@Sun.COM errno = 0; 25959585STim.Szeto@Sun.COM *num = strtoull(value, &end, 10); 25969585STim.Szeto@Sun.COM 25979585STim.Szeto@Sun.COM /* 25989585STim.Szeto@Sun.COM * Check for ERANGE, which indicates that the value is too large to fit 25999585STim.Szeto@Sun.COM * in a 64-bit value. 26009585STim.Szeto@Sun.COM */ 26019585STim.Szeto@Sun.COM if (errno == ERANGE) { 26029585STim.Szeto@Sun.COM return (-1); 26039585STim.Szeto@Sun.COM } 26049585STim.Szeto@Sun.COM 26059585STim.Szeto@Sun.COM /* 26069585STim.Szeto@Sun.COM * If we have a decimal value, then do the computation with floating 26079585STim.Szeto@Sun.COM * point arithmetic. Otherwise, use standard arithmetic. 26089585STim.Szeto@Sun.COM */ 26099585STim.Szeto@Sun.COM if (*end == '.') { 26109585STim.Szeto@Sun.COM double fval = strtod(value, &end); 26119585STim.Szeto@Sun.COM 26129585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 26139585STim.Szeto@Sun.COM return (-1); 26149585STim.Szeto@Sun.COM } 26159585STim.Szeto@Sun.COM 26169585STim.Szeto@Sun.COM fval *= pow(2, shift); 26179585STim.Szeto@Sun.COM 26189585STim.Szeto@Sun.COM if (fval > UINT64_MAX) { 26199585STim.Szeto@Sun.COM return (-1); 26209585STim.Szeto@Sun.COM } 26219585STim.Szeto@Sun.COM 26229585STim.Szeto@Sun.COM *num = (uint64_t)fval; 26239585STim.Szeto@Sun.COM } else { 26249585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 26259585STim.Szeto@Sun.COM return (-1); 26269585STim.Szeto@Sun.COM } 26279585STim.Szeto@Sun.COM 26289585STim.Szeto@Sun.COM /* Check for overflow */ 26299585STim.Szeto@Sun.COM if (shift >= 64 || (*num << shift) >> shift != *num) { 26309585STim.Szeto@Sun.COM return (-1); 26319585STim.Szeto@Sun.COM } 26329585STim.Szeto@Sun.COM 26339585STim.Szeto@Sun.COM *num <<= shift; 26349585STim.Szeto@Sun.COM } 26359585STim.Szeto@Sun.COM 26369585STim.Szeto@Sun.COM return (0); 26379585STim.Szeto@Sun.COM } 26389585STim.Szeto@Sun.COM 26399585STim.Szeto@Sun.COM /* 26407836SJohn.Forte@Sun.COM * stmfCreateTargetGroup 26417836SJohn.Forte@Sun.COM * 26427836SJohn.Forte@Sun.COM * Purpose: Create a local port group 26437836SJohn.Forte@Sun.COM * 26447836SJohn.Forte@Sun.COM * targetGroupName - name of local port group to create 26457836SJohn.Forte@Sun.COM */ 26467836SJohn.Forte@Sun.COM int 26477836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName) 26487836SJohn.Forte@Sun.COM { 26497836SJohn.Forte@Sun.COM int ret; 26507836SJohn.Forte@Sun.COM int fd; 26517836SJohn.Forte@Sun.COM 26527836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 26537836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 26547836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 26557836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 26567836SJohn.Forte@Sun.COM } 26577836SJohn.Forte@Sun.COM 26587836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 26597836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 26607836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 26617836SJohn.Forte@Sun.COM } 26627836SJohn.Forte@Sun.COM 26637836SJohn.Forte@Sun.COM /* call init */ 26647836SJohn.Forte@Sun.COM ret = initializeConfig(); 26657836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 26667836SJohn.Forte@Sun.COM return (ret); 26677836SJohn.Forte@Sun.COM } 26687836SJohn.Forte@Sun.COM 26697836SJohn.Forte@Sun.COM /* 26707836SJohn.Forte@Sun.COM * Open control node for stmf 26717836SJohn.Forte@Sun.COM */ 26727836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 26737836SJohn.Forte@Sun.COM return (ret); 26747836SJohn.Forte@Sun.COM 26757836SJohn.Forte@Sun.COM /* 26767836SJohn.Forte@Sun.COM * Add the group to the driver 26777836SJohn.Forte@Sun.COM */ 26787836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 26797836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 26807836SJohn.Forte@Sun.COM goto done; 26817836SJohn.Forte@Sun.COM } 26827836SJohn.Forte@Sun.COM 26839585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 26849585STim.Szeto@Sun.COM goto done; 26859585STim.Szeto@Sun.COM } 26869585STim.Szeto@Sun.COM 26877836SJohn.Forte@Sun.COM /* 26887836SJohn.Forte@Sun.COM * If the add to the driver was successful, add it to the persistent 26897836SJohn.Forte@Sun.COM * store. 26907836SJohn.Forte@Sun.COM */ 26917836SJohn.Forte@Sun.COM ret = psCreateTargetGroup((char *)targetGroupName); 26927836SJohn.Forte@Sun.COM switch (ret) { 26937836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 26947836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 26957836SJohn.Forte@Sun.COM break; 26967836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 26977836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 26987836SJohn.Forte@Sun.COM break; 26997836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 27007836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 27017836SJohn.Forte@Sun.COM break; 27027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 27037836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 27047836SJohn.Forte@Sun.COM break; 27057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 27067836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 27077836SJohn.Forte@Sun.COM break; 27087836SJohn.Forte@Sun.COM default: 27097836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 27107836SJohn.Forte@Sun.COM "stmfCreateTargetGroup:psCreateTargetGroup" 27117836SJohn.Forte@Sun.COM ":error(%d)", ret); 27127836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 27137836SJohn.Forte@Sun.COM break; 27147836SJohn.Forte@Sun.COM } 27157836SJohn.Forte@Sun.COM 27167836SJohn.Forte@Sun.COM done: 27177836SJohn.Forte@Sun.COM (void) close(fd); 27187836SJohn.Forte@Sun.COM return (ret); 27197836SJohn.Forte@Sun.COM } 27207836SJohn.Forte@Sun.COM 27217836SJohn.Forte@Sun.COM /* 27227836SJohn.Forte@Sun.COM * stmfDeleteHostGroup 27237836SJohn.Forte@Sun.COM * 27247836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 27257836SJohn.Forte@Sun.COM * 27267836SJohn.Forte@Sun.COM * hostGroupName - group to delete 27277836SJohn.Forte@Sun.COM */ 27287836SJohn.Forte@Sun.COM int 27297836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName) 27307836SJohn.Forte@Sun.COM { 27317836SJohn.Forte@Sun.COM int ret; 27327836SJohn.Forte@Sun.COM int fd; 27337836SJohn.Forte@Sun.COM 27347836SJohn.Forte@Sun.COM if (hostGroupName == NULL) { 27357836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 27367836SJohn.Forte@Sun.COM } 27377836SJohn.Forte@Sun.COM 27387836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 27397836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 27407836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 27417836SJohn.Forte@Sun.COM } 27427836SJohn.Forte@Sun.COM 27437836SJohn.Forte@Sun.COM /* call init */ 27447836SJohn.Forte@Sun.COM ret = initializeConfig(); 27457836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 27467836SJohn.Forte@Sun.COM return (ret); 27477836SJohn.Forte@Sun.COM } 27487836SJohn.Forte@Sun.COM 27497836SJohn.Forte@Sun.COM /* 27507836SJohn.Forte@Sun.COM * Open control node for stmf 27517836SJohn.Forte@Sun.COM */ 27527836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 27537836SJohn.Forte@Sun.COM return (ret); 27547836SJohn.Forte@Sun.COM 27557836SJohn.Forte@Sun.COM /* 27567836SJohn.Forte@Sun.COM * Remove the group from the driver 27577836SJohn.Forte@Sun.COM */ 27587836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP, 27597836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 27607836SJohn.Forte@Sun.COM goto done; 27617836SJohn.Forte@Sun.COM } 27627836SJohn.Forte@Sun.COM 27639585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 27649585STim.Szeto@Sun.COM goto done; 27659585STim.Szeto@Sun.COM } 27669585STim.Szeto@Sun.COM 27677836SJohn.Forte@Sun.COM /* 27687836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 27697836SJohn.Forte@Sun.COM * persistent store. 27707836SJohn.Forte@Sun.COM */ 27717836SJohn.Forte@Sun.COM ret = psDeleteHostGroup((char *)hostGroupName); 27727836SJohn.Forte@Sun.COM switch (ret) { 27737836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 27747836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 27757836SJohn.Forte@Sun.COM break; 27767836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 27777836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 27787836SJohn.Forte@Sun.COM break; 27797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 27807836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 27817836SJohn.Forte@Sun.COM break; 27827836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 27837836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 27847836SJohn.Forte@Sun.COM break; 27857836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 27867836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 27877836SJohn.Forte@Sun.COM break; 27887836SJohn.Forte@Sun.COM default: 27897836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 27907836SJohn.Forte@Sun.COM "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)", 27917836SJohn.Forte@Sun.COM ret); 27927836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 27937836SJohn.Forte@Sun.COM break; 27947836SJohn.Forte@Sun.COM } 27957836SJohn.Forte@Sun.COM 27967836SJohn.Forte@Sun.COM done: 27977836SJohn.Forte@Sun.COM (void) close(fd); 27987836SJohn.Forte@Sun.COM return (ret); 27997836SJohn.Forte@Sun.COM } 28007836SJohn.Forte@Sun.COM 28017836SJohn.Forte@Sun.COM /* 28027836SJohn.Forte@Sun.COM * stmfDeleteTargetGroup 28037836SJohn.Forte@Sun.COM * 28047836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 28057836SJohn.Forte@Sun.COM * 28067836SJohn.Forte@Sun.COM * targetGroupName - group to delete 28077836SJohn.Forte@Sun.COM */ 28087836SJohn.Forte@Sun.COM int 28097836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName) 28107836SJohn.Forte@Sun.COM { 28117836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 28127836SJohn.Forte@Sun.COM int fd; 28137836SJohn.Forte@Sun.COM 28147836SJohn.Forte@Sun.COM if (targetGroupName == NULL) { 28157836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 28167836SJohn.Forte@Sun.COM } 28177836SJohn.Forte@Sun.COM 28187836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 28197836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 28207836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 28217836SJohn.Forte@Sun.COM } 28227836SJohn.Forte@Sun.COM 28237836SJohn.Forte@Sun.COM /* call init */ 28247836SJohn.Forte@Sun.COM ret = initializeConfig(); 28257836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 28267836SJohn.Forte@Sun.COM return (ret); 28277836SJohn.Forte@Sun.COM } 28287836SJohn.Forte@Sun.COM 28297836SJohn.Forte@Sun.COM /* 28307836SJohn.Forte@Sun.COM * Open control node for stmf 28317836SJohn.Forte@Sun.COM */ 28327836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 28337836SJohn.Forte@Sun.COM return (ret); 28347836SJohn.Forte@Sun.COM 28357836SJohn.Forte@Sun.COM /* 28367836SJohn.Forte@Sun.COM * Remove the group from the driver 28377836SJohn.Forte@Sun.COM */ 28387836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP, 28397836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 28407836SJohn.Forte@Sun.COM goto done; 28417836SJohn.Forte@Sun.COM } 28427836SJohn.Forte@Sun.COM 28439585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 28449585STim.Szeto@Sun.COM goto done; 28459585STim.Szeto@Sun.COM } 28469585STim.Szeto@Sun.COM 28477836SJohn.Forte@Sun.COM /* 28487836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 28497836SJohn.Forte@Sun.COM * persistent store. 28507836SJohn.Forte@Sun.COM */ 28517836SJohn.Forte@Sun.COM ret = psDeleteTargetGroup((char *)targetGroupName); 28527836SJohn.Forte@Sun.COM switch (ret) { 28537836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 28547836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 28557836SJohn.Forte@Sun.COM break; 28567836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 28577836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 28587836SJohn.Forte@Sun.COM break; 28597836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 28607836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 28617836SJohn.Forte@Sun.COM break; 28627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 28637836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 28647836SJohn.Forte@Sun.COM break; 28657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 28667836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 28677836SJohn.Forte@Sun.COM break; 28687836SJohn.Forte@Sun.COM default: 28697836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 28707836SJohn.Forte@Sun.COM "stmfDeleteTargetGroup:psDeleteTargetGroup" 28717836SJohn.Forte@Sun.COM ":error(%d)", ret); 28727836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 28737836SJohn.Forte@Sun.COM break; 28747836SJohn.Forte@Sun.COM } 28757836SJohn.Forte@Sun.COM 28767836SJohn.Forte@Sun.COM done: 28777836SJohn.Forte@Sun.COM (void) close(fd); 28787836SJohn.Forte@Sun.COM return (ret); 28797836SJohn.Forte@Sun.COM } 28807836SJohn.Forte@Sun.COM 28817836SJohn.Forte@Sun.COM /* 28827836SJohn.Forte@Sun.COM * stmfDevidFromIscsiName 28837836SJohn.Forte@Sun.COM * 28847836SJohn.Forte@Sun.COM * Purpose: convert an iSCSI name to an stmf devid 28857836SJohn.Forte@Sun.COM * 28867836SJohn.Forte@Sun.COM * iscsiName - unicode nul terminated utf-8 encoded iSCSI name 28877836SJohn.Forte@Sun.COM * devid - on success, contains the converted iscsi name 28887836SJohn.Forte@Sun.COM */ 28897836SJohn.Forte@Sun.COM int 28907836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid) 28917836SJohn.Forte@Sun.COM { 28927836SJohn.Forte@Sun.COM if (devid == NULL || iscsiName == NULL) 28937836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 28947836SJohn.Forte@Sun.COM 28957836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 28967836SJohn.Forte@Sun.COM 28977836SJohn.Forte@Sun.COM /* Validate size of target */ 28987836SJohn.Forte@Sun.COM if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME || 28997836SJohn.Forte@Sun.COM devid->identLength < strlen(EUI) || 29007836SJohn.Forte@Sun.COM devid->identLength < strlen(IQN)) { 29017836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29027836SJohn.Forte@Sun.COM } 29037836SJohn.Forte@Sun.COM 29047836SJohn.Forte@Sun.COM if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) && 29057836SJohn.Forte@Sun.COM strncmp(iscsiName, IQN, strlen(IQN)) != 0) { 29067836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29077836SJohn.Forte@Sun.COM } 29087836SJohn.Forte@Sun.COM 29097836SJohn.Forte@Sun.COM /* copy UTF-8 bytes to ident */ 29107836SJohn.Forte@Sun.COM bcopy(iscsiName, devid->ident, devid->identLength); 29117836SJohn.Forte@Sun.COM 29127836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 29137836SJohn.Forte@Sun.COM } 29147836SJohn.Forte@Sun.COM 29157836SJohn.Forte@Sun.COM /* 29167836SJohn.Forte@Sun.COM * stmfDevidFromWwn 29177836SJohn.Forte@Sun.COM * 29187836SJohn.Forte@Sun.COM * Purpose: convert a WWN to an stmf devid 29197836SJohn.Forte@Sun.COM * 29207836SJohn.Forte@Sun.COM * wwn - 8-byte wwn identifier 29217836SJohn.Forte@Sun.COM * devid - on success, contains the converted wwn 29227836SJohn.Forte@Sun.COM */ 29237836SJohn.Forte@Sun.COM int 29247836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid) 29257836SJohn.Forte@Sun.COM { 29267836SJohn.Forte@Sun.COM if (wwn == NULL || devid == NULL) 29277836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29287836SJohn.Forte@Sun.COM 29297836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 29307836SJohn.Forte@Sun.COM 29317836SJohn.Forte@Sun.COM /* Copy eui prefix */ 29327836SJohn.Forte@Sun.COM (void) bcopy(WWN, devid->ident, strlen(WWN)); 29337836SJohn.Forte@Sun.COM 29347836SJohn.Forte@Sun.COM /* Convert to ASCII uppercase hexadecimal string */ 29357836SJohn.Forte@Sun.COM (void) snprintf((char *)&devid->ident[strlen(WWN)], 29367836SJohn.Forte@Sun.COM sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X", 29377836SJohn.Forte@Sun.COM wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 29387836SJohn.Forte@Sun.COM 29397836SJohn.Forte@Sun.COM devid->identLength = strlen((char *)devid->ident); 29407836SJohn.Forte@Sun.COM 29417836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 29427836SJohn.Forte@Sun.COM } 29437836SJohn.Forte@Sun.COM 29447836SJohn.Forte@Sun.COM /* 29457836SJohn.Forte@Sun.COM * stmfFreeMemory 29467836SJohn.Forte@Sun.COM * 29477836SJohn.Forte@Sun.COM * Purpose: Free memory allocated by this library 29487836SJohn.Forte@Sun.COM * 29497836SJohn.Forte@Sun.COM * memory - previously allocated pointer of memory managed by library 29507836SJohn.Forte@Sun.COM */ 29517836SJohn.Forte@Sun.COM void 29527836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory) 29537836SJohn.Forte@Sun.COM { 29547836SJohn.Forte@Sun.COM free(memory); 29557836SJohn.Forte@Sun.COM } 29567836SJohn.Forte@Sun.COM 29577836SJohn.Forte@Sun.COM /* 29589585STim.Szeto@Sun.COM * get host group, target group list from stmf 29597836SJohn.Forte@Sun.COM * 29609585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 29617836SJohn.Forte@Sun.COM */ 29629585STim.Szeto@Sun.COM static int 29639585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType) 29649585STim.Szeto@Sun.COM { 29659585STim.Szeto@Sun.COM int ret; 29669585STim.Szeto@Sun.COM int fd; 29679585STim.Szeto@Sun.COM int ioctlRet; 29689585STim.Szeto@Sun.COM int i; 29699585STim.Szeto@Sun.COM int cmd; 29709585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 29719585STim.Szeto@Sun.COM /* framework group list */ 29729585STim.Szeto@Sun.COM stmf_group_name_t *iGroupList = NULL; 29739585STim.Szeto@Sun.COM uint32_t groupListSize; 29749585STim.Szeto@Sun.COM 29759585STim.Szeto@Sun.COM if (groupList == NULL) { 29769585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29779585STim.Szeto@Sun.COM } 29789585STim.Szeto@Sun.COM 29799585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 29809585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_LIST; 29819585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 29829585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_LIST; 29839585STim.Szeto@Sun.COM } else { 29849585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 29859585STim.Szeto@Sun.COM } 29869585STim.Szeto@Sun.COM 29879585STim.Szeto@Sun.COM /* call init */ 29889585STim.Szeto@Sun.COM ret = initializeConfig(); 29899585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 29909585STim.Szeto@Sun.COM return (ret); 29919585STim.Szeto@Sun.COM } 29929585STim.Szeto@Sun.COM 29939585STim.Szeto@Sun.COM /* 29949585STim.Szeto@Sun.COM * Open control node for stmf 29959585STim.Szeto@Sun.COM */ 29969585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 29979585STim.Szeto@Sun.COM return (ret); 29989585STim.Szeto@Sun.COM 29999585STim.Szeto@Sun.COM /* 30009585STim.Szeto@Sun.COM * Allocate ioctl input buffer 30019585STim.Szeto@Sun.COM */ 30029585STim.Szeto@Sun.COM groupListSize = ALLOC_GROUP; 30039585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_group_name_t)); 30049585STim.Szeto@Sun.COM iGroupList = (stmf_group_name_t *)calloc(1, groupListSize); 30059585STim.Szeto@Sun.COM if (iGroupList == NULL) { 30069585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 30079585STim.Szeto@Sun.COM goto done; 30089585STim.Szeto@Sun.COM } 30099585STim.Szeto@Sun.COM 30109585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 30119585STim.Szeto@Sun.COM /* 30129585STim.Szeto@Sun.COM * Issue ioctl to get the group list 30139585STim.Szeto@Sun.COM */ 30149585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 30159585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 30169585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 30179585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 30189585STim.Szeto@Sun.COM if (ioctlRet != 0) { 30199585STim.Szeto@Sun.COM switch (errno) { 30209585STim.Szeto@Sun.COM case EBUSY: 30219585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 30229585STim.Szeto@Sun.COM break; 30239585STim.Szeto@Sun.COM case EPERM: 30249585STim.Szeto@Sun.COM case EACCES: 30259585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 30269585STim.Szeto@Sun.COM break; 30279585STim.Szeto@Sun.COM default: 30289585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 30299585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 30309585STim.Szeto@Sun.COM errno); 30319585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 30329585STim.Szeto@Sun.COM break; 30339585STim.Szeto@Sun.COM } 30349585STim.Szeto@Sun.COM goto done; 30359585STim.Szeto@Sun.COM } 30369585STim.Szeto@Sun.COM /* 30379585STim.Szeto@Sun.COM * Check whether input buffer was large enough 30389585STim.Szeto@Sun.COM */ 30399585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) { 30409585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 30419585STim.Szeto@Sun.COM sizeof (stmf_group_name_t); 30429585STim.Szeto@Sun.COM iGroupList = realloc(iGroupList, groupListSize); 30439585STim.Szeto@Sun.COM if (iGroupList == NULL) { 30449585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 30459585STim.Szeto@Sun.COM goto done; 30469585STim.Szeto@Sun.COM } 30479585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 30489585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 30499585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 30509585STim.Szeto@Sun.COM if (ioctlRet != 0) { 30519585STim.Szeto@Sun.COM switch (errno) { 30529585STim.Szeto@Sun.COM case EBUSY: 30539585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 30549585STim.Szeto@Sun.COM break; 30559585STim.Szeto@Sun.COM case EPERM: 30569585STim.Szeto@Sun.COM case EACCES: 30579585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 30589585STim.Szeto@Sun.COM break; 30599585STim.Szeto@Sun.COM default: 30609585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 30619585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 30629585STim.Szeto@Sun.COM errno); 30639585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 30649585STim.Szeto@Sun.COM break; 30659585STim.Szeto@Sun.COM } 30669585STim.Szeto@Sun.COM goto done; 30679585STim.Szeto@Sun.COM } 30689585STim.Szeto@Sun.COM } 30699585STim.Szeto@Sun.COM 30709585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 30719585STim.Szeto@Sun.COM *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) * 30729585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_nentries); 30739585STim.Szeto@Sun.COM if (*groupList == NULL) { 30749585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 30759585STim.Szeto@Sun.COM goto done; 30769585STim.Szeto@Sun.COM } 30779585STim.Szeto@Sun.COM (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries; 30789585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 30799585STim.Szeto@Sun.COM bcopy(iGroupList->name, (*groupList)->name[i], 30809585STim.Szeto@Sun.COM sizeof (stmfGroupName)); 30819585STim.Szeto@Sun.COM iGroupList++; 30829585STim.Szeto@Sun.COM } 30839585STim.Szeto@Sun.COM 30849585STim.Szeto@Sun.COM done: 30859585STim.Szeto@Sun.COM free(iGroupList); 30869585STim.Szeto@Sun.COM (void) close(fd); 30879585STim.Szeto@Sun.COM return (ret); 30889585STim.Szeto@Sun.COM } 30899585STim.Szeto@Sun.COM 30909585STim.Szeto@Sun.COM /* 30919585STim.Szeto@Sun.COM * get host group members, target group members from stmf 30929585STim.Szeto@Sun.COM * 30939585STim.Szeto@Sun.COM * groupProps - allocated on success 30949585STim.Szeto@Sun.COM * 30959585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 30969585STim.Szeto@Sun.COM */ 30979585STim.Szeto@Sun.COM static int 30989585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps, 30999585STim.Szeto@Sun.COM int groupType) 31007836SJohn.Forte@Sun.COM { 31017836SJohn.Forte@Sun.COM int ret; 31029585STim.Szeto@Sun.COM int fd; 31039585STim.Szeto@Sun.COM int ioctlRet; 31049585STim.Szeto@Sun.COM int i; 31059585STim.Szeto@Sun.COM int cmd; 31069585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 31079585STim.Szeto@Sun.COM /* framework group list */ 31089585STim.Szeto@Sun.COM stmf_group_name_t iGroupName; 31099585STim.Szeto@Sun.COM stmf_ge_ident_t *iGroupMembers; 31109585STim.Szeto@Sun.COM uint32_t groupListSize; 31119585STim.Szeto@Sun.COM 31129585STim.Szeto@Sun.COM if (groupName == NULL) { 31139585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 31149585STim.Szeto@Sun.COM } 31159585STim.Szeto@Sun.COM 31169585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 31179585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_ENTRIES; 31189585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 31199585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_ENTRIES; 31209585STim.Szeto@Sun.COM } else { 31217836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31227836SJohn.Forte@Sun.COM } 31237836SJohn.Forte@Sun.COM 31249585STim.Szeto@Sun.COM /* call init */ 31259585STim.Szeto@Sun.COM ret = initializeConfig(); 31269585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 31279585STim.Szeto@Sun.COM return (ret); 31289585STim.Szeto@Sun.COM } 31299585STim.Szeto@Sun.COM 31309585STim.Szeto@Sun.COM /* 31319585STim.Szeto@Sun.COM * Open control node for stmf 31329585STim.Szeto@Sun.COM */ 31339585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 31349585STim.Szeto@Sun.COM return (ret); 31359585STim.Szeto@Sun.COM 31369585STim.Szeto@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 31379585STim.Szeto@Sun.COM 31389585STim.Szeto@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 31399585STim.Szeto@Sun.COM 31409585STim.Szeto@Sun.COM iGroupName.name_size = strlen((char *)groupName); 31419585STim.Szeto@Sun.COM 31429585STim.Szeto@Sun.COM /* 31439585STim.Szeto@Sun.COM * Allocate ioctl input buffer 31449585STim.Szeto@Sun.COM */ 31459585STim.Szeto@Sun.COM groupListSize = ALLOC_GRP_MEMBER; 31469585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_ge_ident_t)); 31479585STim.Szeto@Sun.COM iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize); 31489585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 31499585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 31509585STim.Szeto@Sun.COM goto done; 31519585STim.Szeto@Sun.COM } 31529585STim.Szeto@Sun.COM 31539585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 31549585STim.Szeto@Sun.COM /* 31559585STim.Szeto@Sun.COM * Issue ioctl to get the group list 31569585STim.Szeto@Sun.COM */ 31579585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 31589585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 31599585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 31609585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 31619585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 31629585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 31639585STim.Szeto@Sun.COM if (ioctlRet != 0) { 31649585STim.Szeto@Sun.COM switch (errno) { 31659585STim.Szeto@Sun.COM case EBUSY: 31669585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 31679585STim.Szeto@Sun.COM break; 31689585STim.Szeto@Sun.COM case EPERM: 31699585STim.Szeto@Sun.COM case EACCES: 31709585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 31719585STim.Szeto@Sun.COM break; 31729585STim.Szeto@Sun.COM default: 31739585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 31749585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 31759585STim.Szeto@Sun.COM errno); 31769585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 31779585STim.Szeto@Sun.COM break; 31789585STim.Szeto@Sun.COM } 31799585STim.Szeto@Sun.COM goto done; 31809585STim.Szeto@Sun.COM } 31819585STim.Szeto@Sun.COM /* 31829585STim.Szeto@Sun.COM * Check whether input buffer was large enough 31839585STim.Szeto@Sun.COM */ 31849585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) { 31859585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 31869585STim.Szeto@Sun.COM sizeof (stmf_ge_ident_t); 31879585STim.Szeto@Sun.COM iGroupMembers = realloc(iGroupMembers, groupListSize); 31889585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 31899585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 31909585STim.Szeto@Sun.COM goto done; 31919585STim.Szeto@Sun.COM } 31929585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 31939585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 31949585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 31959585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 31969585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 31979585STim.Szeto@Sun.COM if (ioctlRet != 0) { 31989585STim.Szeto@Sun.COM switch (errno) { 31999585STim.Szeto@Sun.COM case EBUSY: 32009585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 32019585STim.Szeto@Sun.COM break; 32029585STim.Szeto@Sun.COM case EPERM: 32039585STim.Szeto@Sun.COM case EACCES: 32049585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 32059585STim.Szeto@Sun.COM break; 32069585STim.Szeto@Sun.COM default: 32079585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 32089585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 32099585STim.Szeto@Sun.COM errno); 32109585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 32119585STim.Szeto@Sun.COM break; 32129585STim.Szeto@Sun.COM } 32139585STim.Szeto@Sun.COM goto done; 32149585STim.Szeto@Sun.COM } 32159585STim.Szeto@Sun.COM } 32169585STim.Szeto@Sun.COM 32179585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 32189585STim.Szeto@Sun.COM *groupProps = (stmfGroupProperties *)calloc(1, 32199585STim.Szeto@Sun.COM sizeof (stmfGroupProperties) * stmfIoctl.stmf_obuf_nentries); 32209585STim.Szeto@Sun.COM if (*groupProps == NULL) { 32219585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32229585STim.Szeto@Sun.COM goto done; 32239585STim.Szeto@Sun.COM } 32249585STim.Szeto@Sun.COM (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries; 32259585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 32269585STim.Szeto@Sun.COM (*groupProps)->name[i].identLength = 32279585STim.Szeto@Sun.COM iGroupMembers->ident_size; 32289585STim.Szeto@Sun.COM bcopy(iGroupMembers->ident, (*groupProps)->name[i].ident, 32299585STim.Szeto@Sun.COM iGroupMembers->ident_size); 32309585STim.Szeto@Sun.COM iGroupMembers++; 32319585STim.Szeto@Sun.COM } 32329585STim.Szeto@Sun.COM 32339585STim.Szeto@Sun.COM done: 32349585STim.Szeto@Sun.COM free(iGroupMembers); 32359585STim.Szeto@Sun.COM (void) close(fd); 32369585STim.Szeto@Sun.COM return (ret); 32379585STim.Szeto@Sun.COM } 32389585STim.Szeto@Sun.COM 32399585STim.Szeto@Sun.COM /* 32409585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 32419585STim.Szeto@Sun.COM */ 32429585STim.Szeto@Sun.COM static int 32439585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type) 32449585STim.Szeto@Sun.COM { 32459585STim.Szeto@Sun.COM int ret; 32469585STim.Szeto@Sun.COM 32479585STim.Szeto@Sun.COM if (groupList == NULL) { 32489585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 32499585STim.Szeto@Sun.COM } 32509585STim.Szeto@Sun.COM 32519585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 32529585STim.Szeto@Sun.COM ret = psGetHostGroupList(groupList); 32539585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 32549585STim.Szeto@Sun.COM ret = psGetTargetGroupList(groupList); 32559585STim.Szeto@Sun.COM } else { 32569585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 32579585STim.Szeto@Sun.COM } 32587836SJohn.Forte@Sun.COM switch (ret) { 32597836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 32607836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 32617836SJohn.Forte@Sun.COM break; 32627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 32637836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 32647836SJohn.Forte@Sun.COM break; 32657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 32667836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 32677836SJohn.Forte@Sun.COM break; 32687836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 32697836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 32707836SJohn.Forte@Sun.COM break; 32717836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 32727836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 32737836SJohn.Forte@Sun.COM break; 32747836SJohn.Forte@Sun.COM default: 32757836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 32767836SJohn.Forte@Sun.COM "stmfGetHostGroupList:psGetHostGroupList:error(%d)", 32777836SJohn.Forte@Sun.COM ret); 32787836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 32797836SJohn.Forte@Sun.COM break; 32807836SJohn.Forte@Sun.COM } 32817836SJohn.Forte@Sun.COM 32827836SJohn.Forte@Sun.COM return (ret); 32837836SJohn.Forte@Sun.COM } 32847836SJohn.Forte@Sun.COM 32857836SJohn.Forte@Sun.COM /* 32869585STim.Szeto@Sun.COM * stmfGetHostGroupList 32877836SJohn.Forte@Sun.COM * 32889585STim.Szeto@Sun.COM * Purpose: Retrieves the list of initiator group oids 32899585STim.Szeto@Sun.COM * 32909585STim.Szeto@Sun.COM * hostGroupList - pointer to pointer to hostGroupList structure 32919585STim.Szeto@Sun.COM * on success, this contains the host group list. 32927836SJohn.Forte@Sun.COM */ 32937836SJohn.Forte@Sun.COM int 32949585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList) 32959585STim.Szeto@Sun.COM { 32969585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 32979585STim.Szeto@Sun.COM 32989585STim.Szeto@Sun.COM if (hostGroupList == NULL) { 32999585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33009585STim.Szeto@Sun.COM } 33019585STim.Szeto@Sun.COM 33029585STim.Szeto@Sun.COM ret = groupListIoctl(hostGroupList, HOST_GROUP); 33039585STim.Szeto@Sun.COM return (ret); 33049585STim.Szeto@Sun.COM } 33059585STim.Szeto@Sun.COM 33069585STim.Szeto@Sun.COM 33079585STim.Szeto@Sun.COM /* 33089585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 33099585STim.Szeto@Sun.COM */ 33109585STim.Szeto@Sun.COM static int 33119585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName, 33129585STim.Szeto@Sun.COM stmfGroupProperties **groupProp, int type) 33137836SJohn.Forte@Sun.COM { 33147836SJohn.Forte@Sun.COM int ret; 33157836SJohn.Forte@Sun.COM 33169585STim.Szeto@Sun.COM if (groupName == NULL) { 33177836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 33187836SJohn.Forte@Sun.COM } 33197836SJohn.Forte@Sun.COM 33209585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 33219585STim.Szeto@Sun.COM ret = psGetHostGroupMemberList((char *)groupName, groupProp); 33229585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 33239585STim.Szeto@Sun.COM ret = psGetTargetGroupMemberList((char *)groupName, groupProp); 33249585STim.Szeto@Sun.COM } else { 33259585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33269585STim.Szeto@Sun.COM } 33277836SJohn.Forte@Sun.COM switch (ret) { 33287836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 33297836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 33307836SJohn.Forte@Sun.COM break; 33317836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 33327836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 33337836SJohn.Forte@Sun.COM break; 33347836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 33357836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 33367836SJohn.Forte@Sun.COM break; 33377836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33387836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33397836SJohn.Forte@Sun.COM break; 33407836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33417836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33427836SJohn.Forte@Sun.COM break; 33437836SJohn.Forte@Sun.COM default: 33447836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 33459585STim.Szeto@Sun.COM "iLoadGroupMembersFromPs:psGetHostGroupList:" 33469585STim.Szeto@Sun.COM "error(%d)", ret); 33477836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33487836SJohn.Forte@Sun.COM break; 33497836SJohn.Forte@Sun.COM } 33507836SJohn.Forte@Sun.COM 33517836SJohn.Forte@Sun.COM return (ret); 33527836SJohn.Forte@Sun.COM } 33537836SJohn.Forte@Sun.COM 33547836SJohn.Forte@Sun.COM /* 33559585STim.Szeto@Sun.COM * stmfGetHostGroupMembers 33569585STim.Szeto@Sun.COM * 33579585STim.Szeto@Sun.COM * Purpose: Retrieves the group properties for a host group 33589585STim.Szeto@Sun.COM * 33599585STim.Szeto@Sun.COM * groupName - name of group for which to retrieve host group members. 33609585STim.Szeto@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 33619585STim.Szeto@Sun.COM * on success, this contains the list of group members. 33629585STim.Szeto@Sun.COM */ 33639585STim.Szeto@Sun.COM int 33649585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName, 33659585STim.Szeto@Sun.COM stmfGroupProperties **groupProp) 33669585STim.Szeto@Sun.COM { 33679585STim.Szeto@Sun.COM int ret; 33689585STim.Szeto@Sun.COM 33699585STim.Szeto@Sun.COM if (groupName == NULL || groupProp == NULL) { 33709585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33719585STim.Szeto@Sun.COM } 33729585STim.Szeto@Sun.COM 33739585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP); 33749585STim.Szeto@Sun.COM 33759585STim.Szeto@Sun.COM return (ret); 33769585STim.Szeto@Sun.COM } 33779585STim.Szeto@Sun.COM 33789585STim.Szeto@Sun.COM /* 33797836SJohn.Forte@Sun.COM * stmfGetProviderData 33807836SJohn.Forte@Sun.COM * 33817836SJohn.Forte@Sun.COM * Purpose: Get provider data list 33827836SJohn.Forte@Sun.COM * 33837836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 33847836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 33857836SJohn.Forte@Sun.COM * retrieved. 33867836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 33877836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 33887836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 33897836SJohn.Forte@Sun.COM */ 33907836SJohn.Forte@Sun.COM int 33917836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType) 33927836SJohn.Forte@Sun.COM { 33937836SJohn.Forte@Sun.COM return (stmfGetProviderDataProt(providerName, nvl, providerType, 33947836SJohn.Forte@Sun.COM NULL)); 33957836SJohn.Forte@Sun.COM } 33967836SJohn.Forte@Sun.COM 33977836SJohn.Forte@Sun.COM /* 33987836SJohn.Forte@Sun.COM * stmfGetProviderDataProt 33997836SJohn.Forte@Sun.COM * 34007836SJohn.Forte@Sun.COM * Purpose: Get provider data list with token 34017836SJohn.Forte@Sun.COM * 34027836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 34037836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 34047836SJohn.Forte@Sun.COM * retrieved. 34057836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 34067836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 34077836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 34087836SJohn.Forte@Sun.COM * setToken - Returns the stale data token 34097836SJohn.Forte@Sun.COM */ 34107836SJohn.Forte@Sun.COM int 34117836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType, 34127836SJohn.Forte@Sun.COM uint64_t *setToken) 34137836SJohn.Forte@Sun.COM { 34147836SJohn.Forte@Sun.COM int ret; 34157836SJohn.Forte@Sun.COM 34167836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 34177836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34187836SJohn.Forte@Sun.COM } 34197836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 34207836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 34217836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34227836SJohn.Forte@Sun.COM } 34237836SJohn.Forte@Sun.COM /* call init */ 34247836SJohn.Forte@Sun.COM ret = initializeConfig(); 34257836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 34267836SJohn.Forte@Sun.COM return (ret); 34277836SJohn.Forte@Sun.COM } 34289585STim.Szeto@Sun.COM return (getProviderData(providerName, nvl, providerType, setToken)); 34297836SJohn.Forte@Sun.COM } 34307836SJohn.Forte@Sun.COM 34317836SJohn.Forte@Sun.COM /* 34327836SJohn.Forte@Sun.COM * stmfGetProviderDataList 34337836SJohn.Forte@Sun.COM * 34347836SJohn.Forte@Sun.COM * Purpose: Get the list of providers currently persisting data 34357836SJohn.Forte@Sun.COM * 34367836SJohn.Forte@Sun.COM * providerList - pointer to pointer to an stmfProviderList structure allocated 34377836SJohn.Forte@Sun.COM * by the caller. Will contain the list of providers on success. 34387836SJohn.Forte@Sun.COM */ 34397836SJohn.Forte@Sun.COM int 34407836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList) 34417836SJohn.Forte@Sun.COM { 34427836SJohn.Forte@Sun.COM int ret; 34437836SJohn.Forte@Sun.COM 34447836SJohn.Forte@Sun.COM ret = psGetProviderDataList(providerList); 34457836SJohn.Forte@Sun.COM switch (ret) { 34467836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 34477836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 34487836SJohn.Forte@Sun.COM break; 34497836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 34507836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 34517836SJohn.Forte@Sun.COM break; 34527836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 34537836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 34547836SJohn.Forte@Sun.COM break; 34557836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 34567836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 34577836SJohn.Forte@Sun.COM break; 34587836SJohn.Forte@Sun.COM default: 34597836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 34607836SJohn.Forte@Sun.COM "stmfGetProviderDataList:psGetProviderDataList" 34617836SJohn.Forte@Sun.COM ":error(%d)", ret); 34627836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 34637836SJohn.Forte@Sun.COM break; 34647836SJohn.Forte@Sun.COM } 34657836SJohn.Forte@Sun.COM 34667836SJohn.Forte@Sun.COM return (ret); 34677836SJohn.Forte@Sun.COM } 34687836SJohn.Forte@Sun.COM 34697836SJohn.Forte@Sun.COM 34707836SJohn.Forte@Sun.COM /* 34717836SJohn.Forte@Sun.COM * stmfGetSessionList 34727836SJohn.Forte@Sun.COM * 34737836SJohn.Forte@Sun.COM * Purpose: Retrieves the session list for a target (devid) 34747836SJohn.Forte@Sun.COM * 34757836SJohn.Forte@Sun.COM * devid - devid of target for which to retrieve session information. 34767836SJohn.Forte@Sun.COM * sessionList - pointer to pointer to stmfSessionList structure 34777836SJohn.Forte@Sun.COM * on success, this contains the list of initiator sessions. 34787836SJohn.Forte@Sun.COM */ 34797836SJohn.Forte@Sun.COM int 34807836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList) 34817836SJohn.Forte@Sun.COM { 34827836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 34837836SJohn.Forte@Sun.COM int fd; 34847836SJohn.Forte@Sun.COM int ioctlRet; 34857836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_SESSION_LIST; 34867836SJohn.Forte@Sun.COM int i; 34877836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 34887836SJohn.Forte@Sun.COM slist_scsi_session_t *fSessionList; 34897836SJohn.Forte@Sun.COM uint8_t ident[260]; 34907836SJohn.Forte@Sun.COM uint32_t fSessionListSize; 34917836SJohn.Forte@Sun.COM 34927836SJohn.Forte@Sun.COM if (sessionList == NULL || devid == NULL) { 34937836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 34947836SJohn.Forte@Sun.COM } 34957836SJohn.Forte@Sun.COM 34967836SJohn.Forte@Sun.COM /* call init */ 34977836SJohn.Forte@Sun.COM ret = initializeConfig(); 34987836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 34997836SJohn.Forte@Sun.COM return (ret); 35007836SJohn.Forte@Sun.COM } 35017836SJohn.Forte@Sun.COM 35027836SJohn.Forte@Sun.COM /* 35037836SJohn.Forte@Sun.COM * Open control node for stmf 35047836SJohn.Forte@Sun.COM */ 35057836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 35067836SJohn.Forte@Sun.COM return (ret); 35077836SJohn.Forte@Sun.COM 35087836SJohn.Forte@Sun.COM /* 35097836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 35107836SJohn.Forte@Sun.COM */ 35119585STim.Szeto@Sun.COM fSessionListSize = ALLOC_SESSION; 35127836SJohn.Forte@Sun.COM fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t)); 35137836SJohn.Forte@Sun.COM fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize); 35147836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 35157836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 35167836SJohn.Forte@Sun.COM } 35177836SJohn.Forte@Sun.COM 35187836SJohn.Forte@Sun.COM ident[IDENT_LENGTH_BYTE] = devid->identLength; 35197836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1], 35207836SJohn.Forte@Sun.COM devid->identLength); 35217836SJohn.Forte@Sun.COM 35227836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 35237836SJohn.Forte@Sun.COM /* 35247836SJohn.Forte@Sun.COM * Issue ioctl to get the session list 35257836SJohn.Forte@Sun.COM */ 35267836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 35277836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident; 35287836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ident); 35297836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 35307836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 35317836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35327836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 35337836SJohn.Forte@Sun.COM switch (errno) { 35347836SJohn.Forte@Sun.COM case EBUSY: 35357836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35367836SJohn.Forte@Sun.COM break; 35379585STim.Szeto@Sun.COM case EPERM: 35387836SJohn.Forte@Sun.COM case EACCES: 35397836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 35407836SJohn.Forte@Sun.COM break; 35417836SJohn.Forte@Sun.COM default: 35427836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 35437836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl errno(%d)", 35447836SJohn.Forte@Sun.COM errno); 35457836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 35467836SJohn.Forte@Sun.COM break; 35477836SJohn.Forte@Sun.COM } 35487836SJohn.Forte@Sun.COM goto done; 35497836SJohn.Forte@Sun.COM } 35507836SJohn.Forte@Sun.COM /* 35517836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 35527836SJohn.Forte@Sun.COM */ 35539585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) { 35547836SJohn.Forte@Sun.COM fSessionListSize = stmfIoctl.stmf_obuf_max_nentries * 35557836SJohn.Forte@Sun.COM sizeof (slist_scsi_session_t); 35567836SJohn.Forte@Sun.COM fSessionList = realloc(fSessionList, fSessionListSize); 35577836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 35587836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 35597836SJohn.Forte@Sun.COM } 35607836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 35617836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 35627836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35637836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 35647836SJohn.Forte@Sun.COM switch (errno) { 35657836SJohn.Forte@Sun.COM case EBUSY: 35667836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35677836SJohn.Forte@Sun.COM break; 35689585STim.Szeto@Sun.COM case EPERM: 35697836SJohn.Forte@Sun.COM case EACCES: 35707836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 35717836SJohn.Forte@Sun.COM break; 35727836SJohn.Forte@Sun.COM default: 35737836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 35747836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl " 35757836SJohn.Forte@Sun.COM "errno(%d)", errno); 35767836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 35777836SJohn.Forte@Sun.COM break; 35787836SJohn.Forte@Sun.COM } 35797836SJohn.Forte@Sun.COM goto done; 35807836SJohn.Forte@Sun.COM } 35817836SJohn.Forte@Sun.COM } 35827836SJohn.Forte@Sun.COM 35837836SJohn.Forte@Sun.COM /* 35847836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 35857836SJohn.Forte@Sun.COM */ 35867836SJohn.Forte@Sun.COM *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) + 35877836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession)); 35887836SJohn.Forte@Sun.COM if (*sessionList == NULL) { 35897836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 35907836SJohn.Forte@Sun.COM free(sessionList); 35917836SJohn.Forte@Sun.COM goto done; 35927836SJohn.Forte@Sun.COM } 35937836SJohn.Forte@Sun.COM 35947836SJohn.Forte@Sun.COM (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 35957836SJohn.Forte@Sun.COM 35967836SJohn.Forte@Sun.COM /* 35977836SJohn.Forte@Sun.COM * copy session info to caller's buffer 35987836SJohn.Forte@Sun.COM */ 35997836SJohn.Forte@Sun.COM for (i = 0; i < (*sessionList)->cnt; i++) { 36007836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.identLength = 36017836SJohn.Forte@Sun.COM fSessionList->initiator[IDENT_LENGTH_BYTE]; 36027836SJohn.Forte@Sun.COM bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]), 36037836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.ident, 36047836SJohn.Forte@Sun.COM STMF_IDENT_LENGTH); 36057836SJohn.Forte@Sun.COM bcopy(&(fSessionList->alias), 36067836SJohn.Forte@Sun.COM &((*sessionList)->session[i].alias), 36077836SJohn.Forte@Sun.COM sizeof ((*sessionList)->session[i].alias)); 36087836SJohn.Forte@Sun.COM bcopy(&(fSessionList++->creation_time), 36097836SJohn.Forte@Sun.COM &((*sessionList)->session[i].creationTime), 36107836SJohn.Forte@Sun.COM sizeof (time_t)); 36117836SJohn.Forte@Sun.COM } 36127836SJohn.Forte@Sun.COM done: 36137836SJohn.Forte@Sun.COM (void) close(fd); 36147836SJohn.Forte@Sun.COM return (ret); 36157836SJohn.Forte@Sun.COM } 36167836SJohn.Forte@Sun.COM 36177836SJohn.Forte@Sun.COM /* 36187836SJohn.Forte@Sun.COM * stmfGetTargetGroupList 36197836SJohn.Forte@Sun.COM * 36207836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target groups 36217836SJohn.Forte@Sun.COM * 36227836SJohn.Forte@Sun.COM * targetGroupList - pointer to a pointer to an stmfGroupList structure. On 36237836SJohn.Forte@Sun.COM * success, it contains the list of target groups. 36247836SJohn.Forte@Sun.COM */ 36257836SJohn.Forte@Sun.COM int 36267836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList) 36277836SJohn.Forte@Sun.COM { 36287836SJohn.Forte@Sun.COM int ret; 36297836SJohn.Forte@Sun.COM 36307836SJohn.Forte@Sun.COM if (targetGroupList == NULL) { 36317836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36327836SJohn.Forte@Sun.COM } 36337836SJohn.Forte@Sun.COM 36349585STim.Szeto@Sun.COM ret = groupListIoctl(targetGroupList, TARGET_GROUP); 36357836SJohn.Forte@Sun.COM return (ret); 36367836SJohn.Forte@Sun.COM } 36377836SJohn.Forte@Sun.COM 36387836SJohn.Forte@Sun.COM /* 36397836SJohn.Forte@Sun.COM * stmfGetTargetGroupMembers 36407836SJohn.Forte@Sun.COM * 36417836SJohn.Forte@Sun.COM * Purpose: Retrieves the group members for a target group 36427836SJohn.Forte@Sun.COM * 36437836SJohn.Forte@Sun.COM * groupName - name of target group for which to retrieve members. 36447836SJohn.Forte@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 36457836SJohn.Forte@Sun.COM * on success, this contains the list of group members. 36467836SJohn.Forte@Sun.COM */ 36477836SJohn.Forte@Sun.COM int 36487836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName, 36497836SJohn.Forte@Sun.COM stmfGroupProperties **groupProp) 36507836SJohn.Forte@Sun.COM { 36517836SJohn.Forte@Sun.COM int ret; 36527836SJohn.Forte@Sun.COM 36537836SJohn.Forte@Sun.COM if (groupName == NULL || groupProp == NULL) { 36547836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36557836SJohn.Forte@Sun.COM } 36567836SJohn.Forte@Sun.COM 36579585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP); 36587836SJohn.Forte@Sun.COM 36597836SJohn.Forte@Sun.COM return (ret); 36607836SJohn.Forte@Sun.COM } 36617836SJohn.Forte@Sun.COM 36627836SJohn.Forte@Sun.COM /* 36637836SJohn.Forte@Sun.COM * stmfGetTargetList 36647836SJohn.Forte@Sun.COM * 36657836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target ports 36667836SJohn.Forte@Sun.COM * 36677836SJohn.Forte@Sun.COM * targetList - pointer to a pointer to an stmfDevidList structure. 36687836SJohn.Forte@Sun.COM * On success, it contains the list of local ports (target). 36697836SJohn.Forte@Sun.COM */ 36707836SJohn.Forte@Sun.COM int 36717836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList) 36727836SJohn.Forte@Sun.COM { 36737836SJohn.Forte@Sun.COM int ret; 36747836SJohn.Forte@Sun.COM int fd; 36757836SJohn.Forte@Sun.COM int ioctlRet; 36767836SJohn.Forte@Sun.COM int i; 36777836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 36787836SJohn.Forte@Sun.COM /* framework target port list */ 36799585STim.Szeto@Sun.COM slist_target_port_t *fTargetList, *fTargetListP = NULL; 36807836SJohn.Forte@Sun.COM uint32_t fTargetListSize; 36817836SJohn.Forte@Sun.COM 36827836SJohn.Forte@Sun.COM if (targetList == NULL) { 36837836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36847836SJohn.Forte@Sun.COM } 36857836SJohn.Forte@Sun.COM 36867836SJohn.Forte@Sun.COM /* call init */ 36877836SJohn.Forte@Sun.COM ret = initializeConfig(); 36887836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 36897836SJohn.Forte@Sun.COM return (ret); 36907836SJohn.Forte@Sun.COM } 36917836SJohn.Forte@Sun.COM 36927836SJohn.Forte@Sun.COM /* 36937836SJohn.Forte@Sun.COM * Open control node for stmf 36947836SJohn.Forte@Sun.COM */ 36957836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 36967836SJohn.Forte@Sun.COM return (ret); 36977836SJohn.Forte@Sun.COM 36987836SJohn.Forte@Sun.COM /* 36997836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 37007836SJohn.Forte@Sun.COM */ 37019585STim.Szeto@Sun.COM fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t); 37028252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 37038252SJohn.Forte@Sun.COM (slist_target_port_t *)calloc(1, fTargetListSize); 37047836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 37059585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37067836SJohn.Forte@Sun.COM goto done; 37077836SJohn.Forte@Sun.COM } 37087836SJohn.Forte@Sun.COM 37097836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 37107836SJohn.Forte@Sun.COM /* 37118252SJohn.Forte@Sun.COM * Issue ioctl to retrieve target list 37127836SJohn.Forte@Sun.COM */ 37137836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 37147836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 37157836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 37167836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl); 37177836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37187836SJohn.Forte@Sun.COM switch (errno) { 37197836SJohn.Forte@Sun.COM case EBUSY: 37207836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37217836SJohn.Forte@Sun.COM break; 37229585STim.Szeto@Sun.COM case EPERM: 37237836SJohn.Forte@Sun.COM case EACCES: 37247836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37257836SJohn.Forte@Sun.COM break; 37267836SJohn.Forte@Sun.COM default: 37277836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37287836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", errno); 37297836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37307836SJohn.Forte@Sun.COM break; 37317836SJohn.Forte@Sun.COM } 37327836SJohn.Forte@Sun.COM goto done; 37337836SJohn.Forte@Sun.COM } 37347836SJohn.Forte@Sun.COM /* 37357836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 37367836SJohn.Forte@Sun.COM */ 37379585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) { 37387836SJohn.Forte@Sun.COM fTargetListSize = stmfIoctl.stmf_obuf_max_nentries * 37398116SJohn.Forte@Sun.COM sizeof (slist_target_port_t); 37408252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 37418252SJohn.Forte@Sun.COM realloc(fTargetList, fTargetListSize); 37427836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 37439585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37449585STim.Szeto@Sun.COM goto done; 37457836SJohn.Forte@Sun.COM } 37467836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 37477836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 37487836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, 37497836SJohn.Forte@Sun.COM &stmfIoctl); 37507836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37517836SJohn.Forte@Sun.COM switch (errno) { 37527836SJohn.Forte@Sun.COM case EBUSY: 37537836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37547836SJohn.Forte@Sun.COM break; 37559585STim.Szeto@Sun.COM case EPERM: 37567836SJohn.Forte@Sun.COM case EACCES: 37577836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37587836SJohn.Forte@Sun.COM break; 37597836SJohn.Forte@Sun.COM default: 37607836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37617836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", 37627836SJohn.Forte@Sun.COM errno); 37637836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37647836SJohn.Forte@Sun.COM break; 37657836SJohn.Forte@Sun.COM } 37667836SJohn.Forte@Sun.COM goto done; 37677836SJohn.Forte@Sun.COM } 37687836SJohn.Forte@Sun.COM } 37697836SJohn.Forte@Sun.COM 37707836SJohn.Forte@Sun.COM *targetList = (stmfDevidList *)calloc(1, 37717836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) + 37727836SJohn.Forte@Sun.COM sizeof (stmfDevidList)); 37739585STim.Szeto@Sun.COM if (*targetList == NULL) { 37749585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37759585STim.Szeto@Sun.COM goto done; 37769585STim.Szeto@Sun.COM } 37777836SJohn.Forte@Sun.COM 37787836SJohn.Forte@Sun.COM (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 37797836SJohn.Forte@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) { 37807836SJohn.Forte@Sun.COM (*targetList)->devid[i].identLength = 37817836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]; 37827836SJohn.Forte@Sun.COM bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1], 37837836SJohn.Forte@Sun.COM &(*targetList)->devid[i].ident, 37847836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]); 37857836SJohn.Forte@Sun.COM } 37867836SJohn.Forte@Sun.COM 37877836SJohn.Forte@Sun.COM done: 37887836SJohn.Forte@Sun.COM (void) close(fd); 37898252SJohn.Forte@Sun.COM free(fTargetListP); 37907836SJohn.Forte@Sun.COM return (ret); 37917836SJohn.Forte@Sun.COM } 37927836SJohn.Forte@Sun.COM 37937836SJohn.Forte@Sun.COM /* 37947836SJohn.Forte@Sun.COM * stmfGetTargetProperties 37957836SJohn.Forte@Sun.COM * 37967836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 37977836SJohn.Forte@Sun.COM * 37987836SJohn.Forte@Sun.COM * devid - devid of the target for which to retrieve properties 37997836SJohn.Forte@Sun.COM * targetProps - pointer to an stmfTargetProperties structure. 38007836SJohn.Forte@Sun.COM * On success, it contains the target properties for 38017836SJohn.Forte@Sun.COM * the specified devid. 38027836SJohn.Forte@Sun.COM */ 38037836SJohn.Forte@Sun.COM int 38047836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps) 38057836SJohn.Forte@Sun.COM { 38067836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 38077836SJohn.Forte@Sun.COM int fd; 38087836SJohn.Forte@Sun.COM int ioctlRet; 38097836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 38107836SJohn.Forte@Sun.COM sioc_target_port_props_t targetProperties; 38117836SJohn.Forte@Sun.COM 38127836SJohn.Forte@Sun.COM if (devid == NULL || targetProps == NULL) { 38137836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38147836SJohn.Forte@Sun.COM } 38157836SJohn.Forte@Sun.COM 38167836SJohn.Forte@Sun.COM /* call init */ 38177836SJohn.Forte@Sun.COM ret = initializeConfig(); 38187836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 38197836SJohn.Forte@Sun.COM return (ret); 38207836SJohn.Forte@Sun.COM } 38217836SJohn.Forte@Sun.COM 38227836SJohn.Forte@Sun.COM /* 38237836SJohn.Forte@Sun.COM * Open control node for stmf 38247836SJohn.Forte@Sun.COM */ 38257836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 38267836SJohn.Forte@Sun.COM return (ret); 38277836SJohn.Forte@Sun.COM 38287836SJohn.Forte@Sun.COM targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength; 38297836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1], 38307836SJohn.Forte@Sun.COM devid->identLength); 38317836SJohn.Forte@Sun.COM 38327836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 38337836SJohn.Forte@Sun.COM /* 38347836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 38357836SJohn.Forte@Sun.COM */ 38367836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 38377836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id); 38387836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id; 38397836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties; 38407836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (targetProperties); 38417836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES, 38427836SJohn.Forte@Sun.COM &stmfIoctl); 38437836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 38447836SJohn.Forte@Sun.COM switch (errno) { 38457836SJohn.Forte@Sun.COM case EBUSY: 38467836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 38477836SJohn.Forte@Sun.COM break; 38489585STim.Szeto@Sun.COM case EPERM: 38497836SJohn.Forte@Sun.COM case EACCES: 38507836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 38517836SJohn.Forte@Sun.COM break; 38527836SJohn.Forte@Sun.COM case ENOENT: 38537836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 38547836SJohn.Forte@Sun.COM break; 38557836SJohn.Forte@Sun.COM default: 38567836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 38577836SJohn.Forte@Sun.COM "stmfGetTargetProperties:ioctl errno(%d)", 38587836SJohn.Forte@Sun.COM errno); 38597836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 38607836SJohn.Forte@Sun.COM break; 38617836SJohn.Forte@Sun.COM } 38627836SJohn.Forte@Sun.COM goto done; 38637836SJohn.Forte@Sun.COM } 38647836SJohn.Forte@Sun.COM 38657836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_provider_name, targetProps->providerName, 38667836SJohn.Forte@Sun.COM sizeof (targetProperties.tgt_provider_name)); 38677836SJohn.Forte@Sun.COM if (targetProperties.tgt_state == STMF_STATE_ONLINE) { 38687836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINE; 38697836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) { 38707836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINE; 38717836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) { 38727836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINING; 38737836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) { 38747836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINING; 38757836SJohn.Forte@Sun.COM } 38767836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_alias, targetProps->alias, 38777836SJohn.Forte@Sun.COM sizeof (targetProps->alias)); 38787836SJohn.Forte@Sun.COM done: 38797836SJohn.Forte@Sun.COM (void) close(fd); 38807836SJohn.Forte@Sun.COM return (ret); 38817836SJohn.Forte@Sun.COM } 38827836SJohn.Forte@Sun.COM 38837836SJohn.Forte@Sun.COM /* 38847836SJohn.Forte@Sun.COM * stmfGetLogicalUnitList 38857836SJohn.Forte@Sun.COM * 38867836SJohn.Forte@Sun.COM * Purpose: Retrieves list of logical unit Object IDs 38877836SJohn.Forte@Sun.COM * 38887836SJohn.Forte@Sun.COM * luList - pointer to a pointer to a stmfGuidList structure. On success, 38897836SJohn.Forte@Sun.COM * it contains the list of logical unit guids. 38907836SJohn.Forte@Sun.COM * 38917836SJohn.Forte@Sun.COM */ 38927836SJohn.Forte@Sun.COM int 38937836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList) 38947836SJohn.Forte@Sun.COM { 38957836SJohn.Forte@Sun.COM int ret; 38967836SJohn.Forte@Sun.COM int fd; 38977836SJohn.Forte@Sun.COM int ioctlRet; 38987836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_LU_LIST; 38999585STim.Szeto@Sun.COM int i; 39007836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 39017836SJohn.Forte@Sun.COM slist_lu_t *fLuList; 39027836SJohn.Forte@Sun.COM uint32_t fLuListSize; 39039585STim.Szeto@Sun.COM uint32_t listCnt; 39047836SJohn.Forte@Sun.COM 39057836SJohn.Forte@Sun.COM if (luList == NULL) { 39067836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39077836SJohn.Forte@Sun.COM } 39087836SJohn.Forte@Sun.COM 39097836SJohn.Forte@Sun.COM /* call init */ 39107836SJohn.Forte@Sun.COM ret = initializeConfig(); 39117836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39127836SJohn.Forte@Sun.COM return (ret); 39137836SJohn.Forte@Sun.COM } 39147836SJohn.Forte@Sun.COM 39157836SJohn.Forte@Sun.COM /* 39167836SJohn.Forte@Sun.COM * Open control node for stmf 39177836SJohn.Forte@Sun.COM */ 39187836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 39197836SJohn.Forte@Sun.COM return (ret); 39207836SJohn.Forte@Sun.COM 39217836SJohn.Forte@Sun.COM /* 39227836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 39237836SJohn.Forte@Sun.COM */ 39249585STim.Szeto@Sun.COM fLuListSize = ALLOC_LU; 39257836SJohn.Forte@Sun.COM fLuListSize = fLuListSize * (sizeof (slist_lu_t)); 39267836SJohn.Forte@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 39277836SJohn.Forte@Sun.COM if (fLuList == NULL) { 39289585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 39299585STim.Szeto@Sun.COM goto done; 39307836SJohn.Forte@Sun.COM } 39317836SJohn.Forte@Sun.COM 39327836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 39337836SJohn.Forte@Sun.COM /* 39347836SJohn.Forte@Sun.COM * Issue ioctl to get the LU list 39357836SJohn.Forte@Sun.COM */ 39367836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 39377836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 39387836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 39397836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 39407836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39417836SJohn.Forte@Sun.COM switch (errno) { 39427836SJohn.Forte@Sun.COM case EBUSY: 39437836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39447836SJohn.Forte@Sun.COM break; 39459585STim.Szeto@Sun.COM case EPERM: 39467836SJohn.Forte@Sun.COM case EACCES: 39477836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39487836SJohn.Forte@Sun.COM break; 39497836SJohn.Forte@Sun.COM default: 39507836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39517836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:ioctl errno(%d)", 39527836SJohn.Forte@Sun.COM errno); 39537836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39547836SJohn.Forte@Sun.COM break; 39557836SJohn.Forte@Sun.COM } 39567836SJohn.Forte@Sun.COM goto done; 39577836SJohn.Forte@Sun.COM } 39587836SJohn.Forte@Sun.COM /* 39597836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 39607836SJohn.Forte@Sun.COM */ 39619585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) { 39627836SJohn.Forte@Sun.COM fLuListSize = stmfIoctl.stmf_obuf_max_nentries * 39637836SJohn.Forte@Sun.COM sizeof (slist_lu_t); 39649585STim.Szeto@Sun.COM free(fLuList); 39659585STim.Szeto@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 39667836SJohn.Forte@Sun.COM if (fLuList == NULL) { 39679585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 39689585STim.Szeto@Sun.COM goto done; 39697836SJohn.Forte@Sun.COM } 39707836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 39717836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 39727836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 39737836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39747836SJohn.Forte@Sun.COM switch (errno) { 39757836SJohn.Forte@Sun.COM case EBUSY: 39767836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39777836SJohn.Forte@Sun.COM break; 39789585STim.Szeto@Sun.COM case EPERM: 39797836SJohn.Forte@Sun.COM case EACCES: 39807836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39817836SJohn.Forte@Sun.COM break; 39827836SJohn.Forte@Sun.COM default: 39837836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39847836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:" 39857836SJohn.Forte@Sun.COM "ioctl errno(%d)", errno); 39867836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39877836SJohn.Forte@Sun.COM break; 39887836SJohn.Forte@Sun.COM } 39897836SJohn.Forte@Sun.COM goto done; 39907836SJohn.Forte@Sun.COM } 39917836SJohn.Forte@Sun.COM } 39927836SJohn.Forte@Sun.COM 39937836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39947836SJohn.Forte@Sun.COM goto done; 39957836SJohn.Forte@Sun.COM } 39967836SJohn.Forte@Sun.COM 39979585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 39987836SJohn.Forte@Sun.COM 39997836SJohn.Forte@Sun.COM /* 40007836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 40017836SJohn.Forte@Sun.COM */ 40027836SJohn.Forte@Sun.COM *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) + 40039585STim.Szeto@Sun.COM listCnt * sizeof (stmfGuid)); 40047836SJohn.Forte@Sun.COM if (*luList == NULL) { 40057836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 40067836SJohn.Forte@Sun.COM goto done; 40077836SJohn.Forte@Sun.COM } 40087836SJohn.Forte@Sun.COM 40099585STim.Szeto@Sun.COM (*luList)->cnt = listCnt; 40109585STim.Szeto@Sun.COM 40119585STim.Szeto@Sun.COM /* copy to caller's buffer */ 40129585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 40139585STim.Szeto@Sun.COM bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid, 40149585STim.Szeto@Sun.COM sizeof (stmfGuid)); 40159585STim.Szeto@Sun.COM } 40169585STim.Szeto@Sun.COM 40177836SJohn.Forte@Sun.COM /* 40189585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 40197836SJohn.Forte@Sun.COM */ 40209585STim.Szeto@Sun.COM qsort((void *)&((*luList)->guid[0]), (*luList)->cnt, 40219585STim.Szeto@Sun.COM sizeof (stmfGuid), guidCompare); 40227836SJohn.Forte@Sun.COM 40237836SJohn.Forte@Sun.COM done: 40247836SJohn.Forte@Sun.COM (void) close(fd); 40257836SJohn.Forte@Sun.COM /* 40267836SJohn.Forte@Sun.COM * free internal buffers 40277836SJohn.Forte@Sun.COM */ 40287836SJohn.Forte@Sun.COM free(fLuList); 40297836SJohn.Forte@Sun.COM return (ret); 40307836SJohn.Forte@Sun.COM } 40317836SJohn.Forte@Sun.COM 40327836SJohn.Forte@Sun.COM /* 40337836SJohn.Forte@Sun.COM * stmfGetLogicalUnitProperties 40347836SJohn.Forte@Sun.COM * 40357836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 40367836SJohn.Forte@Sun.COM * 40377836SJohn.Forte@Sun.COM * lu - guid of the logical unit for which to retrieve properties 40387836SJohn.Forte@Sun.COM * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success, 40397836SJohn.Forte@Sun.COM * it contains the logical unit properties for the specified guid. 40407836SJohn.Forte@Sun.COM */ 40417836SJohn.Forte@Sun.COM int 40427836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps) 40437836SJohn.Forte@Sun.COM { 40447836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 40457836SJohn.Forte@Sun.COM int stmfRet; 40467836SJohn.Forte@Sun.COM int fd; 40477836SJohn.Forte@Sun.COM int ioctlRet; 40487836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_GET_LU_PROPERTIES; 40497836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 40507836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 40517836SJohn.Forte@Sun.COM sioc_lu_props_t fLuProps; 40527836SJohn.Forte@Sun.COM 40539585STim.Szeto@Sun.COM if (lu == NULL || luProps == NULL) { 40549585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 40557836SJohn.Forte@Sun.COM } 40567836SJohn.Forte@Sun.COM 40577836SJohn.Forte@Sun.COM bzero(luProps, sizeof (stmfLogicalUnitProperties)); 40587836SJohn.Forte@Sun.COM 40597836SJohn.Forte@Sun.COM /* call init */ 40607836SJohn.Forte@Sun.COM ret = initializeConfig(); 40617836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 40627836SJohn.Forte@Sun.COM return (ret); 40637836SJohn.Forte@Sun.COM } 40647836SJohn.Forte@Sun.COM 40657836SJohn.Forte@Sun.COM /* 40667836SJohn.Forte@Sun.COM * Open control node for stmf 40677836SJohn.Forte@Sun.COM */ 40687836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 40697836SJohn.Forte@Sun.COM return (ret); 40707836SJohn.Forte@Sun.COM 40717836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 40727836SJohn.Forte@Sun.COM /* 40737836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 40747836SJohn.Forte@Sun.COM */ 40757836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 40767836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 40777836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 40787836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps; 40797836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (fLuProps); 40807836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40817836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40827836SJohn.Forte@Sun.COM switch (errno) { 40837836SJohn.Forte@Sun.COM case EBUSY: 40847836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40857836SJohn.Forte@Sun.COM break; 40869585STim.Szeto@Sun.COM case EPERM: 40877836SJohn.Forte@Sun.COM case EACCES: 40887836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40897836SJohn.Forte@Sun.COM break; 40907836SJohn.Forte@Sun.COM case ENOENT: 40917836SJohn.Forte@Sun.COM stmfRet = stmfGetViewEntryList(lu, 40927836SJohn.Forte@Sun.COM &viewEntryList); 40937836SJohn.Forte@Sun.COM if (stmfRet == STMF_STATUS_SUCCESS) { 40947836SJohn.Forte@Sun.COM luProps->status = 40957836SJohn.Forte@Sun.COM STMF_LOGICAL_UNIT_UNREGISTERED; 40967836SJohn.Forte@Sun.COM if (viewEntryList->cnt > 0) { 40977836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 40987836SJohn.Forte@Sun.COM } else { 40997836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 41007836SJohn.Forte@Sun.COM } 41017836SJohn.Forte@Sun.COM } else { 41027836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 41037836SJohn.Forte@Sun.COM } 41047836SJohn.Forte@Sun.COM stmfFreeMemory(viewEntryList); 41057836SJohn.Forte@Sun.COM break; 41067836SJohn.Forte@Sun.COM default: 41077836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 41087836SJohn.Forte@Sun.COM "stmfGetLogicalUnit:ioctl errno(%d)", 41097836SJohn.Forte@Sun.COM errno); 41107836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 41117836SJohn.Forte@Sun.COM break; 41127836SJohn.Forte@Sun.COM } 41137836SJohn.Forte@Sun.COM goto done; 41147836SJohn.Forte@Sun.COM } 41157836SJohn.Forte@Sun.COM 41167836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_provider_name, luProps->providerName, 41177836SJohn.Forte@Sun.COM sizeof (fLuProps.lu_provider_name)); 41187836SJohn.Forte@Sun.COM if (fLuProps.lu_state == STMF_STATE_ONLINE) { 41197836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINE; 41207836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) { 41217836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINE; 41227836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_ONLINING) { 41237836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINING; 41247836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) { 41257836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINING; 41267836SJohn.Forte@Sun.COM } 41277836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias)); 41287836SJohn.Forte@Sun.COM done: 41297836SJohn.Forte@Sun.COM (void) close(fd); 41307836SJohn.Forte@Sun.COM return (ret); 41317836SJohn.Forte@Sun.COM } 41327836SJohn.Forte@Sun.COM 41337836SJohn.Forte@Sun.COM /* 41347836SJohn.Forte@Sun.COM * stmfGetState 41357836SJohn.Forte@Sun.COM * 41367836SJohn.Forte@Sun.COM * Purpose: retrieve the current state of the stmf module 41377836SJohn.Forte@Sun.COM * 41387836SJohn.Forte@Sun.COM * state - pointer to stmfState structure allocated by the caller 41397836SJohn.Forte@Sun.COM * On success, contains the state of stmf 41407836SJohn.Forte@Sun.COM */ 41417836SJohn.Forte@Sun.COM int 41427836SJohn.Forte@Sun.COM stmfGetState(stmfState *state) 41437836SJohn.Forte@Sun.COM { 41447836SJohn.Forte@Sun.COM int ret; 41457836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 41467836SJohn.Forte@Sun.COM 41477836SJohn.Forte@Sun.COM if (state == NULL) { 41487836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 41497836SJohn.Forte@Sun.COM } 41507836SJohn.Forte@Sun.COM 41517836SJohn.Forte@Sun.COM ret = getStmfState(&iState); 41527836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 41537836SJohn.Forte@Sun.COM return (ret); 41547836SJohn.Forte@Sun.COM } 41557836SJohn.Forte@Sun.COM switch (iState.state) { 41567836SJohn.Forte@Sun.COM case STMF_STATE_ONLINE: 41577836SJohn.Forte@Sun.COM state->operationalState = 41587836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINE; 41597836SJohn.Forte@Sun.COM break; 41607836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINE: 41617836SJohn.Forte@Sun.COM state->operationalState = 41627836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINE; 41637836SJohn.Forte@Sun.COM break; 41647836SJohn.Forte@Sun.COM case STMF_STATE_ONLINING: 41657836SJohn.Forte@Sun.COM state->operationalState = 41667836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINING; 41677836SJohn.Forte@Sun.COM break; 41687836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINING: 41697836SJohn.Forte@Sun.COM state->operationalState = 41707836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINING; 41717836SJohn.Forte@Sun.COM break; 41727836SJohn.Forte@Sun.COM default: 41737836SJohn.Forte@Sun.COM state->operationalState = 41747836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_UNKNOWN; 41757836SJohn.Forte@Sun.COM break; 41767836SJohn.Forte@Sun.COM } 41777836SJohn.Forte@Sun.COM switch (iState.config_state) { 41787836SJohn.Forte@Sun.COM case STMF_CONFIG_NONE: 41797836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_NONE; 41807836SJohn.Forte@Sun.COM break; 41817836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT: 41827836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_INIT; 41837836SJohn.Forte@Sun.COM break; 41847836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT_DONE: 41857836SJohn.Forte@Sun.COM state->configState = 41867836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_INIT_DONE; 41877836SJohn.Forte@Sun.COM break; 41887836SJohn.Forte@Sun.COM default: 41897836SJohn.Forte@Sun.COM state->configState = 41907836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_UNKNOWN; 41917836SJohn.Forte@Sun.COM break; 41927836SJohn.Forte@Sun.COM } 41937836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 41947836SJohn.Forte@Sun.COM } 41957836SJohn.Forte@Sun.COM 41967836SJohn.Forte@Sun.COM /* 41977836SJohn.Forte@Sun.COM * stmfGetViewEntryList 41987836SJohn.Forte@Sun.COM * 41997836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of view entries for the specified 42007836SJohn.Forte@Sun.COM * logical unit. 42017836SJohn.Forte@Sun.COM * 42027836SJohn.Forte@Sun.COM * lu - the guid of the logical unit for which to retrieve the view entry list 42037836SJohn.Forte@Sun.COM * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On 42047836SJohn.Forte@Sun.COM * success, contains the list of view entries. 42057836SJohn.Forte@Sun.COM */ 42067836SJohn.Forte@Sun.COM int 42077836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList) 42087836SJohn.Forte@Sun.COM { 42097836SJohn.Forte@Sun.COM int ret; 42109585STim.Szeto@Sun.COM int fd; 42119585STim.Szeto@Sun.COM int ioctlRet; 42129585STim.Szeto@Sun.COM int cmd = STMF_IOCTL_LU_VE_LIST; 42139585STim.Szeto@Sun.COM int i; 42149585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 42159585STim.Szeto@Sun.COM stmf_view_op_entry_t *fVeList; 42169585STim.Szeto@Sun.COM uint32_t fVeListSize; 42179585STim.Szeto@Sun.COM uint32_t listCnt; 42187836SJohn.Forte@Sun.COM 42197836SJohn.Forte@Sun.COM if (lu == NULL || viewEntryList == NULL) { 42207836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 42217836SJohn.Forte@Sun.COM } 42227836SJohn.Forte@Sun.COM 42239585STim.Szeto@Sun.COM /* call init */ 42249585STim.Szeto@Sun.COM ret = initializeConfig(); 42259585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42269585STim.Szeto@Sun.COM return (ret); 42279585STim.Szeto@Sun.COM } 42289585STim.Szeto@Sun.COM 42299585STim.Szeto@Sun.COM /* 42309585STim.Szeto@Sun.COM * Open control node for stmf 42319585STim.Szeto@Sun.COM */ 42329585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 42339585STim.Szeto@Sun.COM return (ret); 42349585STim.Szeto@Sun.COM 42359585STim.Szeto@Sun.COM /* 42369585STim.Szeto@Sun.COM * Allocate ioctl input buffer 42379585STim.Szeto@Sun.COM */ 42389585STim.Szeto@Sun.COM fVeListSize = ALLOC_VE; 42399585STim.Szeto@Sun.COM fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t)); 42409585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 42419585STim.Szeto@Sun.COM if (fVeList == NULL) { 42429585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 42439585STim.Szeto@Sun.COM goto done; 42449585STim.Szeto@Sun.COM } 42459585STim.Szeto@Sun.COM 42469585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 42479585STim.Szeto@Sun.COM /* 42489585STim.Szeto@Sun.COM * Issue ioctl to get the LU list 42499585STim.Szeto@Sun.COM */ 42509585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 42519585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 42529585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 42539585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 42549585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 42559585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 42569585STim.Szeto@Sun.COM if (ioctlRet != 0) { 42579585STim.Szeto@Sun.COM switch (errno) { 42589585STim.Szeto@Sun.COM case EBUSY: 42599585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 42609585STim.Szeto@Sun.COM break; 42619585STim.Szeto@Sun.COM case EPERM: 42629585STim.Szeto@Sun.COM case EACCES: 42639585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 42649585STim.Szeto@Sun.COM break; 42659585STim.Szeto@Sun.COM default: 42669585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 42679585STim.Szeto@Sun.COM "stmfGetViewEntryList:ioctl errno(%d)", 42689585STim.Szeto@Sun.COM errno); 42699585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 42709585STim.Szeto@Sun.COM break; 42719585STim.Szeto@Sun.COM } 42729585STim.Szeto@Sun.COM goto done; 42739585STim.Szeto@Sun.COM } 42749585STim.Szeto@Sun.COM /* 42759585STim.Szeto@Sun.COM * Check whether input buffer was large enough 42769585STim.Szeto@Sun.COM */ 42779585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) { 42789585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 42799585STim.Szeto@Sun.COM fVeListSize = stmfIoctl.stmf_obuf_max_nentries * 42809585STim.Szeto@Sun.COM sizeof (stmf_view_op_entry_t); 42819585STim.Szeto@Sun.COM free(fVeList); 42829585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 42839585STim.Szeto@Sun.COM if (fVeList == NULL) { 42849585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 42859585STim.Szeto@Sun.COM } 42869585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 42879585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 42889585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 42899585STim.Szeto@Sun.COM if (ioctlRet != 0) { 42909585STim.Szeto@Sun.COM switch (errno) { 42919585STim.Szeto@Sun.COM case EBUSY: 42929585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 42939585STim.Szeto@Sun.COM break; 42949585STim.Szeto@Sun.COM case EPERM: 42959585STim.Szeto@Sun.COM case EACCES: 42969585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 42979585STim.Szeto@Sun.COM break; 42989585STim.Szeto@Sun.COM default: 42999585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 43009585STim.Szeto@Sun.COM "stmfGetLogicalUnitList:" 43019585STim.Szeto@Sun.COM "ioctl errno(%d)", errno); 43029585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 43039585STim.Szeto@Sun.COM break; 43049585STim.Szeto@Sun.COM } 43059585STim.Szeto@Sun.COM goto done; 43069585STim.Szeto@Sun.COM } 43079585STim.Szeto@Sun.COM } 43089585STim.Szeto@Sun.COM 43099585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 43109585STim.Szeto@Sun.COM goto done; 43119585STim.Szeto@Sun.COM } 43129585STim.Szeto@Sun.COM 43139585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_nentries == 0) { 43149585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 43159585STim.Szeto@Sun.COM goto done; 43169585STim.Szeto@Sun.COM } 43179585STim.Szeto@Sun.COM 43189585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 43199585STim.Szeto@Sun.COM 43209585STim.Szeto@Sun.COM /* 43219585STim.Szeto@Sun.COM * allocate caller's buffer with the final size 43229585STim.Szeto@Sun.COM */ 43239585STim.Szeto@Sun.COM *viewEntryList = (stmfViewEntryList *)calloc(1, 43249585STim.Szeto@Sun.COM sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry)); 43259585STim.Szeto@Sun.COM if (*viewEntryList == NULL) { 43269585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 43279585STim.Szeto@Sun.COM goto done; 43289585STim.Szeto@Sun.COM } 43299585STim.Szeto@Sun.COM 43309585STim.Szeto@Sun.COM (*viewEntryList)->cnt = listCnt; 43319585STim.Szeto@Sun.COM 43329585STim.Szeto@Sun.COM /* copy to caller's buffer */ 43339585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 43349585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndexValid = B_TRUE; 43359585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx; 43369585STim.Szeto@Sun.COM if (fVeList[i].ve_all_hosts == 1) { 43379585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allHosts = B_TRUE; 43389585STim.Szeto@Sun.COM } else { 43399585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_host_group.name, 43409585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].hostGroup, 43419585STim.Szeto@Sun.COM fVeList[i].ve_host_group.name_size); 43429585STim.Szeto@Sun.COM } 43439585STim.Szeto@Sun.COM if (fVeList[i].ve_all_targets == 1) { 43449585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allTargets = B_TRUE; 43459585STim.Szeto@Sun.COM } else { 43469585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_target_group.name, 43479585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].targetGroup, 43489585STim.Szeto@Sun.COM fVeList[i].ve_target_group.name_size); 43499585STim.Szeto@Sun.COM } 43509585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr, 43519585STim.Szeto@Sun.COM sizeof ((*viewEntryList)->ve[i].luNbr)); 43529585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].luNbrValid = B_TRUE; 43539585STim.Szeto@Sun.COM } 43549585STim.Szeto@Sun.COM 43559585STim.Szeto@Sun.COM /* 43569585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 43579585STim.Szeto@Sun.COM */ 43589585STim.Szeto@Sun.COM qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt, 43599585STim.Szeto@Sun.COM sizeof (stmfViewEntry), viewEntryCompare); 43609585STim.Szeto@Sun.COM 43619585STim.Szeto@Sun.COM done: 43629585STim.Szeto@Sun.COM (void) close(fd); 43639585STim.Szeto@Sun.COM /* 43649585STim.Szeto@Sun.COM * free internal buffers 43659585STim.Szeto@Sun.COM */ 43669585STim.Szeto@Sun.COM free(fVeList); 43677836SJohn.Forte@Sun.COM return (ret); 43687836SJohn.Forte@Sun.COM } 43697836SJohn.Forte@Sun.COM 43709585STim.Szeto@Sun.COM 43717836SJohn.Forte@Sun.COM /* 43727836SJohn.Forte@Sun.COM * loadHostGroups 43737836SJohn.Forte@Sun.COM * 43747836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the host groups into stmf 43757836SJohn.Forte@Sun.COM * 43767836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 43777836SJohn.Forte@Sun.COM * groupList - populated host group list 43787836SJohn.Forte@Sun.COM */ 43797836SJohn.Forte@Sun.COM static int 43807836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList) 43817836SJohn.Forte@Sun.COM { 43827836SJohn.Forte@Sun.COM int i, j; 43837836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 43847836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 43857836SJohn.Forte@Sun.COM 43867836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 43877836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 43887836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 43897836SJohn.Forte@Sun.COM goto out; 43907836SJohn.Forte@Sun.COM } 43919585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 43929585STim.Szeto@Sun.COM &groupProps, HOST_GROUP); 43937836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 43947836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, 43957836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 43967836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 43977836SJohn.Forte@Sun.COM goto out; 43987836SJohn.Forte@Sun.COM } 43997836SJohn.Forte@Sun.COM } 44007836SJohn.Forte@Sun.COM } 44017836SJohn.Forte@Sun.COM 44027836SJohn.Forte@Sun.COM 44037836SJohn.Forte@Sun.COM out: 44047836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 44057836SJohn.Forte@Sun.COM return (ret); 44067836SJohn.Forte@Sun.COM } 44077836SJohn.Forte@Sun.COM 44087836SJohn.Forte@Sun.COM /* 44097836SJohn.Forte@Sun.COM * loadTargetGroups 44107836SJohn.Forte@Sun.COM * 44117836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the target groups into stmf 44127836SJohn.Forte@Sun.COM * 44137836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 44147836SJohn.Forte@Sun.COM * groupList - populated target group list. 44157836SJohn.Forte@Sun.COM */ 44167836SJohn.Forte@Sun.COM static int 44177836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList) 44187836SJohn.Forte@Sun.COM { 44197836SJohn.Forte@Sun.COM int i, j; 44207836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 44217836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 44227836SJohn.Forte@Sun.COM 44237836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 44247836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 44257836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 44267836SJohn.Forte@Sun.COM goto out; 44277836SJohn.Forte@Sun.COM } 44289585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 44299585STim.Szeto@Sun.COM &groupProps, TARGET_GROUP); 44307836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 44317836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 44327836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 44337836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 44347836SJohn.Forte@Sun.COM goto out; 44357836SJohn.Forte@Sun.COM } 44367836SJohn.Forte@Sun.COM } 44377836SJohn.Forte@Sun.COM } 44387836SJohn.Forte@Sun.COM 44397836SJohn.Forte@Sun.COM 44407836SJohn.Forte@Sun.COM out: 44417836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 44427836SJohn.Forte@Sun.COM return (ret); 44437836SJohn.Forte@Sun.COM } 44447836SJohn.Forte@Sun.COM 44457836SJohn.Forte@Sun.COM 44467836SJohn.Forte@Sun.COM /* 44477836SJohn.Forte@Sun.COM * loadStore 44487836SJohn.Forte@Sun.COM * 44497836SJohn.Forte@Sun.COM * Purpose: Load the configuration data from the store 44507836SJohn.Forte@Sun.COM * 44517836SJohn.Forte@Sun.COM * First load the host groups and target groups, then the view entries 44527836SJohn.Forte@Sun.COM * and finally the provider data 44537836SJohn.Forte@Sun.COM * 44547836SJohn.Forte@Sun.COM * fd - file descriptor of control node for stmf. 44557836SJohn.Forte@Sun.COM */ 44567836SJohn.Forte@Sun.COM static int 44577836SJohn.Forte@Sun.COM loadStore(int fd) 44587836SJohn.Forte@Sun.COM { 44597836SJohn.Forte@Sun.COM int ret; 44607836SJohn.Forte@Sun.COM int i, j; 44617836SJohn.Forte@Sun.COM stmfGroupList *groupList = NULL; 44627836SJohn.Forte@Sun.COM stmfGuidList *guidList = NULL; 44637836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 44647836SJohn.Forte@Sun.COM stmfProviderList *providerList = NULL; 44657836SJohn.Forte@Sun.COM int providerType; 44667836SJohn.Forte@Sun.COM nvlist_t *nvl = NULL; 44677836SJohn.Forte@Sun.COM 44687836SJohn.Forte@Sun.COM 44697836SJohn.Forte@Sun.COM 44707836SJohn.Forte@Sun.COM /* load host groups */ 44719585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, HOST_GROUP); 44727836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44737836SJohn.Forte@Sun.COM return (ret); 44747836SJohn.Forte@Sun.COM } 44757836SJohn.Forte@Sun.COM ret = loadHostGroups(fd, groupList); 44767836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44777836SJohn.Forte@Sun.COM goto out; 44787836SJohn.Forte@Sun.COM } 44797836SJohn.Forte@Sun.COM 44807836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 44817836SJohn.Forte@Sun.COM groupList = NULL; 44827836SJohn.Forte@Sun.COM 44837836SJohn.Forte@Sun.COM /* load target groups */ 44849585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, TARGET_GROUP); 44857836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44867836SJohn.Forte@Sun.COM goto out; 44877836SJohn.Forte@Sun.COM } 44887836SJohn.Forte@Sun.COM ret = loadTargetGroups(fd, groupList); 44897836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 44907836SJohn.Forte@Sun.COM goto out; 44917836SJohn.Forte@Sun.COM } 44927836SJohn.Forte@Sun.COM 44937836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 44947836SJohn.Forte@Sun.COM groupList = NULL; 44957836SJohn.Forte@Sun.COM 44967836SJohn.Forte@Sun.COM /* Get the guid list */ 44977836SJohn.Forte@Sun.COM ret = psGetLogicalUnitList(&guidList); 44987836SJohn.Forte@Sun.COM switch (ret) { 44997836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45007836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45017836SJohn.Forte@Sun.COM break; 45027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45037836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45047836SJohn.Forte@Sun.COM break; 45057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45067836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45077836SJohn.Forte@Sun.COM break; 45087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45097836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45107836SJohn.Forte@Sun.COM break; 45117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45127836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45137836SJohn.Forte@Sun.COM break; 45147836SJohn.Forte@Sun.COM default: 45157836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45167836SJohn.Forte@Sun.COM break; 45177836SJohn.Forte@Sun.COM } 45187836SJohn.Forte@Sun.COM 45197836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45207836SJohn.Forte@Sun.COM goto out; 45217836SJohn.Forte@Sun.COM } 45227836SJohn.Forte@Sun.COM 45237836SJohn.Forte@Sun.COM /* 45247836SJohn.Forte@Sun.COM * We have the guid list, now get the corresponding 45257836SJohn.Forte@Sun.COM * view entries for each guid 45267836SJohn.Forte@Sun.COM */ 45277836SJohn.Forte@Sun.COM for (i = 0; i < guidList->cnt; i++) { 45287836SJohn.Forte@Sun.COM ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList); 45297836SJohn.Forte@Sun.COM switch (ret) { 45307836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45317836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45327836SJohn.Forte@Sun.COM break; 45337836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45347836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45357836SJohn.Forte@Sun.COM break; 45367836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45377836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45387836SJohn.Forte@Sun.COM break; 45397836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45407836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45417836SJohn.Forte@Sun.COM break; 45427836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45437836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45447836SJohn.Forte@Sun.COM break; 45457836SJohn.Forte@Sun.COM default: 45467836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45477836SJohn.Forte@Sun.COM break; 45487836SJohn.Forte@Sun.COM } 45497836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45507836SJohn.Forte@Sun.COM goto out; 45517836SJohn.Forte@Sun.COM } 45527836SJohn.Forte@Sun.COM for (j = 0; j < viewEntryList->cnt; j++) { 45537836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, &guidList->guid[i], 45547836SJohn.Forte@Sun.COM &viewEntryList->ve[j]); 45557836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45567836SJohn.Forte@Sun.COM goto out; 45577836SJohn.Forte@Sun.COM } 45587836SJohn.Forte@Sun.COM } 45597836SJohn.Forte@Sun.COM } 45607836SJohn.Forte@Sun.COM 45617836SJohn.Forte@Sun.COM /* get the list of providers that have data */ 45627836SJohn.Forte@Sun.COM ret = psGetProviderDataList(&providerList); 45637836SJohn.Forte@Sun.COM switch (ret) { 45647836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45657836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45667836SJohn.Forte@Sun.COM break; 45677836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45687836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45697836SJohn.Forte@Sun.COM break; 45707836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45717836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45727836SJohn.Forte@Sun.COM break; 45737836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45747836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45757836SJohn.Forte@Sun.COM break; 45767836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45777836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45787836SJohn.Forte@Sun.COM break; 45797836SJohn.Forte@Sun.COM default: 45807836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45817836SJohn.Forte@Sun.COM break; 45827836SJohn.Forte@Sun.COM } 45837836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45847836SJohn.Forte@Sun.COM goto out; 45857836SJohn.Forte@Sun.COM } 45867836SJohn.Forte@Sun.COM 45877836SJohn.Forte@Sun.COM for (i = 0; i < providerList->cnt; i++) { 45887836SJohn.Forte@Sun.COM providerType = providerList->provider[i].providerType; 45897836SJohn.Forte@Sun.COM ret = psGetProviderData(providerList->provider[i].name, 45907836SJohn.Forte@Sun.COM &nvl, providerType, NULL); 45917836SJohn.Forte@Sun.COM switch (ret) { 45927836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45937836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45947836SJohn.Forte@Sun.COM break; 45957836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45967836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45977836SJohn.Forte@Sun.COM break; 45987836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45997836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46007836SJohn.Forte@Sun.COM break; 46017836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46027836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46037836SJohn.Forte@Sun.COM break; 46047836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46057836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46067836SJohn.Forte@Sun.COM break; 46077836SJohn.Forte@Sun.COM default: 46087836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46097836SJohn.Forte@Sun.COM break; 46107836SJohn.Forte@Sun.COM } 46117836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46127836SJohn.Forte@Sun.COM goto out; 46137836SJohn.Forte@Sun.COM } 46147836SJohn.Forte@Sun.COM 46157836SJohn.Forte@Sun.COM /* call setProviderData */ 46167836SJohn.Forte@Sun.COM ret = setProviderData(fd, providerList->provider[i].name, nvl, 46179585STim.Szeto@Sun.COM providerType, NULL); 46187836SJohn.Forte@Sun.COM switch (ret) { 46197836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 46207836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46217836SJohn.Forte@Sun.COM break; 46227836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 46237836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46247836SJohn.Forte@Sun.COM break; 46257836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 46267836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46277836SJohn.Forte@Sun.COM break; 46287836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46297836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46307836SJohn.Forte@Sun.COM break; 46317836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46327836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46337836SJohn.Forte@Sun.COM break; 46347836SJohn.Forte@Sun.COM default: 46357836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46367836SJohn.Forte@Sun.COM break; 46377836SJohn.Forte@Sun.COM } 46387836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46397836SJohn.Forte@Sun.COM goto out; 46407836SJohn.Forte@Sun.COM } 46417836SJohn.Forte@Sun.COM 46427836SJohn.Forte@Sun.COM nvlist_free(nvl); 46437836SJohn.Forte@Sun.COM nvl = NULL; 46447836SJohn.Forte@Sun.COM } 46457836SJohn.Forte@Sun.COM out: 46467836SJohn.Forte@Sun.COM if (groupList != NULL) { 46477836SJohn.Forte@Sun.COM free(groupList); 46487836SJohn.Forte@Sun.COM } 46497836SJohn.Forte@Sun.COM if (guidList != NULL) { 46507836SJohn.Forte@Sun.COM free(guidList); 46517836SJohn.Forte@Sun.COM } 46527836SJohn.Forte@Sun.COM if (viewEntryList != NULL) { 46537836SJohn.Forte@Sun.COM free(viewEntryList); 46547836SJohn.Forte@Sun.COM } 46557836SJohn.Forte@Sun.COM if (nvl != NULL) { 46567836SJohn.Forte@Sun.COM nvlist_free(nvl); 46577836SJohn.Forte@Sun.COM } 46587836SJohn.Forte@Sun.COM return (ret); 46597836SJohn.Forte@Sun.COM } 46607836SJohn.Forte@Sun.COM 46617836SJohn.Forte@Sun.COM /* 46627836SJohn.Forte@Sun.COM * stmfLoadConfig 46637836SJohn.Forte@Sun.COM * 46647836SJohn.Forte@Sun.COM * Purpose - load the configuration data from smf into stmf 46657836SJohn.Forte@Sun.COM * 46667836SJohn.Forte@Sun.COM */ 46677836SJohn.Forte@Sun.COM int 46687836SJohn.Forte@Sun.COM stmfLoadConfig(void) 46697836SJohn.Forte@Sun.COM { 46709585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 46717836SJohn.Forte@Sun.COM int fd; 46727836SJohn.Forte@Sun.COM stmf_state_desc_t stmfStateSet; 46737836SJohn.Forte@Sun.COM stmfState state; 46747836SJohn.Forte@Sun.COM 46759585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 46769585STim.Szeto@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 46779585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 46789585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) 46799585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 46809585STim.Szeto@Sun.COM return (ret); 46819585STim.Szeto@Sun.COM } 46829585STim.Szeto@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 46839585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46849585STim.Szeto@Sun.COM goto done; 46859585STim.Szeto@Sun.COM } 46869585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 46879585STim.Szeto@Sun.COM goto done; 46889585STim.Szeto@Sun.COM } 46897836SJohn.Forte@Sun.COM 46907836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 46917836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 46927836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 46937836SJohn.Forte@Sun.COM } 46947836SJohn.Forte@Sun.COM 46957836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 46967836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 46977836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 46987836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 46997836SJohn.Forte@Sun.COM } 47007836SJohn.Forte@Sun.COM } else { 47017836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 47027836SJohn.Forte@Sun.COM } 47037836SJohn.Forte@Sun.COM 47047836SJohn.Forte@Sun.COM 47057836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 47067836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 47077836SJohn.Forte@Sun.COM 47087836SJohn.Forte@Sun.COM /* 47097836SJohn.Forte@Sun.COM * Open control node for stmf 47107836SJohn.Forte@Sun.COM */ 47117836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 47127836SJohn.Forte@Sun.COM return (ret); 47137836SJohn.Forte@Sun.COM 47147836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 47157836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47167836SJohn.Forte@Sun.COM goto done; 47177836SJohn.Forte@Sun.COM } 47187836SJohn.Forte@Sun.COM 47197836SJohn.Forte@Sun.COM /* Load the persistent configuration data */ 47207836SJohn.Forte@Sun.COM ret = loadStore(fd); 47217836SJohn.Forte@Sun.COM if (ret != 0) { 47227836SJohn.Forte@Sun.COM goto done; 47237836SJohn.Forte@Sun.COM } 47247836SJohn.Forte@Sun.COM 47257836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 47267836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 47277836SJohn.Forte@Sun.COM 47287836SJohn.Forte@Sun.COM done: 47297836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 47307836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 47317836SJohn.Forte@Sun.COM } 47327836SJohn.Forte@Sun.COM (void) close(fd); 47337836SJohn.Forte@Sun.COM return (ret); 47347836SJohn.Forte@Sun.COM } 47357836SJohn.Forte@Sun.COM 47369585STim.Szeto@Sun.COM 47377836SJohn.Forte@Sun.COM /* 47387836SJohn.Forte@Sun.COM * getStmfState 47397836SJohn.Forte@Sun.COM * 47407836SJohn.Forte@Sun.COM * stmfState - pointer to stmf_state_desc_t structure. Will contain the state 47417836SJohn.Forte@Sun.COM * information of the stmf service on success. 47427836SJohn.Forte@Sun.COM */ 47437836SJohn.Forte@Sun.COM static int 47447836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState) 47457836SJohn.Forte@Sun.COM { 47467836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 47477836SJohn.Forte@Sun.COM int fd; 47487836SJohn.Forte@Sun.COM int ioctlRet; 47497836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 47507836SJohn.Forte@Sun.COM 47517836SJohn.Forte@Sun.COM /* 47527836SJohn.Forte@Sun.COM * Open control node for stmf 47537836SJohn.Forte@Sun.COM */ 47547836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 47557836SJohn.Forte@Sun.COM return (ret); 47567836SJohn.Forte@Sun.COM 47577836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 47587836SJohn.Forte@Sun.COM /* 47597836SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 47607836SJohn.Forte@Sun.COM */ 47617836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 47627836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 47637836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 47647836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t); 47657836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState; 47667836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl); 47677836SJohn.Forte@Sun.COM 47687836SJohn.Forte@Sun.COM (void) close(fd); 47697836SJohn.Forte@Sun.COM 47707836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 47717836SJohn.Forte@Sun.COM switch (errno) { 47727836SJohn.Forte@Sun.COM case EBUSY: 47737836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 47747836SJohn.Forte@Sun.COM break; 47757836SJohn.Forte@Sun.COM case EPERM: 47767836SJohn.Forte@Sun.COM case EACCES: 47777836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 47787836SJohn.Forte@Sun.COM break; 47797836SJohn.Forte@Sun.COM default: 47807836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 47817836SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 47827836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 47837836SJohn.Forte@Sun.COM break; 47847836SJohn.Forte@Sun.COM } 47857836SJohn.Forte@Sun.COM } 47867836SJohn.Forte@Sun.COM return (ret); 47877836SJohn.Forte@Sun.COM } 47887836SJohn.Forte@Sun.COM 47897836SJohn.Forte@Sun.COM 47907836SJohn.Forte@Sun.COM /* 47917836SJohn.Forte@Sun.COM * setStmfState 47927836SJohn.Forte@Sun.COM * 47937836SJohn.Forte@Sun.COM * stmfState - pointer to caller set state structure 47947836SJohn.Forte@Sun.COM * objectType - one of: 47957836SJohn.Forte@Sun.COM * LOGICAL_UNIT_TYPE 47967836SJohn.Forte@Sun.COM * TARGET_TYPE 47977836SJohn.Forte@Sun.COM * STMF_SERVICE_TYPE 47987836SJohn.Forte@Sun.COM */ 47997836SJohn.Forte@Sun.COM static int 48007836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType) 48017836SJohn.Forte@Sun.COM { 48027836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 48037836SJohn.Forte@Sun.COM int ioctlRet; 48047836SJohn.Forte@Sun.COM int cmd; 48057836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 48067836SJohn.Forte@Sun.COM 48077836SJohn.Forte@Sun.COM switch (objectType) { 48087836SJohn.Forte@Sun.COM case LOGICAL_UNIT_TYPE: 48097836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_LU_STATE; 48107836SJohn.Forte@Sun.COM break; 48117836SJohn.Forte@Sun.COM case TARGET_TYPE: 48127836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_TARGET_PORT_STATE; 48137836SJohn.Forte@Sun.COM break; 48147836SJohn.Forte@Sun.COM case STMF_SERVICE_TYPE: 48157836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_STMF_STATE; 48167836SJohn.Forte@Sun.COM break; 48177836SJohn.Forte@Sun.COM default: 48187836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48197836SJohn.Forte@Sun.COM goto done; 48207836SJohn.Forte@Sun.COM } 48217836SJohn.Forte@Sun.COM 48227836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 48237836SJohn.Forte@Sun.COM /* 48247836SJohn.Forte@Sun.COM * Issue ioctl to set the stmf state 48257836SJohn.Forte@Sun.COM */ 48267836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 48277836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 48287836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 48297836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 48307836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 48317836SJohn.Forte@Sun.COM switch (errno) { 48327836SJohn.Forte@Sun.COM case EBUSY: 48337836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48347836SJohn.Forte@Sun.COM break; 48359585STim.Szeto@Sun.COM case EPERM: 48367836SJohn.Forte@Sun.COM case EACCES: 48377836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 48387836SJohn.Forte@Sun.COM break; 48397836SJohn.Forte@Sun.COM case ENOENT: 48407836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 48417836SJohn.Forte@Sun.COM break; 48427836SJohn.Forte@Sun.COM default: 48437836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 48447836SJohn.Forte@Sun.COM "setStmfState:ioctl errno(%d)", errno); 48457836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48467836SJohn.Forte@Sun.COM break; 48477836SJohn.Forte@Sun.COM } 48487836SJohn.Forte@Sun.COM } 48497836SJohn.Forte@Sun.COM done: 48507836SJohn.Forte@Sun.COM return (ret); 48517836SJohn.Forte@Sun.COM } 48527836SJohn.Forte@Sun.COM 48537836SJohn.Forte@Sun.COM /* 48547836SJohn.Forte@Sun.COM * stmfOnline 48557836SJohn.Forte@Sun.COM * 48567836SJohn.Forte@Sun.COM * Purpose: Online stmf service 48577836SJohn.Forte@Sun.COM * 48587836SJohn.Forte@Sun.COM */ 48597836SJohn.Forte@Sun.COM int 48607836SJohn.Forte@Sun.COM stmfOnline(void) 48617836SJohn.Forte@Sun.COM { 48627836SJohn.Forte@Sun.COM int ret; 48637836SJohn.Forte@Sun.COM int fd; 48647836SJohn.Forte@Sun.COM stmfState state; 48657836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 48667836SJohn.Forte@Sun.COM 48677836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 48687836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 48697836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 48707836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 48717836SJohn.Forte@Sun.COM } 48727836SJohn.Forte@Sun.COM } else { 48737836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 48747836SJohn.Forte@Sun.COM } 48757836SJohn.Forte@Sun.COM iState.state = STMF_STATE_ONLINE; 48767836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 48777836SJohn.Forte@Sun.COM /* 48787836SJohn.Forte@Sun.COM * Open control node for stmf 48797836SJohn.Forte@Sun.COM * to make call to setStmfState() 48807836SJohn.Forte@Sun.COM */ 48817836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 48827836SJohn.Forte@Sun.COM return (ret); 48837836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 48847836SJohn.Forte@Sun.COM (void) close(fd); 48857836SJohn.Forte@Sun.COM return (ret); 48867836SJohn.Forte@Sun.COM } 48877836SJohn.Forte@Sun.COM 48887836SJohn.Forte@Sun.COM /* 48897836SJohn.Forte@Sun.COM * stmfOffline 48907836SJohn.Forte@Sun.COM * 48917836SJohn.Forte@Sun.COM * Purpose: Offline stmf service 48927836SJohn.Forte@Sun.COM * 48937836SJohn.Forte@Sun.COM */ 48947836SJohn.Forte@Sun.COM int 48957836SJohn.Forte@Sun.COM stmfOffline(void) 48967836SJohn.Forte@Sun.COM { 48977836SJohn.Forte@Sun.COM int ret; 48987836SJohn.Forte@Sun.COM int fd; 48997836SJohn.Forte@Sun.COM stmfState state; 49007836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 49017836SJohn.Forte@Sun.COM 49027836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 49037836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 49047836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 49057836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_OFFLINE); 49067836SJohn.Forte@Sun.COM } 49077836SJohn.Forte@Sun.COM } else { 49087836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 49097836SJohn.Forte@Sun.COM } 49107836SJohn.Forte@Sun.COM iState.state = STMF_STATE_OFFLINE; 49117836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 49127836SJohn.Forte@Sun.COM 49137836SJohn.Forte@Sun.COM /* 49147836SJohn.Forte@Sun.COM * Open control node for stmf 49157836SJohn.Forte@Sun.COM * to make call to setStmfState() 49167836SJohn.Forte@Sun.COM */ 49177836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49187836SJohn.Forte@Sun.COM return (ret); 49197836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 49207836SJohn.Forte@Sun.COM (void) close(fd); 49217836SJohn.Forte@Sun.COM return (ret); 49227836SJohn.Forte@Sun.COM } 49237836SJohn.Forte@Sun.COM 49247836SJohn.Forte@Sun.COM 49257836SJohn.Forte@Sun.COM /* 49267836SJohn.Forte@Sun.COM * stmfOfflineTarget 49277836SJohn.Forte@Sun.COM * 49287836SJohn.Forte@Sun.COM * Purpose: Change state of target to offline 49297836SJohn.Forte@Sun.COM * 49307836SJohn.Forte@Sun.COM * devid - devid of the target to offline 49317836SJohn.Forte@Sun.COM */ 49327836SJohn.Forte@Sun.COM int 49337836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid) 49347836SJohn.Forte@Sun.COM { 49357836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 49367836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49377836SJohn.Forte@Sun.COM int fd; 49387836SJohn.Forte@Sun.COM 49397836SJohn.Forte@Sun.COM if (devid == NULL) { 49407836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 49417836SJohn.Forte@Sun.COM } 49427836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 49437836SJohn.Forte@Sun.COM 49447836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_OFFLINE; 49457836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 49467836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 49477836SJohn.Forte@Sun.COM devid->identLength); 49487836SJohn.Forte@Sun.COM /* 49497836SJohn.Forte@Sun.COM * Open control node for stmf 49507836SJohn.Forte@Sun.COM * to make call to setStmfState() 49517836SJohn.Forte@Sun.COM */ 49527836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49537836SJohn.Forte@Sun.COM return (ret); 49547836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 49557836SJohn.Forte@Sun.COM (void) close(fd); 49567836SJohn.Forte@Sun.COM return (ret); 49577836SJohn.Forte@Sun.COM } 49587836SJohn.Forte@Sun.COM 49597836SJohn.Forte@Sun.COM /* 49607836SJohn.Forte@Sun.COM * stmfOfflineLogicalUnit 49617836SJohn.Forte@Sun.COM * 49627836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to offline 49637836SJohn.Forte@Sun.COM * 49647836SJohn.Forte@Sun.COM * lu - guid of the logical unit to offline 49657836SJohn.Forte@Sun.COM */ 49667836SJohn.Forte@Sun.COM int 49677836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu) 49687836SJohn.Forte@Sun.COM { 49697836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 49707836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49717836SJohn.Forte@Sun.COM int fd; 49727836SJohn.Forte@Sun.COM 49737836SJohn.Forte@Sun.COM if (lu == NULL) { 49747836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 49757836SJohn.Forte@Sun.COM } 49767836SJohn.Forte@Sun.COM 49777836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 49787836SJohn.Forte@Sun.COM 49797836SJohn.Forte@Sun.COM luState.state = STMF_STATE_OFFLINE; 49807836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 49817836SJohn.Forte@Sun.COM /* 49827836SJohn.Forte@Sun.COM * Open control node for stmf 49837836SJohn.Forte@Sun.COM * to make call to setStmfState() 49847836SJohn.Forte@Sun.COM */ 49857836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49867836SJohn.Forte@Sun.COM return (ret); 49877836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 49887836SJohn.Forte@Sun.COM (void) close(fd); 49897836SJohn.Forte@Sun.COM return (ret); 49907836SJohn.Forte@Sun.COM } 49917836SJohn.Forte@Sun.COM 49927836SJohn.Forte@Sun.COM /* 49937836SJohn.Forte@Sun.COM * stmfOnlineTarget 49947836SJohn.Forte@Sun.COM * 49957836SJohn.Forte@Sun.COM * Purpose: Change state of target to online 49967836SJohn.Forte@Sun.COM * 49977836SJohn.Forte@Sun.COM * devid - devid of the target to online 49987836SJohn.Forte@Sun.COM */ 49997836SJohn.Forte@Sun.COM int 50007836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid) 50017836SJohn.Forte@Sun.COM { 50027836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 50037836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50047836SJohn.Forte@Sun.COM int fd; 50057836SJohn.Forte@Sun.COM 50067836SJohn.Forte@Sun.COM if (devid == NULL) { 50077836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50087836SJohn.Forte@Sun.COM } 50097836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 50107836SJohn.Forte@Sun.COM 50117836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_ONLINE; 50127836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 50137836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 50147836SJohn.Forte@Sun.COM devid->identLength); 50157836SJohn.Forte@Sun.COM /* 50167836SJohn.Forte@Sun.COM * Open control node for stmf 50177836SJohn.Forte@Sun.COM * to make call to setStmfState() 50187836SJohn.Forte@Sun.COM */ 50197836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50207836SJohn.Forte@Sun.COM return (ret); 50217836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 50227836SJohn.Forte@Sun.COM (void) close(fd); 50237836SJohn.Forte@Sun.COM return (ret); 50247836SJohn.Forte@Sun.COM } 50257836SJohn.Forte@Sun.COM 50267836SJohn.Forte@Sun.COM /* 50277836SJohn.Forte@Sun.COM * stmfOnlineLogicalUnit 50287836SJohn.Forte@Sun.COM * 50297836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to online 50307836SJohn.Forte@Sun.COM * 50317836SJohn.Forte@Sun.COM * lu - guid of the logical unit to online 50327836SJohn.Forte@Sun.COM */ 50337836SJohn.Forte@Sun.COM int 50347836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu) 50357836SJohn.Forte@Sun.COM { 50367836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 50377836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50387836SJohn.Forte@Sun.COM int fd; 50397836SJohn.Forte@Sun.COM 50407836SJohn.Forte@Sun.COM if (lu == NULL) { 50417836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50427836SJohn.Forte@Sun.COM } 50437836SJohn.Forte@Sun.COM 50447836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 50457836SJohn.Forte@Sun.COM 50467836SJohn.Forte@Sun.COM luState.state = STMF_STATE_ONLINE; 50477836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 50487836SJohn.Forte@Sun.COM /* 50497836SJohn.Forte@Sun.COM * Open control node for stmf 50507836SJohn.Forte@Sun.COM * to make call to setStmfState() 50517836SJohn.Forte@Sun.COM */ 50527836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50537836SJohn.Forte@Sun.COM return (ret); 50547836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 50557836SJohn.Forte@Sun.COM (void) close(fd); 50567836SJohn.Forte@Sun.COM return (ret); 50577836SJohn.Forte@Sun.COM } 50587836SJohn.Forte@Sun.COM 50597836SJohn.Forte@Sun.COM /* 50607836SJohn.Forte@Sun.COM * stmfRemoveFromHostGroup 50617836SJohn.Forte@Sun.COM * 50627836SJohn.Forte@Sun.COM * Purpose: Removes an initiator from an initiator group 50637836SJohn.Forte@Sun.COM * 50647836SJohn.Forte@Sun.COM * hostGroupName - name of an initiator group 50657836SJohn.Forte@Sun.COM * hostName - name of host group member to remove 50667836SJohn.Forte@Sun.COM */ 50677836SJohn.Forte@Sun.COM int 50687836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 50697836SJohn.Forte@Sun.COM { 50707836SJohn.Forte@Sun.COM int ret; 50717836SJohn.Forte@Sun.COM int fd; 50727836SJohn.Forte@Sun.COM 50737836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 50747836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 50757836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 50767836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50777836SJohn.Forte@Sun.COM } 50787836SJohn.Forte@Sun.COM 50797836SJohn.Forte@Sun.COM /* call init */ 50807836SJohn.Forte@Sun.COM ret = initializeConfig(); 50817836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 50827836SJohn.Forte@Sun.COM return (ret); 50837836SJohn.Forte@Sun.COM } 50847836SJohn.Forte@Sun.COM 50857836SJohn.Forte@Sun.COM /* 50867836SJohn.Forte@Sun.COM * Open control node for stmf 50877836SJohn.Forte@Sun.COM */ 50887836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 50897836SJohn.Forte@Sun.COM return (ret); 50907836SJohn.Forte@Sun.COM 50917836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY, 50927836SJohn.Forte@Sun.COM hostGroupName, hostName)) != STMF_STATUS_SUCCESS) { 50937836SJohn.Forte@Sun.COM goto done; 50947836SJohn.Forte@Sun.COM } 50957836SJohn.Forte@Sun.COM 50969585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 50979585STim.Szeto@Sun.COM goto done; 50989585STim.Szeto@Sun.COM } 50999585STim.Szeto@Sun.COM 51007836SJohn.Forte@Sun.COM ret = psRemoveHostGroupMember((char *)hostGroupName, 51017836SJohn.Forte@Sun.COM (char *)hostName->ident); 51027836SJohn.Forte@Sun.COM switch (ret) { 51037836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51047836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51057836SJohn.Forte@Sun.COM break; 51067836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 51077836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 51087836SJohn.Forte@Sun.COM break; 51097836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 51107836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 51117836SJohn.Forte@Sun.COM break; 51127836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51137836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51147836SJohn.Forte@Sun.COM break; 51157836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51167836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51177836SJohn.Forte@Sun.COM break; 51187836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51197836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51207836SJohn.Forte@Sun.COM break; 51217836SJohn.Forte@Sun.COM default: 51227836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 51237836SJohn.Forte@Sun.COM "stmfRemoveFromHostGroup" 51247836SJohn.Forte@Sun.COM "psRemoveHostGroupMember:error(%d)", ret); 51257836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51267836SJohn.Forte@Sun.COM break; 51277836SJohn.Forte@Sun.COM } 51287836SJohn.Forte@Sun.COM 51297836SJohn.Forte@Sun.COM done: 51307836SJohn.Forte@Sun.COM (void) close(fd); 51317836SJohn.Forte@Sun.COM return (ret); 51327836SJohn.Forte@Sun.COM } 51337836SJohn.Forte@Sun.COM 51347836SJohn.Forte@Sun.COM /* 51357836SJohn.Forte@Sun.COM * stmfRemoveFromTargetGroup 51367836SJohn.Forte@Sun.COM * 51377836SJohn.Forte@Sun.COM * Purpose: Removes a local port from a local port group 51387836SJohn.Forte@Sun.COM * 51397836SJohn.Forte@Sun.COM * targetGroupName - name of a target group 51407836SJohn.Forte@Sun.COM * targetName - name of target to remove 51417836SJohn.Forte@Sun.COM */ 51427836SJohn.Forte@Sun.COM int 51437836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 51447836SJohn.Forte@Sun.COM { 51457836SJohn.Forte@Sun.COM int ret; 51467836SJohn.Forte@Sun.COM int fd; 51477836SJohn.Forte@Sun.COM 51487836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 51497836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 51507836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 51517836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 51527836SJohn.Forte@Sun.COM } 51537836SJohn.Forte@Sun.COM 51547836SJohn.Forte@Sun.COM /* call init */ 51557836SJohn.Forte@Sun.COM ret = initializeConfig(); 51567836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51577836SJohn.Forte@Sun.COM return (ret); 51587836SJohn.Forte@Sun.COM } 51597836SJohn.Forte@Sun.COM 51607836SJohn.Forte@Sun.COM /* 51617836SJohn.Forte@Sun.COM * Open control node for stmf 51627836SJohn.Forte@Sun.COM */ 51637836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 51647836SJohn.Forte@Sun.COM return (ret); 51657836SJohn.Forte@Sun.COM 51667836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY, 51677836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 51687836SJohn.Forte@Sun.COM goto done; 51697836SJohn.Forte@Sun.COM } 51707836SJohn.Forte@Sun.COM 51719585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 51729585STim.Szeto@Sun.COM goto done; 51739585STim.Szeto@Sun.COM } 51749585STim.Szeto@Sun.COM 51757836SJohn.Forte@Sun.COM ret = psRemoveTargetGroupMember((char *)targetGroupName, 51767836SJohn.Forte@Sun.COM (char *)targetName->ident); 51777836SJohn.Forte@Sun.COM switch (ret) { 51787836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51797836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51807836SJohn.Forte@Sun.COM break; 51817836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 51827836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 51837836SJohn.Forte@Sun.COM break; 51847836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 51857836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 51867836SJohn.Forte@Sun.COM break; 51877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51887836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51897836SJohn.Forte@Sun.COM break; 51907836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51917836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51927836SJohn.Forte@Sun.COM break; 51937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51947836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51957836SJohn.Forte@Sun.COM break; 51967836SJohn.Forte@Sun.COM default: 51977836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 51987836SJohn.Forte@Sun.COM "stmfRemoveFromTargetGroup" 51997836SJohn.Forte@Sun.COM "psRemoveTargetGroupMember:error(%d)", ret); 52007836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52017836SJohn.Forte@Sun.COM break; 52027836SJohn.Forte@Sun.COM } 52037836SJohn.Forte@Sun.COM 52047836SJohn.Forte@Sun.COM done: 52057836SJohn.Forte@Sun.COM (void) close(fd); 52067836SJohn.Forte@Sun.COM return (ret); 52077836SJohn.Forte@Sun.COM } 52087836SJohn.Forte@Sun.COM 52097836SJohn.Forte@Sun.COM /* 52107836SJohn.Forte@Sun.COM * stmfRemoveViewEntry 52117836SJohn.Forte@Sun.COM * 52127836SJohn.Forte@Sun.COM * Purpose: Removes a view entry from a logical unit 52137836SJohn.Forte@Sun.COM * 52147836SJohn.Forte@Sun.COM * lu - guid of lu for which view entry is being removed 52157836SJohn.Forte@Sun.COM * viewEntryIndex - index of view entry to remove 52167836SJohn.Forte@Sun.COM * 52177836SJohn.Forte@Sun.COM */ 52187836SJohn.Forte@Sun.COM int 52197836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex) 52207836SJohn.Forte@Sun.COM { 52217836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 52227836SJohn.Forte@Sun.COM int fd; 52237836SJohn.Forte@Sun.COM int ioctlRet; 52247836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 52257836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 52267836SJohn.Forte@Sun.COM 52277836SJohn.Forte@Sun.COM if (lu == NULL) { 52287836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 52297836SJohn.Forte@Sun.COM } 52307836SJohn.Forte@Sun.COM 52317836SJohn.Forte@Sun.COM /* call init */ 52327836SJohn.Forte@Sun.COM ret = initializeConfig(); 52337836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 52347836SJohn.Forte@Sun.COM return (ret); 52357836SJohn.Forte@Sun.COM } 52367836SJohn.Forte@Sun.COM 52377836SJohn.Forte@Sun.COM /* 52387836SJohn.Forte@Sun.COM * Open control node for stmf 52397836SJohn.Forte@Sun.COM */ 52407836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 52417836SJohn.Forte@Sun.COM return (ret); 52427836SJohn.Forte@Sun.COM 52437836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 52447836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx_valid = B_TRUE; 52457836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx = viewEntryIndex; 52467836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 52477836SJohn.Forte@Sun.COM 52487836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 52497836SJohn.Forte@Sun.COM /* 52507836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 52517836SJohn.Forte@Sun.COM */ 52527836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 52537836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 52547836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 52557836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl); 52567836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 52577836SJohn.Forte@Sun.COM switch (errno) { 52587836SJohn.Forte@Sun.COM case EBUSY: 52597836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 52607836SJohn.Forte@Sun.COM break; 52619585STim.Szeto@Sun.COM case EPERM: 52629585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 52639585STim.Szeto@Sun.COM break; 52647836SJohn.Forte@Sun.COM case EACCES: 52657836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 52667836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 52677836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 52687836SJohn.Forte@Sun.COM break; 52697836SJohn.Forte@Sun.COM default: 52707836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 52717836SJohn.Forte@Sun.COM break; 52727836SJohn.Forte@Sun.COM } 52737836SJohn.Forte@Sun.COM break; 52747836SJohn.Forte@Sun.COM case ENODEV: 52757836SJohn.Forte@Sun.COM case ENOENT: 52767836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 52777836SJohn.Forte@Sun.COM break; 52787836SJohn.Forte@Sun.COM default: 52797836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 52807836SJohn.Forte@Sun.COM "stmfRemoveViewEntry:ioctl errno(%d)", 52817836SJohn.Forte@Sun.COM errno); 52827836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52837836SJohn.Forte@Sun.COM break; 52847836SJohn.Forte@Sun.COM } 52857836SJohn.Forte@Sun.COM goto done; 52867836SJohn.Forte@Sun.COM } 52877836SJohn.Forte@Sun.COM 52889585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 52899585STim.Szeto@Sun.COM goto done; 52909585STim.Szeto@Sun.COM } 52919585STim.Szeto@Sun.COM 52927836SJohn.Forte@Sun.COM ret = psRemoveViewEntry(lu, viewEntryIndex); 52937836SJohn.Forte@Sun.COM switch (ret) { 52947836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 52957836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 52967836SJohn.Forte@Sun.COM break; 52977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 52987836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 52997836SJohn.Forte@Sun.COM break; 53007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 53017836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 53027836SJohn.Forte@Sun.COM break; 53037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 53047836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 53057836SJohn.Forte@Sun.COM break; 53067836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 53077836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 53087836SJohn.Forte@Sun.COM break; 53097836SJohn.Forte@Sun.COM default: 53107836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 53117836SJohn.Forte@Sun.COM "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)", 53127836SJohn.Forte@Sun.COM ret); 53137836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 53147836SJohn.Forte@Sun.COM break; 53157836SJohn.Forte@Sun.COM } 53167836SJohn.Forte@Sun.COM 53177836SJohn.Forte@Sun.COM done: 53187836SJohn.Forte@Sun.COM (void) close(fd); 53197836SJohn.Forte@Sun.COM return (ret); 53207836SJohn.Forte@Sun.COM } 53217836SJohn.Forte@Sun.COM 53227836SJohn.Forte@Sun.COM /* 53237836SJohn.Forte@Sun.COM * stmfSetProviderData 53247836SJohn.Forte@Sun.COM * 53257836SJohn.Forte@Sun.COM * Purpose: set the provider data 53267836SJohn.Forte@Sun.COM * 53277836SJohn.Forte@Sun.COM * providerName - unique name of provider 53287836SJohn.Forte@Sun.COM * nvl - nvlist to set 53297836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 53307836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 53317836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 53327836SJohn.Forte@Sun.COM */ 53337836SJohn.Forte@Sun.COM int 53347836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType) 53357836SJohn.Forte@Sun.COM { 53367836SJohn.Forte@Sun.COM return (stmfSetProviderDataProt(providerName, nvl, providerType, 53377836SJohn.Forte@Sun.COM NULL)); 53387836SJohn.Forte@Sun.COM } 53397836SJohn.Forte@Sun.COM 53407836SJohn.Forte@Sun.COM /* 53417836SJohn.Forte@Sun.COM * stmfSetProviderDataProt 53427836SJohn.Forte@Sun.COM * 53437836SJohn.Forte@Sun.COM * Purpose: set the provider data 53447836SJohn.Forte@Sun.COM * 53457836SJohn.Forte@Sun.COM * providerName - unique name of provider 53467836SJohn.Forte@Sun.COM * nvl - nvlist to set 53477836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 53487836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 53497836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 53507836SJohn.Forte@Sun.COM * setToken - Stale data token returned in the stmfGetProviderDataProt() 53517836SJohn.Forte@Sun.COM * call or NULL. 53527836SJohn.Forte@Sun.COM */ 53537836SJohn.Forte@Sun.COM int 53547836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, 53557836SJohn.Forte@Sun.COM uint64_t *setToken) 53567836SJohn.Forte@Sun.COM { 53577836SJohn.Forte@Sun.COM int ret; 53587836SJohn.Forte@Sun.COM int fd; 53597836SJohn.Forte@Sun.COM 53607836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 53617836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 53627836SJohn.Forte@Sun.COM } 53637836SJohn.Forte@Sun.COM 53647836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 53657836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 53667836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 53677836SJohn.Forte@Sun.COM } 53687836SJohn.Forte@Sun.COM 53697836SJohn.Forte@Sun.COM /* call init */ 53707836SJohn.Forte@Sun.COM ret = initializeConfig(); 53717836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 53727836SJohn.Forte@Sun.COM return (ret); 53737836SJohn.Forte@Sun.COM } 53747836SJohn.Forte@Sun.COM 53757836SJohn.Forte@Sun.COM /* 53767836SJohn.Forte@Sun.COM * Open control node for stmf 53777836SJohn.Forte@Sun.COM */ 53787836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 53797836SJohn.Forte@Sun.COM return (ret); 53807836SJohn.Forte@Sun.COM 53819585STim.Szeto@Sun.COM ret = setProviderData(fd, providerName, nvl, providerType, setToken); 53827836SJohn.Forte@Sun.COM 53837836SJohn.Forte@Sun.COM (void) close(fd); 53847836SJohn.Forte@Sun.COM 53857836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 53867836SJohn.Forte@Sun.COM goto done; 53877836SJohn.Forte@Sun.COM } 53887836SJohn.Forte@Sun.COM 53899585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 53909585STim.Szeto@Sun.COM goto done; 53919585STim.Szeto@Sun.COM } 53929585STim.Szeto@Sun.COM 53937836SJohn.Forte@Sun.COM /* setting driver provider data successful. Now persist it */ 53949585STim.Szeto@Sun.COM ret = psSetProviderData(providerName, nvl, providerType, NULL); 53957836SJohn.Forte@Sun.COM switch (ret) { 53967836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 53977836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 53987836SJohn.Forte@Sun.COM break; 53997836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 54007836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 54017836SJohn.Forte@Sun.COM break; 54027836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 54037836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 54047836SJohn.Forte@Sun.COM break; 54057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 54067836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 54077836SJohn.Forte@Sun.COM break; 54087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 54097836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 54107836SJohn.Forte@Sun.COM break; 54117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_PROV_DATA_STALE: 54127836SJohn.Forte@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 54137836SJohn.Forte@Sun.COM break; 54147836SJohn.Forte@Sun.COM default: 54157836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 54167836SJohn.Forte@Sun.COM "stmfSetProviderData" 54177836SJohn.Forte@Sun.COM "psSetProviderData:error(%d)", ret); 54187836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 54197836SJohn.Forte@Sun.COM break; 54207836SJohn.Forte@Sun.COM } 54217836SJohn.Forte@Sun.COM 54227836SJohn.Forte@Sun.COM done: 54237836SJohn.Forte@Sun.COM return (ret); 54247836SJohn.Forte@Sun.COM } 54257836SJohn.Forte@Sun.COM 54267836SJohn.Forte@Sun.COM /* 54279585STim.Szeto@Sun.COM * getProviderData 54289585STim.Szeto@Sun.COM * 54299585STim.Szeto@Sun.COM * Purpose: set the provider data from stmf 54309585STim.Szeto@Sun.COM * 54319585STim.Szeto@Sun.COM * providerName - unique name of provider 54329585STim.Szeto@Sun.COM * nvl - nvlist to load/retrieve 54339585STim.Szeto@Sun.COM * providerType - logical unit or port provider 54349585STim.Szeto@Sun.COM * setToken - returned stale data token 54359585STim.Szeto@Sun.COM */ 54369585STim.Szeto@Sun.COM int 54379585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType, 54389585STim.Szeto@Sun.COM uint64_t *setToken) 54399585STim.Szeto@Sun.COM { 54409585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 54419585STim.Szeto@Sun.COM int fd; 54429585STim.Szeto@Sun.COM int ioctlRet; 54439585STim.Szeto@Sun.COM size_t nvlistSize = ALLOC_PP_DATA_SIZE; 54449585STim.Szeto@Sun.COM int retryCnt = 0; 54459585STim.Szeto@Sun.COM int retryCntMax = MAX_PROVIDER_RETRY; 54469585STim.Szeto@Sun.COM stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL; 54479585STim.Szeto@Sun.COM boolean_t retry = B_TRUE; 54489585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 54499585STim.Szeto@Sun.COM 54509585STim.Szeto@Sun.COM if (providerName == NULL) { 54519585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 54529585STim.Szeto@Sun.COM } 54539585STim.Szeto@Sun.COM 54549585STim.Szeto@Sun.COM /* 54559585STim.Szeto@Sun.COM * Open control node for stmf 54569585STim.Szeto@Sun.COM */ 54579585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 54589585STim.Szeto@Sun.COM return (ret); 54599585STim.Szeto@Sun.COM 54609585STim.Szeto@Sun.COM /* set provider name and provider type */ 54619585STim.Szeto@Sun.COM if (strlcpy(ppi.ppi_name, providerName, 54629585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) >= 54639585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) { 54649585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 54659585STim.Szeto@Sun.COM goto done; 54669585STim.Szeto@Sun.COM } 54679585STim.Szeto@Sun.COM switch (providerType) { 54689585STim.Szeto@Sun.COM case STMF_LU_PROVIDER_TYPE: 54699585STim.Szeto@Sun.COM ppi.ppi_lu_provider = 1; 54709585STim.Szeto@Sun.COM break; 54719585STim.Szeto@Sun.COM case STMF_PORT_PROVIDER_TYPE: 54729585STim.Szeto@Sun.COM ppi.ppi_port_provider = 1; 54739585STim.Szeto@Sun.COM break; 54749585STim.Szeto@Sun.COM default: 54759585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 54769585STim.Szeto@Sun.COM goto done; 54779585STim.Szeto@Sun.COM } 54789585STim.Szeto@Sun.COM 54799585STim.Szeto@Sun.COM do { 54809585STim.Szeto@Sun.COM /* allocate memory for ioctl */ 54819585STim.Szeto@Sun.COM ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize + 54829585STim.Szeto@Sun.COM sizeof (stmf_ppioctl_data_t)); 54839585STim.Szeto@Sun.COM if (ppi_out == NULL) { 54849585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 54859585STim.Szeto@Sun.COM goto done; 54869585STim.Szeto@Sun.COM 54879585STim.Szeto@Sun.COM } 54889585STim.Szeto@Sun.COM 54899585STim.Szeto@Sun.COM /* set the size of the ioctl data to allocated buffer */ 54909585STim.Szeto@Sun.COM ppi.ppi_data_size = nvlistSize; 54919585STim.Szeto@Sun.COM 54929585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 54939585STim.Szeto@Sun.COM 54949585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 54959585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 54969585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 54979585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) + 54989585STim.Szeto@Sun.COM nvlistSize; 54999585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out; 55009585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl); 55019585STim.Szeto@Sun.COM if (ioctlRet != 0) { 55029585STim.Szeto@Sun.COM switch (errno) { 55039585STim.Szeto@Sun.COM case EBUSY: 55049585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 55059585STim.Szeto@Sun.COM break; 55069585STim.Szeto@Sun.COM case EPERM: 55079585STim.Szeto@Sun.COM case EACCES: 55089585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 55099585STim.Szeto@Sun.COM break; 55109585STim.Szeto@Sun.COM case EINVAL: 55119585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 55129585STim.Szeto@Sun.COM STMF_IOCERR_INSUFFICIENT_BUF) { 55139585STim.Szeto@Sun.COM nvlistSize = 55149585STim.Szeto@Sun.COM ppi_out->ppi_data_size; 55159585STim.Szeto@Sun.COM free(ppi_out); 55169585STim.Szeto@Sun.COM ppi_out = NULL; 55179585STim.Szeto@Sun.COM if (retryCnt++ > retryCntMax) { 55189585STim.Szeto@Sun.COM retry = B_FALSE; 55199585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 55209585STim.Szeto@Sun.COM } else { 55219585STim.Szeto@Sun.COM ret = 55229585STim.Szeto@Sun.COM STMF_STATUS_SUCCESS; 55239585STim.Szeto@Sun.COM } 55249585STim.Szeto@Sun.COM } else { 55259585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 55269585STim.Szeto@Sun.COM "getProviderData:ioctl" 55279585STim.Szeto@Sun.COM "unable to retrieve " 55289585STim.Szeto@Sun.COM "nvlist"); 55299585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 55309585STim.Szeto@Sun.COM } 55319585STim.Szeto@Sun.COM break; 55329585STim.Szeto@Sun.COM case ENOENT: 55339585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 55349585STim.Szeto@Sun.COM break; 55359585STim.Szeto@Sun.COM default: 55369585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 55379585STim.Szeto@Sun.COM "getProviderData:ioctl errno(%d)", 55389585STim.Szeto@Sun.COM errno); 55399585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 55409585STim.Szeto@Sun.COM break; 55419585STim.Szeto@Sun.COM } 55429585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) 55439585STim.Szeto@Sun.COM goto done; 55449585STim.Szeto@Sun.COM } 55459585STim.Szeto@Sun.COM } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF); 55469585STim.Szeto@Sun.COM 55479585STim.Szeto@Sun.COM if ((ret = nvlist_unpack((char *)ppi_out->ppi_data, 55489585STim.Szeto@Sun.COM ppi_out->ppi_data_size, nvl, 0)) != 0) { 55499585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 55509585STim.Szeto@Sun.COM goto done; 55519585STim.Szeto@Sun.COM } 55529585STim.Szeto@Sun.COM 55539585STim.Szeto@Sun.COM /* caller has asked for new token */ 55549585STim.Szeto@Sun.COM if (setToken) { 55559585STim.Szeto@Sun.COM *setToken = ppi_out->ppi_token; 55569585STim.Szeto@Sun.COM } 55579585STim.Szeto@Sun.COM done: 55589585STim.Szeto@Sun.COM free(ppi_out); 55599585STim.Szeto@Sun.COM (void) close(fd); 55609585STim.Szeto@Sun.COM return (ret); 55619585STim.Szeto@Sun.COM } 55629585STim.Szeto@Sun.COM 55639585STim.Szeto@Sun.COM /* 55647836SJohn.Forte@Sun.COM * setProviderData 55657836SJohn.Forte@Sun.COM * 55669585STim.Szeto@Sun.COM * Purpose: set the provider data in stmf 55677836SJohn.Forte@Sun.COM * 55687836SJohn.Forte@Sun.COM * providerName - unique name of provider 55697836SJohn.Forte@Sun.COM * nvl - nvlist to set 55707836SJohn.Forte@Sun.COM * providerType - logical unit or port provider 55719585STim.Szeto@Sun.COM * setToken - stale data token to check if not NULL 55727836SJohn.Forte@Sun.COM */ 55737836SJohn.Forte@Sun.COM static int 55749585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType, 55759585STim.Szeto@Sun.COM uint64_t *setToken) 55767836SJohn.Forte@Sun.COM { 55777836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 55787836SJohn.Forte@Sun.COM int ioctlRet; 55797836SJohn.Forte@Sun.COM size_t nvlistEncodedSize; 55807836SJohn.Forte@Sun.COM stmf_ppioctl_data_t *ppi = NULL; 55819585STim.Szeto@Sun.COM uint64_t outToken; 55827836SJohn.Forte@Sun.COM char *allocatedNvBuffer; 55837836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 55847836SJohn.Forte@Sun.COM 55857836SJohn.Forte@Sun.COM if (providerName == NULL) { 55867836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 55877836SJohn.Forte@Sun.COM } 55887836SJohn.Forte@Sun.COM 55897836SJohn.Forte@Sun.COM /* get size of encoded nvlist */ 55907836SJohn.Forte@Sun.COM if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) { 55917836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 55927836SJohn.Forte@Sun.COM } 55937836SJohn.Forte@Sun.COM 55947836SJohn.Forte@Sun.COM /* allocate memory for ioctl */ 55957836SJohn.Forte@Sun.COM ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize + 55967836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t)); 55977836SJohn.Forte@Sun.COM if (ppi == NULL) { 55987836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 55997836SJohn.Forte@Sun.COM } 56007836SJohn.Forte@Sun.COM 56019585STim.Szeto@Sun.COM if (setToken) { 56029585STim.Szeto@Sun.COM ppi->ppi_token_valid = 1; 56039585STim.Szeto@Sun.COM ppi->ppi_token = *setToken; 56049585STim.Szeto@Sun.COM } 56059585STim.Szeto@Sun.COM 56067836SJohn.Forte@Sun.COM allocatedNvBuffer = (char *)&ppi->ppi_data; 56077836SJohn.Forte@Sun.COM if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize, 56087836SJohn.Forte@Sun.COM NV_ENCODE_XDR, 0) != 0) { 56097836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 56107836SJohn.Forte@Sun.COM } 56117836SJohn.Forte@Sun.COM 56127836SJohn.Forte@Sun.COM /* set provider name and provider type */ 56137836SJohn.Forte@Sun.COM (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name)); 56147836SJohn.Forte@Sun.COM switch (providerType) { 56157836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 56167836SJohn.Forte@Sun.COM ppi->ppi_lu_provider = 1; 56177836SJohn.Forte@Sun.COM break; 56187836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 56197836SJohn.Forte@Sun.COM ppi->ppi_port_provider = 1; 56207836SJohn.Forte@Sun.COM break; 56217836SJohn.Forte@Sun.COM default: 56227836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56237836SJohn.Forte@Sun.COM } 56247836SJohn.Forte@Sun.COM 56257836SJohn.Forte@Sun.COM /* set the size of the ioctl data to packed data size */ 56267836SJohn.Forte@Sun.COM ppi->ppi_data_size = nvlistEncodedSize; 56277836SJohn.Forte@Sun.COM 56287836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 56297836SJohn.Forte@Sun.COM 56307836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 56317836SJohn.Forte@Sun.COM /* 56327836SJohn.Forte@Sun.COM * Subtracting 8 from the size as that is the size of the last member 56337836SJohn.Forte@Sun.COM * of the structure where the packed data resides 56347836SJohn.Forte@Sun.COM */ 56357836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = nvlistEncodedSize + 56367836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t) - 8; 56377836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi; 56389585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (uint64_t); 56399585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken; 56407836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl); 56417836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 56427836SJohn.Forte@Sun.COM switch (errno) { 56437836SJohn.Forte@Sun.COM case EBUSY: 56447836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 56457836SJohn.Forte@Sun.COM break; 56469585STim.Szeto@Sun.COM case EPERM: 56477836SJohn.Forte@Sun.COM case EACCES: 56487836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 56497836SJohn.Forte@Sun.COM break; 56509585STim.Szeto@Sun.COM case EINVAL: 56519585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 56529585STim.Szeto@Sun.COM STMF_IOCERR_PPD_UPDATED) { 56539585STim.Szeto@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 56549585STim.Szeto@Sun.COM } else { 56559585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 56569585STim.Szeto@Sun.COM } 56579585STim.Szeto@Sun.COM break; 56587836SJohn.Forte@Sun.COM default: 56597836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 56607836SJohn.Forte@Sun.COM "setProviderData:ioctl errno(%d)", errno); 56617836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 56627836SJohn.Forte@Sun.COM break; 56637836SJohn.Forte@Sun.COM } 56647836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) 56657836SJohn.Forte@Sun.COM goto done; 56667836SJohn.Forte@Sun.COM } 56677836SJohn.Forte@Sun.COM 56689585STim.Szeto@Sun.COM /* caller has asked for new token */ 56699585STim.Szeto@Sun.COM if (setToken) { 56709585STim.Szeto@Sun.COM *setToken = outToken; 56719585STim.Szeto@Sun.COM } 56727836SJohn.Forte@Sun.COM done: 56737836SJohn.Forte@Sun.COM free(ppi); 56747836SJohn.Forte@Sun.COM return (ret); 56757836SJohn.Forte@Sun.COM } 56769585STim.Szeto@Sun.COM 56779585STim.Szeto@Sun.COM /* 56789585STim.Szeto@Sun.COM * set the persistence method in the library only or library and service 56799585STim.Szeto@Sun.COM */ 56809585STim.Szeto@Sun.COM int 56819585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet) 56829585STim.Szeto@Sun.COM { 56839585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 56849585STim.Szeto@Sun.COM int oldPersist; 56859585STim.Szeto@Sun.COM 56869585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 56879585STim.Szeto@Sun.COM oldPersist = iPersistType; 56889585STim.Szeto@Sun.COM if (persistType == STMF_PERSIST_NONE || 56899585STim.Szeto@Sun.COM persistType == STMF_PERSIST_SMF) { 56909585STim.Szeto@Sun.COM iLibSetPersist = B_TRUE; 56919585STim.Szeto@Sun.COM iPersistType = persistType; 56929585STim.Szeto@Sun.COM } else { 56939585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 56949585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 56959585STim.Szeto@Sun.COM } 56969585STim.Szeto@Sun.COM /* Is this for this library open or in SMF */ 56979585STim.Szeto@Sun.COM if (serviceSet == B_TRUE) { 56989585STim.Szeto@Sun.COM ret = psSetServicePersist(persistType); 56999585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 57009585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 57019585STim.Szeto@Sun.COM /* Set to old value */ 57029585STim.Szeto@Sun.COM iPersistType = oldPersist; 57039585STim.Szeto@Sun.COM } 57049585STim.Szeto@Sun.COM } 57059585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 57069585STim.Szeto@Sun.COM 57079585STim.Szeto@Sun.COM return (ret); 57089585STim.Szeto@Sun.COM } 57099585STim.Szeto@Sun.COM 57109585STim.Szeto@Sun.COM /* 57119585STim.Szeto@Sun.COM * Only returns internal state for persist. If unset, goes to ps. If that 57129585STim.Szeto@Sun.COM * fails, returns default setting 57139585STim.Szeto@Sun.COM */ 57149585STim.Szeto@Sun.COM static uint8_t 57159585STim.Szeto@Sun.COM iGetPersistMethod() 57169585STim.Szeto@Sun.COM { 57179585STim.Szeto@Sun.COM 57189585STim.Szeto@Sun.COM uint8_t persistType = 0; 57199585STim.Szeto@Sun.COM 57209585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 57219585STim.Szeto@Sun.COM if (iLibSetPersist) { 57229585STim.Szeto@Sun.COM persistType = iPersistType; 57239585STim.Szeto@Sun.COM } else { 57249585STim.Szeto@Sun.COM int ret; 57259585STim.Szeto@Sun.COM ret = psGetServicePersist(&persistType); 57269585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 57279585STim.Szeto@Sun.COM /* set to default */ 57289585STim.Szeto@Sun.COM persistType = STMF_DEFAULT_PERSIST; 57299585STim.Szeto@Sun.COM } 57309585STim.Szeto@Sun.COM } 57319585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 57329585STim.Szeto@Sun.COM return (persistType); 57339585STim.Szeto@Sun.COM } 57349585STim.Szeto@Sun.COM 57359585STim.Szeto@Sun.COM /* 57369585STim.Szeto@Sun.COM * Returns either library state or persistent config state depending on 57379585STim.Szeto@Sun.COM * serviceState 57389585STim.Szeto@Sun.COM */ 57399585STim.Szeto@Sun.COM int 57409585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState) 57419585STim.Szeto@Sun.COM { 57429585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 57439585STim.Szeto@Sun.COM 57449585STim.Szeto@Sun.COM if (persistType == NULL) { 57459585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 57469585STim.Szeto@Sun.COM } 57479585STim.Szeto@Sun.COM if (serviceState) { 57489585STim.Szeto@Sun.COM ret = psGetServicePersist(persistType); 57499585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 57509585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 57519585STim.Szeto@Sun.COM } 57529585STim.Szeto@Sun.COM } else { 57539585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 57549585STim.Szeto@Sun.COM if (iLibSetPersist) { 57559585STim.Szeto@Sun.COM *persistType = iPersistType; 57569585STim.Szeto@Sun.COM } else { 57579585STim.Szeto@Sun.COM *persistType = STMF_DEFAULT_PERSIST; 57589585STim.Szeto@Sun.COM } 57599585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 57609585STim.Szeto@Sun.COM } 57619585STim.Szeto@Sun.COM 57629585STim.Szeto@Sun.COM return (ret); 57639585STim.Szeto@Sun.COM } 5764