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: 3459884STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 3469884STim.Szeto@Sun.COM case STMF_IOCERR_TG_NEED_TG_OFFLINE: 3479884STim.Szeto@Sun.COM ret = STMF_ERROR_TG_ONLINE; 3489884STim.Szeto@Sun.COM break; 3499884STim.Szeto@Sun.COM default: 3509884STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 3519884STim.Szeto@Sun.COM break; 3529884STim.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; 108110113SNattuvetty.Bhavyan@Sun.COM int luMgmtUrlLen = 0; 10829585STim.Szeto@Sun.COM int sluBufSize = 0; 10839585STim.Szeto@Sun.COM int bufOffset = 0; 10849585STim.Szeto@Sun.COM int fd = 0; 10859585STim.Szeto@Sun.COM int ioctlRet; 10869585STim.Szeto@Sun.COM int savedErrno; 10879585STim.Szeto@Sun.COM stmfGuid guid; 10889585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 10899585STim.Szeto@Sun.COM 10909585STim.Szeto@Sun.COM sbd_create_and_reg_lu_t *sbdLu = NULL; 10919585STim.Szeto@Sun.COM 10929585STim.Szeto@Sun.COM /* 10939585STim.Szeto@Sun.COM * Open control node for sbd 10949585STim.Szeto@Sun.COM */ 10959585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 10969585STim.Szeto@Sun.COM return (ret); 10979585STim.Szeto@Sun.COM 10989585STim.Szeto@Sun.COM /* data file name must be specified */ 10999585STim.Szeto@Sun.COM if (disk->luDataFileNameValid) { 11009585STim.Szeto@Sun.COM dataFileNameLen = strlen(disk->luDataFileName); 11019585STim.Szeto@Sun.COM } else { 11029585STim.Szeto@Sun.COM (void) close(fd); 11039585STim.Szeto@Sun.COM return (STMF_ERROR_MISSING_PROP_VAL); 11049585STim.Szeto@Sun.COM } 11059585STim.Szeto@Sun.COM 11069585STim.Szeto@Sun.COM sluBufSize += dataFileNameLen + 1; 11079585STim.Szeto@Sun.COM 11089585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 11099585STim.Szeto@Sun.COM metaFileNameLen = strlen(disk->luMetaFileName); 11109585STim.Szeto@Sun.COM sluBufSize += metaFileNameLen + 1; 11119585STim.Szeto@Sun.COM } 11129585STim.Szeto@Sun.COM 11139585STim.Szeto@Sun.COM serialNumLen = strlen(disk->serialNum); 11149585STim.Szeto@Sun.COM sluBufSize += serialNumLen; 11159585STim.Szeto@Sun.COM 11169585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11179585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 11189585STim.Szeto@Sun.COM sluBufSize += luAliasLen + 1; 11199585STim.Szeto@Sun.COM } 11209585STim.Szeto@Sun.COM 112110113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 112210113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen = strlen(disk->luMgmtUrl); 112310113SNattuvetty.Bhavyan@Sun.COM sluBufSize += luMgmtUrlLen + 1; 112410113SNattuvetty.Bhavyan@Sun.COM } 112510113SNattuvetty.Bhavyan@Sun.COM 11269585STim.Szeto@Sun.COM /* 11279585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 11289585STim.Szeto@Sun.COM * concatenation of variable length fields 11299585STim.Szeto@Sun.COM */ 11309585STim.Szeto@Sun.COM sbdLu = (sbd_create_and_reg_lu_t *)calloc(1, 11319585STim.Szeto@Sun.COM sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8); 11329585STim.Szeto@Sun.COM if (sbdLu == NULL) { 11339585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 11349585STim.Szeto@Sun.COM } 11359585STim.Szeto@Sun.COM 11369585STim.Szeto@Sun.COM sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) + 11379585STim.Szeto@Sun.COM sluBufSize - 8; 11389585STim.Szeto@Sun.COM 11399585STim.Szeto@Sun.COM if (metaFileNameLen) { 11409585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_valid = 1; 11419585STim.Szeto@Sun.COM sbdLu->slu_meta_fname_off = bufOffset; 11429585STim.Szeto@Sun.COM bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]), 11439585STim.Szeto@Sun.COM metaFileNameLen + 1); 11449585STim.Szeto@Sun.COM bufOffset += metaFileNameLen + 1; 11459585STim.Szeto@Sun.COM } 11469585STim.Szeto@Sun.COM 11479585STim.Szeto@Sun.COM bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]), 11489585STim.Szeto@Sun.COM dataFileNameLen + 1); 11499585STim.Szeto@Sun.COM sbdLu->slu_data_fname_off = bufOffset; 11509585STim.Szeto@Sun.COM bufOffset += dataFileNameLen + 1; 11519585STim.Szeto@Sun.COM 11529585STim.Szeto@Sun.COM /* currently, serial # is not passed null terminated to the driver */ 11539585STim.Szeto@Sun.COM if (disk->serialNumValid) { 11549585STim.Szeto@Sun.COM sbdLu->slu_serial_valid = 1; 11559585STim.Szeto@Sun.COM sbdLu->slu_serial_off = bufOffset; 11569585STim.Szeto@Sun.COM sbdLu->slu_serial_size = serialNumLen; 11579585STim.Szeto@Sun.COM bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]), 11589585STim.Szeto@Sun.COM serialNumLen); 11599585STim.Szeto@Sun.COM bufOffset += serialNumLen; 11609585STim.Szeto@Sun.COM } 11619585STim.Szeto@Sun.COM 11629585STim.Szeto@Sun.COM if (disk->luAliasValid) { 11639585STim.Szeto@Sun.COM sbdLu->slu_alias_valid = 1; 11649585STim.Szeto@Sun.COM sbdLu->slu_alias_off = bufOffset; 11659585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]), 11669585STim.Szeto@Sun.COM luAliasLen + 1); 11679585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 11689585STim.Szeto@Sun.COM } 11699585STim.Szeto@Sun.COM 117010113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 117110113SNattuvetty.Bhavyan@Sun.COM sbdLu->slu_mgmt_url_valid = 1; 117210113SNattuvetty.Bhavyan@Sun.COM sbdLu->slu_mgmt_url_off = bufOffset; 117310113SNattuvetty.Bhavyan@Sun.COM bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]), 117410113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen + 1); 117510113SNattuvetty.Bhavyan@Sun.COM bufOffset += luMgmtUrlLen + 1; 117610113SNattuvetty.Bhavyan@Sun.COM } 117710113SNattuvetty.Bhavyan@Sun.COM 11789585STim.Szeto@Sun.COM if (disk->luSizeValid) { 11799585STim.Szeto@Sun.COM sbdLu->slu_lu_size_valid = 1; 11809585STim.Szeto@Sun.COM sbdLu->slu_lu_size = disk->luSize; 11819585STim.Szeto@Sun.COM } 11829585STim.Szeto@Sun.COM 11839585STim.Szeto@Sun.COM if (disk->luGuidValid) { 11849585STim.Szeto@Sun.COM sbdLu->slu_guid_valid = 1; 11859585STim.Szeto@Sun.COM bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid)); 11869585STim.Szeto@Sun.COM } 11879585STim.Szeto@Sun.COM 11889585STim.Szeto@Sun.COM if (disk->vidValid) { 11899585STim.Szeto@Sun.COM sbdLu->slu_vid_valid = 1; 11909585STim.Szeto@Sun.COM bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid)); 11919585STim.Szeto@Sun.COM } 11929585STim.Szeto@Sun.COM 11939585STim.Szeto@Sun.COM if (disk->pidValid) { 11949585STim.Szeto@Sun.COM sbdLu->slu_pid_valid = 1; 11959585STim.Szeto@Sun.COM bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid)); 11969585STim.Szeto@Sun.COM } 11979585STim.Szeto@Sun.COM 11989585STim.Szeto@Sun.COM if (disk->revValid) { 11999585STim.Szeto@Sun.COM sbdLu->slu_rev_valid = 1; 12009585STim.Szeto@Sun.COM bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev)); 12019585STim.Szeto@Sun.COM } 12029585STim.Szeto@Sun.COM 12039585STim.Szeto@Sun.COM if (disk->companyIdValid) { 12049585STim.Szeto@Sun.COM sbdLu->slu_company_id_valid = 1; 12059585STim.Szeto@Sun.COM sbdLu->slu_company_id = disk->companyId; 12069585STim.Szeto@Sun.COM } 12079585STim.Szeto@Sun.COM 12089585STim.Szeto@Sun.COM if (disk->blkSizeValid) { 12099585STim.Szeto@Sun.COM sbdLu->slu_blksize_valid = 1; 12109585STim.Szeto@Sun.COM sbdLu->slu_blksize = disk->blkSize; 12119585STim.Szeto@Sun.COM } 12129585STim.Szeto@Sun.COM 12139585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 12149585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 12159585STim.Szeto@Sun.COM sbdLu->slu_write_protected = 1; 12169585STim.Szeto@Sun.COM } 12179585STim.Szeto@Sun.COM } 12189585STim.Szeto@Sun.COM 12199585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 12209585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable_valid = 1; 12219585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 12229585STim.Szeto@Sun.COM sbdLu->slu_writeback_cache_disable = 1; 12239585STim.Szeto@Sun.COM } 12249585STim.Szeto@Sun.COM } 12259585STim.Szeto@Sun.COM 12269585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 12279585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size; 12289585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 12299585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size; 12309585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 12319585STim.Szeto@Sun.COM 12329585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl); 12339585STim.Szeto@Sun.COM if (ioctlRet != 0) { 12349585STim.Szeto@Sun.COM savedErrno = errno; 12359585STim.Szeto@Sun.COM switch (savedErrno) { 12369585STim.Szeto@Sun.COM case EBUSY: 12379585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 12389585STim.Szeto@Sun.COM break; 12399585STim.Szeto@Sun.COM case EPERM: 12409585STim.Szeto@Sun.COM case EACCES: 12419585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 12429585STim.Szeto@Sun.COM break; 12439585STim.Szeto@Sun.COM default: 12449585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 12459585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 12469585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 12479585STim.Szeto@Sun.COM "createDiskLu:ioctl " 12489585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 12499585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 12509585STim.Szeto@Sun.COM } 12519585STim.Szeto@Sun.COM break; 12529585STim.Szeto@Sun.COM } 12539585STim.Szeto@Sun.COM } 12549585STim.Szeto@Sun.COM 12559585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 12569585STim.Szeto@Sun.COM goto done; 12579585STim.Szeto@Sun.COM } 12589585STim.Szeto@Sun.COM 12599585STim.Szeto@Sun.COM /* 12609585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 12619585STim.Szeto@Sun.COM * NULL 12629585STim.Szeto@Sun.COM */ 12639585STim.Szeto@Sun.COM if (createdGuid) { 12649585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, createdGuid->guid, 12659585STim.Szeto@Sun.COM sizeof (sbdLu->slu_guid)); 12669585STim.Szeto@Sun.COM } 12679585STim.Szeto@Sun.COM 12689585STim.Szeto@Sun.COM bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid)); 12699585STim.Szeto@Sun.COM if (disk->luMetaFileNameValid) { 12709585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luMetaFileName); 12719585STim.Szeto@Sun.COM } else { 12729585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&guid, disk->luDataFileName); 12739585STim.Szeto@Sun.COM } 12749585STim.Szeto@Sun.COM done: 12759585STim.Szeto@Sun.COM free(sbdLu); 12769585STim.Szeto@Sun.COM (void) close(fd); 12779585STim.Szeto@Sun.COM return (ret); 12789585STim.Szeto@Sun.COM } 12799585STim.Szeto@Sun.COM 12809585STim.Szeto@Sun.COM 12819585STim.Szeto@Sun.COM /* 12829585STim.Szeto@Sun.COM * stmfImportLu 12839585STim.Szeto@Sun.COM * 12849585STim.Szeto@Sun.COM * Purpose: Import a previously created logical unit 12859585STim.Szeto@Sun.COM * 12869585STim.Szeto@Sun.COM * dType - Type of logical unit 12879585STim.Szeto@Sun.COM * Can be: STMF_DISK 12889585STim.Szeto@Sun.COM * 12899585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the imported logical 12909585STim.Szeto@Sun.COM * unit 12919585STim.Szeto@Sun.COM * 12929585STim.Szeto@Sun.COM * fname - A file name where the metadata resides 12939585STim.Szeto@Sun.COM * 12949585STim.Szeto@Sun.COM */ 12959585STim.Szeto@Sun.COM int 12969585STim.Szeto@Sun.COM stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid) 12979585STim.Szeto@Sun.COM { 12989585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 12999585STim.Szeto@Sun.COM 13009585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 13019585STim.Szeto@Sun.COM ret = importDiskLu(fname, luGuid); 13029585STim.Szeto@Sun.COM } else { 13039585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13049585STim.Szeto@Sun.COM } 13059585STim.Szeto@Sun.COM 13069585STim.Szeto@Sun.COM return (ret); 13079585STim.Szeto@Sun.COM } 13089585STim.Szeto@Sun.COM 13099585STim.Szeto@Sun.COM /* 13109585STim.Szeto@Sun.COM * importDiskLu 13119585STim.Szeto@Sun.COM * 13129585STim.Szeto@Sun.COM * filename - filename to import 13139585STim.Szeto@Sun.COM * createdGuid - if not NULL, on success contains the imported guid 13149585STim.Szeto@Sun.COM * 13159585STim.Szeto@Sun.COM */ 13169585STim.Szeto@Sun.COM static int 13179585STim.Szeto@Sun.COM importDiskLu(char *fname, stmfGuid *createdGuid) 13189585STim.Szeto@Sun.COM { 13199585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 13209585STim.Szeto@Sun.COM int fd = 0; 13219585STim.Szeto@Sun.COM int ioctlRet; 13229585STim.Szeto@Sun.COM int savedErrno; 13239585STim.Szeto@Sun.COM int metaFileNameLen; 13249585STim.Szeto@Sun.COM stmfGuid iGuid; 13259585STim.Szeto@Sun.COM int iluBufSize = 0; 13269585STim.Szeto@Sun.COM sbd_import_lu_t *sbdLu = NULL; 13279585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 13289585STim.Szeto@Sun.COM 13299585STim.Szeto@Sun.COM if (fname == NULL) { 13309585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 13319585STim.Szeto@Sun.COM } 13329585STim.Szeto@Sun.COM 13339585STim.Szeto@Sun.COM /* 13349585STim.Szeto@Sun.COM * Open control node for sbd 13359585STim.Szeto@Sun.COM */ 13369585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 13379585STim.Szeto@Sun.COM return (ret); 13389585STim.Szeto@Sun.COM 13399585STim.Szeto@Sun.COM metaFileNameLen = strlen(fname); 13409585STim.Szeto@Sun.COM iluBufSize += metaFileNameLen + 1; 13419585STim.Szeto@Sun.COM 13429585STim.Szeto@Sun.COM /* 13439585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 13449585STim.Szeto@Sun.COM * concatenation of variable length fields 13459585STim.Szeto@Sun.COM */ 13469585STim.Szeto@Sun.COM sbdLu = (sbd_import_lu_t *)calloc(1, 13479585STim.Szeto@Sun.COM sizeof (sbd_import_lu_t) + iluBufSize - 8); 13489585STim.Szeto@Sun.COM if (sbdLu == NULL) { 13499585STim.Szeto@Sun.COM (void) close(fd); 13509585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 13519585STim.Szeto@Sun.COM } 13529585STim.Szeto@Sun.COM 13539585STim.Szeto@Sun.COM /* 13549585STim.Szeto@Sun.COM * Accept either a data file or meta data file. 13559585STim.Szeto@Sun.COM * sbd will do the right thing here either way. 13569585STim.Szeto@Sun.COM * i.e. if it's a data file, it assumes that the 13579585STim.Szeto@Sun.COM * meta data is shared with the data. 13589585STim.Szeto@Sun.COM */ 13599585STim.Szeto@Sun.COM (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen); 13609585STim.Szeto@Sun.COM 13619585STim.Szeto@Sun.COM sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8; 13629585STim.Szeto@Sun.COM 13639585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 13649585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size; 13659585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 13669585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size; 13679585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu; 13689585STim.Szeto@Sun.COM 13699585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl); 13709585STim.Szeto@Sun.COM if (ioctlRet != 0) { 13719585STim.Szeto@Sun.COM savedErrno = errno; 13729585STim.Szeto@Sun.COM switch (savedErrno) { 13739585STim.Szeto@Sun.COM case EBUSY: 13749585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 13759585STim.Szeto@Sun.COM break; 13769585STim.Szeto@Sun.COM case EPERM: 13779585STim.Szeto@Sun.COM case EACCES: 13789585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 13799585STim.Szeto@Sun.COM break; 13809585STim.Szeto@Sun.COM default: 13819585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 13829585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 13839585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 13849585STim.Szeto@Sun.COM "importDiskLu:ioctl " 13859585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 13869585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 13879585STim.Szeto@Sun.COM } 13889585STim.Szeto@Sun.COM break; 13899585STim.Szeto@Sun.COM } 13909585STim.Szeto@Sun.COM } 13919585STim.Szeto@Sun.COM 13929585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 13939585STim.Szeto@Sun.COM goto done; 13949585STim.Szeto@Sun.COM } 13959585STim.Szeto@Sun.COM 13969585STim.Szeto@Sun.COM /* 13979585STim.Szeto@Sun.COM * on success, copy the resulting guid into the caller's guid if not 13989585STim.Szeto@Sun.COM * NULL and add it to the persistent store for sbd 13999585STim.Szeto@Sun.COM */ 14009585STim.Szeto@Sun.COM if (createdGuid) { 14019585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, createdGuid->guid, 14029585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 14039585STim.Szeto@Sun.COM ret = addGuidToDiskStore(createdGuid, fname); 14049585STim.Szeto@Sun.COM } else { 14059585STim.Szeto@Sun.COM bcopy(sbdLu->ilu_ret_guid, iGuid.guid, 14069585STim.Szeto@Sun.COM sizeof (sbdLu->ilu_ret_guid)); 14079585STim.Szeto@Sun.COM ret = addGuidToDiskStore(&iGuid, fname); 14089585STim.Szeto@Sun.COM } 14099585STim.Szeto@Sun.COM done: 14109585STim.Szeto@Sun.COM free(sbdLu); 14119585STim.Szeto@Sun.COM (void) close(fd); 14129585STim.Szeto@Sun.COM return (ret); 14139585STim.Szeto@Sun.COM } 14149585STim.Szeto@Sun.COM 14159585STim.Szeto@Sun.COM /* 14169585STim.Szeto@Sun.COM * diskError 14179585STim.Szeto@Sun.COM * 14189585STim.Szeto@Sun.COM * Purpose: Translate sbd driver error 14199585STim.Szeto@Sun.COM */ 14209585STim.Szeto@Sun.COM static void 14219585STim.Szeto@Sun.COM diskError(uint32_t stmfError, int *ret) 14229585STim.Szeto@Sun.COM { 14239585STim.Szeto@Sun.COM switch (stmfError) { 14249585STim.Szeto@Sun.COM case SBD_RET_META_CREATION_FAILED: 14259585STim.Szeto@Sun.COM case SBD_RET_ZFS_META_CREATE_FAILED: 14269585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_CREATION; 14279585STim.Szeto@Sun.COM break; 14289585STim.Szeto@Sun.COM case SBD_RET_INVALID_BLKSIZE: 14299585STim.Szeto@Sun.COM *ret = STMF_ERROR_INVALID_BLKSIZE; 14309585STim.Szeto@Sun.COM break; 14319585STim.Szeto@Sun.COM case SBD_RET_FILE_ALREADY_REGISTERED: 14329585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_IN_USE; 14339585STim.Szeto@Sun.COM break; 14349585STim.Szeto@Sun.COM case SBD_RET_GUID_ALREADY_REGISTERED: 14359585STim.Szeto@Sun.COM *ret = STMF_ERROR_GUID_IN_USE; 14369585STim.Szeto@Sun.COM break; 14379585STim.Szeto@Sun.COM case SBD_RET_META_PATH_NOT_ABSOLUTE: 14389585STim.Szeto@Sun.COM case SBD_RET_META_FILE_LOOKUP_FAILED: 14399585STim.Szeto@Sun.COM case SBD_RET_META_FILE_OPEN_FAILED: 14409585STim.Szeto@Sun.COM case SBD_RET_META_FILE_GETATTR_FAILED: 14419585STim.Szeto@Sun.COM case SBD_RET_NO_META: 14429585STim.Szeto@Sun.COM *ret = STMF_ERROR_META_FILE_NAME; 14439585STim.Szeto@Sun.COM break; 14449585STim.Szeto@Sun.COM case SBD_RET_DATA_PATH_NOT_ABSOLUTE: 14459585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_LOOKUP_FAILED: 14469585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_OPEN_FAILED: 14479585STim.Szeto@Sun.COM case SBD_RET_DATA_FILE_GETATTR_FAILED: 14489585STim.Szeto@Sun.COM *ret = STMF_ERROR_DATA_FILE_NAME; 14499585STim.Szeto@Sun.COM break; 14509585STim.Szeto@Sun.COM case SBD_RET_FILE_SIZE_ERROR: 14519585STim.Szeto@Sun.COM *ret = STMF_ERROR_FILE_SIZE_INVALID; 14529585STim.Szeto@Sun.COM break; 14539585STim.Szeto@Sun.COM case SBD_RET_SIZE_OUT_OF_RANGE: 14549585STim.Szeto@Sun.COM *ret = STMF_ERROR_SIZE_OUT_OF_RANGE; 14559585STim.Szeto@Sun.COM break; 14569585STim.Szeto@Sun.COM case SBD_RET_LU_BUSY: 14579585STim.Szeto@Sun.COM *ret = STMF_ERROR_LU_BUSY; 14589585STim.Szeto@Sun.COM break; 14599585STim.Szeto@Sun.COM case SBD_RET_WRITE_CACHE_SET_FAILED: 14609585STim.Szeto@Sun.COM *ret = STMF_ERROR_WRITE_CACHE_SET; 14619585STim.Szeto@Sun.COM break; 14629585STim.Szeto@Sun.COM default: 14639585STim.Szeto@Sun.COM *ret = STMF_STATUS_ERROR; 14649585STim.Szeto@Sun.COM break; 14659585STim.Szeto@Sun.COM } 14669585STim.Szeto@Sun.COM } 14679585STim.Szeto@Sun.COM 14689585STim.Szeto@Sun.COM /* 14699585STim.Szeto@Sun.COM * Creates a logical unit resource of type STMF_DISK. 14709585STim.Szeto@Sun.COM * 14719585STim.Szeto@Sun.COM * No defaults should be set here as all defaults are derived from the 14729585STim.Szeto@Sun.COM * driver's default settings. 14739585STim.Szeto@Sun.COM */ 14749585STim.Szeto@Sun.COM static int 14759585STim.Szeto@Sun.COM createDiskResource(luResourceImpl *hdl) 14769585STim.Szeto@Sun.COM { 14779585STim.Szeto@Sun.COM hdl->type = STMF_DISK; 14789585STim.Szeto@Sun.COM 14799585STim.Szeto@Sun.COM hdl->resource = calloc(1, sizeof (diskResource)); 14809585STim.Szeto@Sun.COM if (hdl->resource == NULL) { 14819585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 14829585STim.Szeto@Sun.COM } 14839585STim.Szeto@Sun.COM 14849585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 14859585STim.Szeto@Sun.COM } 14869585STim.Szeto@Sun.COM 14879585STim.Szeto@Sun.COM /* 14889585STim.Szeto@Sun.COM * stmfDeleteLu 14899585STim.Szeto@Sun.COM * 14909585STim.Szeto@Sun.COM * Purpose: Delete a logical unit 14919585STim.Szeto@Sun.COM * 14929585STim.Szeto@Sun.COM * hdl - handle to logical unit resource created via stmfCreateLuResource 14939585STim.Szeto@Sun.COM * 14949585STim.Szeto@Sun.COM * luGuid - If non-NULL, on success, contains the guid of the created logical 14959585STim.Szeto@Sun.COM * unit 14969585STim.Szeto@Sun.COM */ 14979585STim.Szeto@Sun.COM int 14989585STim.Szeto@Sun.COM stmfDeleteLu(stmfGuid *luGuid) 14999585STim.Szeto@Sun.COM { 15009585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15019585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 15029585STim.Szeto@Sun.COM 15039585STim.Szeto@Sun.COM if (luGuid == NULL) { 15049585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15059585STim.Szeto@Sun.COM } 15069585STim.Szeto@Sun.COM 15079585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 15089585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 15099585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 15109585STim.Szeto@Sun.COM return (ret); 15119585STim.Szeto@Sun.COM } else { 15129585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 15139585STim.Szeto@Sun.COM ret = deleteDiskLu(luGuid); 15149585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 15159585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 15169585STim.Szeto@Sun.COM } else { 15179585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15189585STim.Szeto@Sun.COM } 15199585STim.Szeto@Sun.COM } 15209585STim.Szeto@Sun.COM 15219585STim.Szeto@Sun.COM return (ret); 15229585STim.Szeto@Sun.COM } 15239585STim.Szeto@Sun.COM 15249585STim.Szeto@Sun.COM static int 15259585STim.Szeto@Sun.COM deleteDiskLu(stmfGuid *luGuid) 15269585STim.Szeto@Sun.COM { 15279585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15289585STim.Szeto@Sun.COM int fd; 15299585STim.Szeto@Sun.COM int savedErrno; 15309585STim.Szeto@Sun.COM int ioctlRet; 15319585STim.Szeto@Sun.COM sbd_delete_lu_t deleteLu = {0}; 15329585STim.Szeto@Sun.COM 15339585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 15349585STim.Szeto@Sun.COM 15359585STim.Szeto@Sun.COM /* 15369585STim.Szeto@Sun.COM * Open control node for sbd 15379585STim.Szeto@Sun.COM */ 15389585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 15399585STim.Szeto@Sun.COM return (ret); 15409585STim.Szeto@Sun.COM 15419585STim.Szeto@Sun.COM ret = removeGuidFromDiskStore(luGuid); 15429585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 15439585STim.Szeto@Sun.COM goto done; 15449585STim.Szeto@Sun.COM } 15459585STim.Szeto@Sun.COM 15469585STim.Szeto@Sun.COM bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid)); 15479585STim.Szeto@Sun.COM deleteLu.dlu_by_guid = 1; 15489585STim.Szeto@Sun.COM 15499585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 15509585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sizeof (deleteLu); 15519585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu; 15529585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl); 15539585STim.Szeto@Sun.COM if (ioctlRet != 0) { 15549585STim.Szeto@Sun.COM savedErrno = errno; 15559585STim.Szeto@Sun.COM switch (savedErrno) { 15569585STim.Szeto@Sun.COM case EBUSY: 15579585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 15589585STim.Szeto@Sun.COM break; 15599585STim.Szeto@Sun.COM case EPERM: 15609585STim.Szeto@Sun.COM case EACCES: 15619585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 15629585STim.Szeto@Sun.COM break; 15639585STim.Szeto@Sun.COM case ENOENT: 15649585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 15659585STim.Szeto@Sun.COM break; 15669585STim.Szeto@Sun.COM default: 15679585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 15689585STim.Szeto@Sun.COM "deleteDiskLu:ioctl error(%d) (%d) (%d)", 15699585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 15709585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 15719585STim.Szeto@Sun.COM break; 15729585STim.Szeto@Sun.COM } 15739585STim.Szeto@Sun.COM } 15749585STim.Szeto@Sun.COM 15759585STim.Szeto@Sun.COM done: 15769585STim.Szeto@Sun.COM (void) close(fd); 15779585STim.Szeto@Sun.COM return (ret); 15789585STim.Szeto@Sun.COM } 15799585STim.Szeto@Sun.COM 15809585STim.Szeto@Sun.COM /* 15819585STim.Szeto@Sun.COM * stmfModifyLu 15829585STim.Szeto@Sun.COM * 15839585STim.Szeto@Sun.COM * Purpose: Modify properties of a logical unit 15849585STim.Szeto@Sun.COM * 15859585STim.Szeto@Sun.COM * luGuid - guid of registered logical unit 15869585STim.Szeto@Sun.COM * prop - property to modify 15879585STim.Szeto@Sun.COM * propVal - property value to set 15889585STim.Szeto@Sun.COM * 15899585STim.Szeto@Sun.COM */ 15909585STim.Szeto@Sun.COM int 15919585STim.Szeto@Sun.COM stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal) 15929585STim.Szeto@Sun.COM { 15939585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 15949585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 15959585STim.Szeto@Sun.COM 15969585STim.Szeto@Sun.COM if (luGuid == NULL) { 15979585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 15989585STim.Szeto@Sun.COM } 15999585STim.Szeto@Sun.COM 16009585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 16019585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 16029585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 16039585STim.Szeto@Sun.COM return (ret); 16049585STim.Szeto@Sun.COM } else { 16059585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 16069585STim.Szeto@Sun.COM ret = modifyDiskLuProp(luGuid, NULL, prop, propVal); 16079585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 16089585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 16099585STim.Szeto@Sun.COM } else { 16109585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 16119585STim.Szeto@Sun.COM } 16129585STim.Szeto@Sun.COM } 16139585STim.Szeto@Sun.COM 16149585STim.Szeto@Sun.COM return (ret); 16159585STim.Szeto@Sun.COM } 16169585STim.Szeto@Sun.COM 16179585STim.Szeto@Sun.COM /* 16189585STim.Szeto@Sun.COM * stmfModifyLuByFname 16199585STim.Szeto@Sun.COM * 16209585STim.Szeto@Sun.COM * Purpose: Modify a device by filename. Device does not need to be registered. 16219585STim.Szeto@Sun.COM * 16229585STim.Szeto@Sun.COM * dType - type of device to modify 16239585STim.Szeto@Sun.COM * STMF_DISK 16249585STim.Szeto@Sun.COM * 16259585STim.Szeto@Sun.COM * fname - filename or meta filename 16269585STim.Szeto@Sun.COM * prop - valid property identifier 16279585STim.Szeto@Sun.COM * propVal - property value 16289585STim.Szeto@Sun.COM * 16299585STim.Szeto@Sun.COM */ 16309585STim.Szeto@Sun.COM int 16319585STim.Szeto@Sun.COM stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop, 16329585STim.Szeto@Sun.COM const char *propVal) 16339585STim.Szeto@Sun.COM { 16349585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 16359585STim.Szeto@Sun.COM if (fname == NULL) { 16369585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 16379585STim.Szeto@Sun.COM } 16389585STim.Szeto@Sun.COM 16399585STim.Szeto@Sun.COM if (dType == STMF_DISK) { 16409585STim.Szeto@Sun.COM ret = modifyDiskLuProp(NULL, fname, prop, propVal); 16419585STim.Szeto@Sun.COM } else { 16429585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 16439585STim.Szeto@Sun.COM } 16449585STim.Szeto@Sun.COM 16459585STim.Szeto@Sun.COM return (ret); 16469585STim.Szeto@Sun.COM } 16479585STim.Szeto@Sun.COM 16489585STim.Szeto@Sun.COM static int 16499585STim.Szeto@Sun.COM modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop, 16509585STim.Szeto@Sun.COM const char *propVal) 16519585STim.Szeto@Sun.COM { 16529585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 16539585STim.Szeto@Sun.COM luResource hdl = NULL; 16549585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl; 16559585STim.Szeto@Sun.COM 16569585STim.Szeto@Sun.COM ret = stmfCreateLuResource(STMF_DISK, &hdl); 16579585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 16589585STim.Szeto@Sun.COM return (ret); 16599585STim.Szeto@Sun.COM } 16609585STim.Szeto@Sun.COM ret = validateModifyDiskProp(prop); 16619585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 16629585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 16639585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROP); 16649585STim.Szeto@Sun.COM } 16659585STim.Szeto@Sun.COM ret = stmfSetLuProp(hdl, prop, propVal); 16669585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 16679585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 16689585STim.Szeto@Sun.COM return (ret); 16699585STim.Szeto@Sun.COM } 16709585STim.Szeto@Sun.COM luPropsHdl = hdl; 16719585STim.Szeto@Sun.COM ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname); 16729585STim.Szeto@Sun.COM (void) stmfFreeLuResource(hdl); 16739585STim.Szeto@Sun.COM return (ret); 16749585STim.Szeto@Sun.COM } 16759585STim.Szeto@Sun.COM 16769585STim.Szeto@Sun.COM static int 16779585STim.Szeto@Sun.COM validateModifyDiskProp(uint32_t prop) 16789585STim.Szeto@Sun.COM { 16799585STim.Szeto@Sun.COM switch (prop) { 16809585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 16819585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 168210113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 16839585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 16849585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 16859585STim.Szeto@Sun.COM return (STMF_STATUS_SUCCESS); 16869585STim.Szeto@Sun.COM break; 16879585STim.Szeto@Sun.COM default: 16889585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 16899585STim.Szeto@Sun.COM break; 16909585STim.Szeto@Sun.COM } 16919585STim.Szeto@Sun.COM } 16929585STim.Szeto@Sun.COM 16939585STim.Szeto@Sun.COM static int 16949585STim.Szeto@Sun.COM modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname) 16959585STim.Szeto@Sun.COM { 16969585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 16979585STim.Szeto@Sun.COM int luAliasLen = 0; 169810113SNattuvetty.Bhavyan@Sun.COM int luMgmtUrlLen = 0; 16999585STim.Szeto@Sun.COM int mluBufSize = 0; 17009585STim.Szeto@Sun.COM int bufOffset = 0; 17019585STim.Szeto@Sun.COM int fd = 0; 17029585STim.Szeto@Sun.COM int ioctlRet; 17039585STim.Szeto@Sun.COM int savedErrno; 17049585STim.Szeto@Sun.COM int fnameSize = 0; 17059585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 17069585STim.Szeto@Sun.COM 17079585STim.Szeto@Sun.COM sbd_modify_lu_t *sbdLu = NULL; 17089585STim.Szeto@Sun.COM 17099585STim.Szeto@Sun.COM if (luGuid == NULL && fname == NULL) { 17109585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 17119585STim.Szeto@Sun.COM } 17129585STim.Szeto@Sun.COM 17139585STim.Szeto@Sun.COM if (fname) { 17149585STim.Szeto@Sun.COM fnameSize = strlen(fname) + 1; 17159585STim.Szeto@Sun.COM mluBufSize += fnameSize; 17169585STim.Szeto@Sun.COM } 17179585STim.Szeto@Sun.COM 17189585STim.Szeto@Sun.COM /* 17199585STim.Szeto@Sun.COM * Open control node for sbd 17209585STim.Szeto@Sun.COM */ 17219585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 17229585STim.Szeto@Sun.COM return (ret); 17239585STim.Szeto@Sun.COM 17249585STim.Szeto@Sun.COM if (disk->luAliasValid) { 17259585STim.Szeto@Sun.COM luAliasLen = strlen(disk->luAlias); 17269585STim.Szeto@Sun.COM mluBufSize += luAliasLen + 1; 17279585STim.Szeto@Sun.COM } 17289585STim.Szeto@Sun.COM 172910113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 173010113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen = strlen(disk->luMgmtUrl); 173110113SNattuvetty.Bhavyan@Sun.COM mluBufSize += luMgmtUrlLen + 1; 173210113SNattuvetty.Bhavyan@Sun.COM } 173310113SNattuvetty.Bhavyan@Sun.COM 17349585STim.Szeto@Sun.COM /* 17359585STim.Szeto@Sun.COM * 8 is the size of the buffer set aside for 17369585STim.Szeto@Sun.COM * concatenation of variable length fields 17379585STim.Szeto@Sun.COM */ 17389585STim.Szeto@Sun.COM sbdLu = (sbd_modify_lu_t *)calloc(1, 17399585STim.Szeto@Sun.COM sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize); 17409585STim.Szeto@Sun.COM if (sbdLu == NULL) { 17419585STim.Szeto@Sun.COM (void) close(fd); 17429585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 17439585STim.Szeto@Sun.COM } 17449585STim.Szeto@Sun.COM 17459585STim.Szeto@Sun.COM sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) + 17469585STim.Szeto@Sun.COM mluBufSize - 8 + fnameSize; 17479585STim.Szeto@Sun.COM 17489585STim.Szeto@Sun.COM if (disk->luAliasValid) { 17499585STim.Szeto@Sun.COM sbdLu->mlu_alias_valid = 1; 17509585STim.Szeto@Sun.COM sbdLu->mlu_alias_off = bufOffset; 17519585STim.Szeto@Sun.COM bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]), 17529585STim.Szeto@Sun.COM luAliasLen + 1); 17539585STim.Szeto@Sun.COM bufOffset += luAliasLen + 1; 17549585STim.Szeto@Sun.COM } 17559585STim.Szeto@Sun.COM 175610113SNattuvetty.Bhavyan@Sun.COM if (disk->luMgmtUrlValid) { 175710113SNattuvetty.Bhavyan@Sun.COM sbdLu->mlu_mgmt_url_valid = 1; 175810113SNattuvetty.Bhavyan@Sun.COM sbdLu->mlu_mgmt_url_off = bufOffset; 175910113SNattuvetty.Bhavyan@Sun.COM bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]), 176010113SNattuvetty.Bhavyan@Sun.COM luMgmtUrlLen + 1); 176110113SNattuvetty.Bhavyan@Sun.COM bufOffset += luMgmtUrlLen + 1; 176210113SNattuvetty.Bhavyan@Sun.COM } 176310113SNattuvetty.Bhavyan@Sun.COM 17649585STim.Szeto@Sun.COM if (disk->luSizeValid) { 17659585STim.Szeto@Sun.COM sbdLu->mlu_lu_size_valid = 1; 17669585STim.Szeto@Sun.COM sbdLu->mlu_lu_size = disk->luSize; 17679585STim.Szeto@Sun.COM } 17689585STim.Szeto@Sun.COM 17699585STim.Szeto@Sun.COM if (disk->writeProtectEnableValid) { 17709585STim.Szeto@Sun.COM sbdLu->mlu_write_protected_valid = 1; 17719585STim.Szeto@Sun.COM if (disk->writeProtectEnable) { 17729585STim.Szeto@Sun.COM sbdLu->mlu_write_protected = 1; 17739585STim.Szeto@Sun.COM } 17749585STim.Szeto@Sun.COM } 17759585STim.Szeto@Sun.COM 17769585STim.Szeto@Sun.COM if (disk->writebackCacheDisableValid) { 17779585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable_valid = 1; 17789585STim.Szeto@Sun.COM if (disk->writebackCacheDisable) { 17799585STim.Szeto@Sun.COM sbdLu->mlu_writeback_cache_disable = 1; 17809585STim.Szeto@Sun.COM } 17819585STim.Szeto@Sun.COM } 17829585STim.Szeto@Sun.COM 17839585STim.Szeto@Sun.COM if (luGuid) { 17849585STim.Szeto@Sun.COM bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid)); 17859585STim.Szeto@Sun.COM sbdLu->mlu_by_guid = 1; 17869585STim.Szeto@Sun.COM } else { 17879585STim.Szeto@Sun.COM sbdLu->mlu_fname_off = bufOffset; 17889585STim.Szeto@Sun.COM bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1); 17899585STim.Szeto@Sun.COM sbdLu->mlu_by_fname = 1; 17909585STim.Szeto@Sun.COM } 17919585STim.Szeto@Sun.COM 17929585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 17939585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size; 17949585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu; 17959585STim.Szeto@Sun.COM 17969585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl); 17979585STim.Szeto@Sun.COM if (ioctlRet != 0) { 17989585STim.Szeto@Sun.COM savedErrno = errno; 17999585STim.Szeto@Sun.COM switch (savedErrno) { 18009585STim.Szeto@Sun.COM case EBUSY: 18019585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 18029585STim.Szeto@Sun.COM break; 18039585STim.Szeto@Sun.COM case EPERM: 18049585STim.Szeto@Sun.COM case EACCES: 18059585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 18069585STim.Szeto@Sun.COM break; 18079585STim.Szeto@Sun.COM default: 18089585STim.Szeto@Sun.COM diskError(sbdIoctl.stmf_error, &ret); 18099585STim.Szeto@Sun.COM if (ret == STMF_STATUS_ERROR) { 18109585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 18119585STim.Szeto@Sun.COM "modifyDiskLu:ioctl " 18129585STim.Szeto@Sun.COM "error(%d) (%d) (%d)", ioctlRet, 18139585STim.Szeto@Sun.COM sbdIoctl.stmf_error, savedErrno); 18149585STim.Szeto@Sun.COM } 18159585STim.Szeto@Sun.COM break; 18169585STim.Szeto@Sun.COM } 18179585STim.Szeto@Sun.COM } 18189585STim.Szeto@Sun.COM 18199585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 18209585STim.Szeto@Sun.COM goto done; 18219585STim.Szeto@Sun.COM } 18229585STim.Szeto@Sun.COM 18239585STim.Szeto@Sun.COM done: 18249585STim.Szeto@Sun.COM free(sbdLu); 18259585STim.Szeto@Sun.COM (void) close(fd); 18269585STim.Szeto@Sun.COM return (ret); 18279585STim.Szeto@Sun.COM } 18289585STim.Szeto@Sun.COM 18299585STim.Szeto@Sun.COM /* 18309585STim.Szeto@Sun.COM * removeGuidFromDiskStore 18319585STim.Szeto@Sun.COM * 18329585STim.Szeto@Sun.COM * Purpose: delete a logical unit from the sbd provider data 18339585STim.Szeto@Sun.COM */ 18349585STim.Szeto@Sun.COM static int 18359585STim.Szeto@Sun.COM removeGuidFromDiskStore(stmfGuid *guid) 18369585STim.Szeto@Sun.COM { 18379585STim.Szeto@Sun.COM return (persistDiskGuid(guid, NULL, B_FALSE)); 18389585STim.Szeto@Sun.COM } 18399585STim.Szeto@Sun.COM 18409585STim.Szeto@Sun.COM 18419585STim.Szeto@Sun.COM /* 18429585STim.Szeto@Sun.COM * addGuidToDiskStore 18439585STim.Szeto@Sun.COM * 18449585STim.Szeto@Sun.COM * Purpose: add a logical unit to the sbd provider data 18459585STim.Szeto@Sun.COM */ 18469585STim.Szeto@Sun.COM static int 18479585STim.Szeto@Sun.COM addGuidToDiskStore(stmfGuid *guid, char *filename) 18489585STim.Szeto@Sun.COM { 18499585STim.Szeto@Sun.COM return (persistDiskGuid(guid, filename, B_TRUE)); 18509585STim.Szeto@Sun.COM } 18519585STim.Szeto@Sun.COM 18529585STim.Szeto@Sun.COM 18539585STim.Szeto@Sun.COM /* 18549585STim.Szeto@Sun.COM * persistDiskGuid 18559585STim.Szeto@Sun.COM * 18569585STim.Szeto@Sun.COM * Purpose: Persist or unpersist a guid for the sbd provider data 18579585STim.Szeto@Sun.COM * 18589585STim.Szeto@Sun.COM */ 18599585STim.Szeto@Sun.COM static int 18609585STim.Szeto@Sun.COM persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist) 18619585STim.Szeto@Sun.COM { 18629585STim.Szeto@Sun.COM char guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0}; 18639585STim.Szeto@Sun.COM nvlist_t *nvl = NULL; 18649585STim.Szeto@Sun.COM 18659585STim.Szeto@Sun.COM uint64_t setToken; 18669585STim.Szeto@Sun.COM boolean_t retryGetProviderData = B_FALSE; 18679585STim.Szeto@Sun.COM boolean_t newData = B_FALSE; 18689585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 18699585STim.Szeto@Sun.COM int retryCnt = 0; 18709585STim.Szeto@Sun.COM int stmfRet; 18719585STim.Szeto@Sun.COM 18729585STim.Szeto@Sun.COM /* if we're persisting a guid, there must be a filename */ 18739585STim.Szeto@Sun.COM if (persist && !filename) { 18749585STim.Szeto@Sun.COM return (1); 18759585STim.Szeto@Sun.COM } 18769585STim.Szeto@Sun.COM 18779585STim.Szeto@Sun.COM /* guid is stored in lowercase ascii hex */ 18789585STim.Szeto@Sun.COM (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf), 18799585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" 18809585STim.Szeto@Sun.COM "%02x%02x%02x%02x%02x%02x", 18819585STim.Szeto@Sun.COM guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3], 18829585STim.Szeto@Sun.COM guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7], 18839585STim.Szeto@Sun.COM guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11], 18849585STim.Szeto@Sun.COM guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]); 18859585STim.Szeto@Sun.COM 18869585STim.Szeto@Sun.COM 18879585STim.Szeto@Sun.COM do { 18889585STim.Szeto@Sun.COM retryGetProviderData = B_FALSE; 18899585STim.Szeto@Sun.COM stmfRet = stmfGetProviderDataProt("sbd", &nvl, 18909585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 18919585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 18929585STim.Szeto@Sun.COM if (persist && stmfRet == STMF_ERROR_NOT_FOUND) { 18939585STim.Szeto@Sun.COM ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0); 18949585STim.Szeto@Sun.COM if (ret != 0) { 18959585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 18969585STim.Szeto@Sun.COM "unpersistGuid:nvlist_alloc(%d)", 18979585STim.Szeto@Sun.COM ret); 18989585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 18999585STim.Szeto@Sun.COM goto done; 19009585STim.Szeto@Sun.COM } 19019585STim.Szeto@Sun.COM newData = B_TRUE; 19029585STim.Szeto@Sun.COM } else { 19039585STim.Szeto@Sun.COM ret = stmfRet; 19049585STim.Szeto@Sun.COM goto done; 19059585STim.Szeto@Sun.COM } 19069585STim.Szeto@Sun.COM } 19079585STim.Szeto@Sun.COM if (persist) { 19089585STim.Szeto@Sun.COM ret = nvlist_add_string(nvl, guidAsciiBuf, filename); 19099585STim.Szeto@Sun.COM } else { 19109585STim.Szeto@Sun.COM ret = nvlist_remove(nvl, guidAsciiBuf, 19119585STim.Szeto@Sun.COM DATA_TYPE_STRING); 19129585STim.Szeto@Sun.COM if (ret == ENOENT) { 19139585STim.Szeto@Sun.COM ret = 0; 19149585STim.Szeto@Sun.COM } 19159585STim.Szeto@Sun.COM } 19169585STim.Szeto@Sun.COM if (ret == 0) { 19179585STim.Szeto@Sun.COM if (newData) { 19189585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 19199585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, NULL); 19209585STim.Szeto@Sun.COM } else { 19219585STim.Szeto@Sun.COM stmfRet = stmfSetProviderDataProt("sbd", nvl, 19229585STim.Szeto@Sun.COM STMF_LU_PROVIDER_TYPE, &setToken); 19239585STim.Szeto@Sun.COM } 19249585STim.Szeto@Sun.COM if (stmfRet != STMF_STATUS_SUCCESS) { 19259585STim.Szeto@Sun.COM if (stmfRet == STMF_ERROR_BUSY) { 19269585STim.Szeto@Sun.COM /* get/set failed, try again */ 19279585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 19289585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 19299585STim.Szeto@Sun.COM ret = stmfRet; 19309585STim.Szeto@Sun.COM break; 19319585STim.Szeto@Sun.COM } 19329585STim.Szeto@Sun.COM continue; 19339585STim.Szeto@Sun.COM } else if (stmfRet == 19349585STim.Szeto@Sun.COM STMF_ERROR_PROV_DATA_STALE) { 19359585STim.Szeto@Sun.COM /* update failed, try again */ 19369585STim.Szeto@Sun.COM nvlist_free(nvl); 19379585STim.Szeto@Sun.COM nvl = NULL; 19389585STim.Szeto@Sun.COM retryGetProviderData = B_TRUE; 19399585STim.Szeto@Sun.COM if (retryCnt++ > MAX_PROVIDER_RETRY) { 19409585STim.Szeto@Sun.COM ret = stmfRet; 19419585STim.Szeto@Sun.COM break; 19429585STim.Szeto@Sun.COM } 19439585STim.Szeto@Sun.COM continue; 19449585STim.Szeto@Sun.COM } else { 19459585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 19469585STim.Szeto@Sun.COM "unpersistGuid:error(%x)", stmfRet); 19479585STim.Szeto@Sun.COM ret = stmfRet; 19489585STim.Szeto@Sun.COM } 19499585STim.Szeto@Sun.COM break; 19509585STim.Szeto@Sun.COM } 19519585STim.Szeto@Sun.COM } else { 19529585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 19539585STim.Szeto@Sun.COM "unpersistGuid:error nvlist_add/remove(%d)", 19549585STim.Szeto@Sun.COM ret); 19559585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 19569585STim.Szeto@Sun.COM } 19579585STim.Szeto@Sun.COM } while (retryGetProviderData); 19589585STim.Szeto@Sun.COM 19599585STim.Szeto@Sun.COM done: 19609585STim.Szeto@Sun.COM nvlist_free(nvl); 19619585STim.Szeto@Sun.COM return (ret); 19629585STim.Szeto@Sun.COM } 19639585STim.Szeto@Sun.COM 19649585STim.Szeto@Sun.COM 19659585STim.Szeto@Sun.COM /* 19669585STim.Szeto@Sun.COM * stmfGetLuProp 19679585STim.Szeto@Sun.COM * 19689585STim.Szeto@Sun.COM * Purpose: Get current value for a resource property 19699585STim.Szeto@Sun.COM * 19709585STim.Szeto@Sun.COM * hdl - luResource from a previous call to stmfCreateLuResource 19719585STim.Szeto@Sun.COM * 19729585STim.Szeto@Sun.COM * resourceProp - a valid resource property type 19739585STim.Szeto@Sun.COM * 19749585STim.Szeto@Sun.COM * propVal - void pointer to a pointer of the value to be retrieved 19759585STim.Szeto@Sun.COM */ 19769585STim.Szeto@Sun.COM int 19779585STim.Szeto@Sun.COM stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen) 19789585STim.Szeto@Sun.COM { 19799585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 19809585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 19819585STim.Szeto@Sun.COM if (hdl == NULL || propLen == NULL || propVal == NULL) { 19829585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 19839585STim.Szeto@Sun.COM } 19849585STim.Szeto@Sun.COM 19859585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 19869585STim.Szeto@Sun.COM ret = getDiskProp(luPropsHdl, prop, propVal, propLen); 19879585STim.Szeto@Sun.COM } else { 19889585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 19899585STim.Szeto@Sun.COM } 19909585STim.Szeto@Sun.COM 19919585STim.Szeto@Sun.COM return (ret); 19929585STim.Szeto@Sun.COM } 19939585STim.Szeto@Sun.COM 19949585STim.Szeto@Sun.COM /* 19959585STim.Szeto@Sun.COM * stmfGetLuResource 19969585STim.Szeto@Sun.COM * 19979585STim.Szeto@Sun.COM * Purpose: Get a logical unit resource handle for a given logical unit. 19989585STim.Szeto@Sun.COM * 19999585STim.Szeto@Sun.COM * hdl - pointer to luResource 20009585STim.Szeto@Sun.COM */ 20019585STim.Szeto@Sun.COM int 20029585STim.Szeto@Sun.COM stmfGetLuResource(stmfGuid *luGuid, luResource *hdl) 20039585STim.Szeto@Sun.COM { 20049585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 20059585STim.Szeto@Sun.COM stmfLogicalUnitProperties luProps; 20069585STim.Szeto@Sun.COM 20079585STim.Szeto@Sun.COM 20089585STim.Szeto@Sun.COM /* Check logical unit provider name to call correct dtype function */ 20099585STim.Szeto@Sun.COM if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps)) 20109585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 20119585STim.Szeto@Sun.COM return (ret); 20129585STim.Szeto@Sun.COM } else { 20139585STim.Szeto@Sun.COM if (strcmp(luProps.providerName, "sbd") == 0) { 20149585STim.Szeto@Sun.COM ret = getDiskAllProps(luGuid, hdl); 20159585STim.Szeto@Sun.COM } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) { 20169585STim.Szeto@Sun.COM return (STMF_ERROR_NOT_FOUND); 20179585STim.Szeto@Sun.COM } else { 20189585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 20199585STim.Szeto@Sun.COM } 20209585STim.Szeto@Sun.COM } 20219585STim.Szeto@Sun.COM 20229585STim.Szeto@Sun.COM return (ret); 20239585STim.Szeto@Sun.COM } 20249585STim.Szeto@Sun.COM 20259585STim.Szeto@Sun.COM /* 20269585STim.Szeto@Sun.COM * getDiskAllProps 20279585STim.Szeto@Sun.COM * 20289585STim.Szeto@Sun.COM * Purpose: load all disk properties from sbd driver 20299585STim.Szeto@Sun.COM * 20309585STim.Szeto@Sun.COM * luGuid - guid of disk device for which properties are to be retrieved 20319585STim.Szeto@Sun.COM * hdl - allocated luResource into which properties are to be copied 20329585STim.Szeto@Sun.COM * 20339585STim.Szeto@Sun.COM */ 20349585STim.Szeto@Sun.COM static int 20359585STim.Szeto@Sun.COM getDiskAllProps(stmfGuid *luGuid, luResource *hdl) 20369585STim.Szeto@Sun.COM { 20379585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 20389585STim.Szeto@Sun.COM int fd; 20399585STim.Szeto@Sun.COM sbd_lu_props_t *sbdProps; 20409585STim.Szeto@Sun.COM int ioctlRet; 20419585STim.Szeto@Sun.COM int savedErrno; 20429585STim.Szeto@Sun.COM int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS; 20439585STim.Szeto@Sun.COM stmf_iocdata_t sbdIoctl = {0}; 20449585STim.Szeto@Sun.COM 20459585STim.Szeto@Sun.COM /* 20469585STim.Szeto@Sun.COM * Open control node for sbd 20479585STim.Szeto@Sun.COM */ 20489585STim.Szeto@Sun.COM if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS) 20499585STim.Szeto@Sun.COM return (ret); 20509585STim.Szeto@Sun.COM 20519585STim.Szeto@Sun.COM 20529585STim.Szeto@Sun.COM *hdl = calloc(1, sizeof (luResourceImpl)); 20539585STim.Szeto@Sun.COM if (*hdl == NULL) { 20549585STim.Szeto@Sun.COM (void) close(fd); 20559585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 20569585STim.Szeto@Sun.COM } 20579585STim.Szeto@Sun.COM 20589585STim.Szeto@Sun.COM sbdProps = calloc(1, sbdPropsSize); 20599585STim.Szeto@Sun.COM if (sbdProps == NULL) { 20609585STim.Szeto@Sun.COM free(*hdl); 20619585STim.Szeto@Sun.COM (void) close(fd); 20629585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 20639585STim.Szeto@Sun.COM } 20649585STim.Szeto@Sun.COM 20659585STim.Szeto@Sun.COM ret = createDiskResource((luResourceImpl *)*hdl); 20669585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 20679585STim.Szeto@Sun.COM free(*hdl); 20689585STim.Szeto@Sun.COM (void) close(fd); 20699585STim.Szeto@Sun.COM return (ret); 20709585STim.Szeto@Sun.COM } 20719585STim.Szeto@Sun.COM 20729585STim.Szeto@Sun.COM sbdProps->slp_input_guid = 1; 20739585STim.Szeto@Sun.COM bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid)); 20749585STim.Szeto@Sun.COM 20759585STim.Szeto@Sun.COM sbdIoctl.stmf_version = STMF_VERSION_1; 20769585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf_size = sbdPropsSize; 20779585STim.Szeto@Sun.COM sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps; 20789585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf_size = sbdPropsSize; 20799585STim.Szeto@Sun.COM sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps; 20809585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl); 20819585STim.Szeto@Sun.COM if (ioctlRet != 0) { 20829585STim.Szeto@Sun.COM savedErrno = errno; 20839585STim.Szeto@Sun.COM switch (savedErrno) { 20849585STim.Szeto@Sun.COM case EBUSY: 20859585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 20869585STim.Szeto@Sun.COM break; 20879585STim.Szeto@Sun.COM case EPERM: 20889585STim.Szeto@Sun.COM case EACCES: 20899585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 20909585STim.Szeto@Sun.COM break; 20919585STim.Szeto@Sun.COM case ENOENT: 20929585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 20939585STim.Szeto@Sun.COM break; 20949585STim.Szeto@Sun.COM default: 20959585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 20969585STim.Szeto@Sun.COM "getDiskAllProps:ioctl error(%d) (%d) (%d)", 20979585STim.Szeto@Sun.COM ioctlRet, sbdIoctl.stmf_error, savedErrno); 20989585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 20999585STim.Szeto@Sun.COM break; 21009585STim.Szeto@Sun.COM } 21019585STim.Szeto@Sun.COM } 21029585STim.Szeto@Sun.COM 21039585STim.Szeto@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 21049585STim.Szeto@Sun.COM ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps); 21059585STim.Szeto@Sun.COM } 21069585STim.Szeto@Sun.COM 21079585STim.Szeto@Sun.COM (void) close(fd); 21089585STim.Szeto@Sun.COM return (ret); 21099585STim.Szeto@Sun.COM } 21109585STim.Szeto@Sun.COM 21119585STim.Szeto@Sun.COM /* 21129585STim.Szeto@Sun.COM * loadDiskPropsFromDriver 21139585STim.Szeto@Sun.COM * 21149585STim.Szeto@Sun.COM * Purpose: Retrieve all disk type properties from sbd driver 21159585STim.Szeto@Sun.COM * 21169585STim.Szeto@Sun.COM * hdl - Allocated luResourceImpl 21179585STim.Szeto@Sun.COM * sbdProps - sbd_lu_props_t structure returned from sbd driver 21189585STim.Szeto@Sun.COM * 21199585STim.Szeto@Sun.COM */ 21209585STim.Szeto@Sun.COM static int 21219585STim.Szeto@Sun.COM loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps) 21229585STim.Szeto@Sun.COM { 21239585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 21249585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 21259585STim.Szeto@Sun.COM /* copy guid */ 21269585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 21279585STim.Szeto@Sun.COM bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid)); 21289585STim.Szeto@Sun.COM 21299585STim.Szeto@Sun.COM if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) { 21309585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 21319585STim.Szeto@Sun.COM if (strlcpy(diskLu->luMetaFileName, 21329585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]), 21339585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) >= 21349585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 21359585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21369585STim.Szeto@Sun.COM } 21379585STim.Szeto@Sun.COM } 21389585STim.Szeto@Sun.COM 21399585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 21409585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 21419585STim.Szeto@Sun.COM if (strlcpy(diskLu->luDataFileName, 21429585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]), 21439585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) >= 21449585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 21459585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21469585STim.Szeto@Sun.COM } 21479585STim.Szeto@Sun.COM } 21489585STim.Szeto@Sun.COM 21499585STim.Szeto@Sun.COM if (sbdProps->slp_serial_valid) { 21509585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 21519585STim.Szeto@Sun.COM bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]), 21529585STim.Szeto@Sun.COM diskLu->serialNum, sbdProps->slp_serial_size); 21539585STim.Szeto@Sun.COM } 21549585STim.Szeto@Sun.COM 215510113SNattuvetty.Bhavyan@Sun.COM if (sbdProps->slp_mgmt_url_valid) { 215610113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 215710113SNattuvetty.Bhavyan@Sun.COM if (strlcpy(diskLu->luMgmtUrl, 215810113SNattuvetty.Bhavyan@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]), 215910113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) >= 216010113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 216110113SNattuvetty.Bhavyan@Sun.COM return (STMF_STATUS_ERROR); 216210113SNattuvetty.Bhavyan@Sun.COM } 216310113SNattuvetty.Bhavyan@Sun.COM } 216410113SNattuvetty.Bhavyan@Sun.COM 21659585STim.Szeto@Sun.COM if (sbdProps->slp_alias_valid) { 21669585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 21679585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 21689585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]), 21699585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 21709585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 21719585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21729585STim.Szeto@Sun.COM } 21739585STim.Szeto@Sun.COM } else { /* set alias to data filename if not set */ 21749585STim.Szeto@Sun.COM if (sbdProps->slp_data_fname_valid) { 21759585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 21769585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, 21779585STim.Szeto@Sun.COM (char *)&(sbdProps->slp_buf[ 21789585STim.Szeto@Sun.COM sbdProps->slp_data_fname_off]), 21799585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 21809585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 21819585STim.Szeto@Sun.COM return (STMF_STATUS_ERROR); 21829585STim.Szeto@Sun.COM } 21839585STim.Szeto@Sun.COM } 21849585STim.Szeto@Sun.COM } 21859585STim.Szeto@Sun.COM 21869585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 21879585STim.Szeto@Sun.COM bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid)); 21889585STim.Szeto@Sun.COM 21899585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 21909585STim.Szeto@Sun.COM bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid)); 21919585STim.Szeto@Sun.COM 21929585STim.Szeto@Sun.COM diskLu->revValid = B_TRUE; 21939585STim.Szeto@Sun.COM bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev)); 21949585STim.Szeto@Sun.COM 21959585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 21969585STim.Szeto@Sun.COM if (sbdProps->slp_write_protected) { 21979585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 21989585STim.Szeto@Sun.COM } 21999585STim.Szeto@Sun.COM 22009585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 22019585STim.Szeto@Sun.COM if (sbdProps->slp_writeback_cache_disable_cur) { 22029585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 22039585STim.Szeto@Sun.COM } 22049585STim.Szeto@Sun.COM 22059585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 22069585STim.Szeto@Sun.COM diskLu->blkSize = sbdProps->slp_blksize; 22079585STim.Szeto@Sun.COM 22089585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 22099585STim.Szeto@Sun.COM diskLu->luSize = sbdProps->slp_lu_size; 22109585STim.Szeto@Sun.COM 22119585STim.Szeto@Sun.COM return (ret); 22129585STim.Szeto@Sun.COM } 22139585STim.Szeto@Sun.COM 22149585STim.Szeto@Sun.COM 22159585STim.Szeto@Sun.COM /* 22169585STim.Szeto@Sun.COM * stmfSetLuProp 22179585STim.Szeto@Sun.COM * 22189585STim.Szeto@Sun.COM * Purpose: set a property on an luResource 22199585STim.Szeto@Sun.COM * 22209585STim.Szeto@Sun.COM * hdl - allocated luResource 22219585STim.Szeto@Sun.COM * prop - property identifier 22229585STim.Szeto@Sun.COM * propVal - property value to be set 22239585STim.Szeto@Sun.COM */ 22249585STim.Szeto@Sun.COM int 22259585STim.Szeto@Sun.COM stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal) 22269585STim.Szeto@Sun.COM { 22279585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 22289585STim.Szeto@Sun.COM luResourceImpl *luPropsHdl = hdl; 22299585STim.Szeto@Sun.COM if (hdl == NULL) { 22309585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22319585STim.Szeto@Sun.COM } 22329585STim.Szeto@Sun.COM 22339585STim.Szeto@Sun.COM if (luPropsHdl->type == STMF_DISK) { 22349585STim.Szeto@Sun.COM ret = setDiskProp(luPropsHdl, prop, propVal); 22359585STim.Szeto@Sun.COM } else { 22369585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22379585STim.Szeto@Sun.COM } 22389585STim.Szeto@Sun.COM 22399585STim.Szeto@Sun.COM return (ret); 22409585STim.Szeto@Sun.COM } 22419585STim.Szeto@Sun.COM 22429585STim.Szeto@Sun.COM /* 22439585STim.Szeto@Sun.COM * getDiskProp 22449585STim.Szeto@Sun.COM * 22459585STim.Szeto@Sun.COM * Purpose: retrieve a given property from a logical unit resource of type disk 22469585STim.Szeto@Sun.COM * 22479585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 22489585STim.Szeto@Sun.COM * prop - property identifier 22499585STim.Szeto@Sun.COM * propVal - pointer to character to contain the retrieved property value 22509585STim.Szeto@Sun.COM * propLen - On input this is the length of propVal. On failure, it contains the 22519585STim.Szeto@Sun.COM * number of bytes required for propVal 22529585STim.Szeto@Sun.COM */ 22539585STim.Szeto@Sun.COM static int 22549585STim.Szeto@Sun.COM getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen) 22559585STim.Szeto@Sun.COM { 22569585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 22579585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 22589585STim.Szeto@Sun.COM size_t reqLen; 22599585STim.Szeto@Sun.COM 22609585STim.Szeto@Sun.COM switch (prop) { 22619585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 22629585STim.Szeto@Sun.COM if (diskLu->blkSizeValid == B_FALSE) { 22639585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22649585STim.Szeto@Sun.COM } 22659585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, "%llu", 22669585STim.Szeto@Sun.COM (u_longlong_t)diskLu->blkSize); 22679585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 22689585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22699585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22709585STim.Szeto@Sun.COM } 22719585STim.Szeto@Sun.COM break; 22729585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 22739585STim.Szeto@Sun.COM if (diskLu->luDataFileNameValid == B_FALSE) { 22749585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22759585STim.Szeto@Sun.COM } 22769585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luDataFileName, 22779585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 22789585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22799585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22809585STim.Szeto@Sun.COM } 22819585STim.Szeto@Sun.COM break; 22829585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 22839585STim.Szeto@Sun.COM if (diskLu->luMetaFileNameValid == B_FALSE) { 22849585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 22859585STim.Szeto@Sun.COM } 22869585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName, 22879585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 22889585STim.Szeto@Sun.COM *propLen = reqLen + 1; 22899585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 22909585STim.Szeto@Sun.COM } 22919585STim.Szeto@Sun.COM break; 229210113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 229310113SNattuvetty.Bhavyan@Sun.COM if (diskLu->luMgmtUrlValid == B_FALSE) { 229410113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_NO_PROP); 229510113SNattuvetty.Bhavyan@Sun.COM } 229610113SNattuvetty.Bhavyan@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl, 229710113SNattuvetty.Bhavyan@Sun.COM *propLen)) >= *propLen) { 229810113SNattuvetty.Bhavyan@Sun.COM *propLen = reqLen + 1; 229910113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_ARG); 230010113SNattuvetty.Bhavyan@Sun.COM } 230110113SNattuvetty.Bhavyan@Sun.COM break; 23029585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 23039585STim.Szeto@Sun.COM if (diskLu->luGuidValid == B_FALSE) { 23049585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23059585STim.Szeto@Sun.COM } 23069585STim.Szeto@Sun.COM reqLen = snprintf(propVal, *propLen, 23079585STim.Szeto@Sun.COM "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" 23089585STim.Szeto@Sun.COM "%02X%02X%02X%02X", 23099585STim.Szeto@Sun.COM diskLu->luGuid[0], diskLu->luGuid[1], 23109585STim.Szeto@Sun.COM diskLu->luGuid[2], diskLu->luGuid[3], 23119585STim.Szeto@Sun.COM diskLu->luGuid[4], diskLu->luGuid[5], 23129585STim.Szeto@Sun.COM diskLu->luGuid[6], diskLu->luGuid[7], 23139585STim.Szeto@Sun.COM diskLu->luGuid[8], diskLu->luGuid[9], 23149585STim.Szeto@Sun.COM diskLu->luGuid[10], diskLu->luGuid[11], 23159585STim.Szeto@Sun.COM diskLu->luGuid[12], diskLu->luGuid[13], 23169585STim.Szeto@Sun.COM diskLu->luGuid[14], diskLu->luGuid[15]); 23179585STim.Szeto@Sun.COM if (reqLen >= *propLen) { 23189585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23199585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23209585STim.Szeto@Sun.COM } 23219585STim.Szeto@Sun.COM break; 23229585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 23239585STim.Szeto@Sun.COM if (diskLu->serialNumValid == B_FALSE) { 23249585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23259585STim.Szeto@Sun.COM } 23269585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->serialNum, 23279585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23289585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23299585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23309585STim.Szeto@Sun.COM } 23319585STim.Szeto@Sun.COM break; 23329585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 23339585STim.Szeto@Sun.COM if (diskLu->luSizeValid == B_FALSE) { 23349585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23359585STim.Szeto@Sun.COM } 23369585STim.Szeto@Sun.COM (void) snprintf(propVal, *propLen, "%llu", 23379585STim.Szeto@Sun.COM (u_longlong_t)diskLu->luSize); 23389585STim.Szeto@Sun.COM break; 23399585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 23409585STim.Szeto@Sun.COM if (diskLu->luAliasValid == B_FALSE) { 23419585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23429585STim.Szeto@Sun.COM } 23439585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, diskLu->luAlias, 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 break; 23499585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 23509585STim.Szeto@Sun.COM if (diskLu->vidValid == B_FALSE) { 23519585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23529585STim.Szeto@Sun.COM } 23539585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->vid)) { 23549585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23559585STim.Szeto@Sun.COM } 23569585STim.Szeto@Sun.COM bcopy(diskLu->vid, propVal, sizeof (diskLu->vid)); 23579585STim.Szeto@Sun.COM propVal[sizeof (diskLu->vid)] = 0; 23589585STim.Szeto@Sun.COM break; 23599585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 23609585STim.Szeto@Sun.COM if (diskLu->pidValid == B_FALSE) { 23619585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23629585STim.Szeto@Sun.COM } 23639585STim.Szeto@Sun.COM if (*propLen <= sizeof (diskLu->pid)) { 23649585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23659585STim.Szeto@Sun.COM } 23669585STim.Szeto@Sun.COM bcopy(diskLu->pid, propVal, sizeof (diskLu->pid)); 23679585STim.Szeto@Sun.COM propVal[sizeof (diskLu->pid)] = 0; 23689585STim.Szeto@Sun.COM break; 23699585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 23709585STim.Szeto@Sun.COM if (diskLu->writeProtectEnableValid == B_FALSE) { 23719585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23729585STim.Szeto@Sun.COM } 23739585STim.Szeto@Sun.COM if (diskLu->writeProtectEnable) { 23749585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 23759585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23769585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23779585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23789585STim.Szeto@Sun.COM } 23799585STim.Szeto@Sun.COM } else { 23809585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 23819585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23829585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23839585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23849585STim.Szeto@Sun.COM } 23859585STim.Szeto@Sun.COM } 23869585STim.Szeto@Sun.COM break; 23879585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 23889585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisableValid == B_FALSE) { 23899585STim.Szeto@Sun.COM return (STMF_ERROR_NO_PROP); 23909585STim.Szeto@Sun.COM } 23919585STim.Szeto@Sun.COM if (diskLu->writebackCacheDisable) { 23929585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "true", 23939585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 23949585STim.Szeto@Sun.COM *propLen = reqLen + 1; 23959585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 23969585STim.Szeto@Sun.COM } 23979585STim.Szeto@Sun.COM } else { 23989585STim.Szeto@Sun.COM if ((reqLen = strlcpy(propVal, "false", 23999585STim.Szeto@Sun.COM *propLen)) >= *propLen) { 24009585STim.Szeto@Sun.COM *propLen = reqLen + 1; 24019585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24029585STim.Szeto@Sun.COM } 24039585STim.Szeto@Sun.COM } 24049585STim.Szeto@Sun.COM break; 24059585STim.Szeto@Sun.COM default: 24069585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 24079585STim.Szeto@Sun.COM break; 24089585STim.Szeto@Sun.COM } 24099585STim.Szeto@Sun.COM 24109585STim.Szeto@Sun.COM return (ret); 24119585STim.Szeto@Sun.COM } 24129585STim.Szeto@Sun.COM 24139585STim.Szeto@Sun.COM /* 24149585STim.Szeto@Sun.COM * setDiskProp 24159585STim.Szeto@Sun.COM * 24169585STim.Szeto@Sun.COM * Purpose: set properties for resource of type disk 24179585STim.Szeto@Sun.COM * 24189585STim.Szeto@Sun.COM * hdl - allocated luResourceImpl 24199585STim.Szeto@Sun.COM * resourceProp - valid resource identifier 24209585STim.Szeto@Sun.COM * propVal - valid resource value 24219585STim.Szeto@Sun.COM */ 24229585STim.Szeto@Sun.COM static int 24239585STim.Szeto@Sun.COM setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal) 24249585STim.Szeto@Sun.COM { 24259585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 24269585STim.Szeto@Sun.COM int i; 24279585STim.Szeto@Sun.COM diskResource *diskLu = hdl->resource; 24289585STim.Szeto@Sun.COM unsigned long long numericProp = 0; 24299585STim.Szeto@Sun.COM char guidProp[LU_ASCII_GUID_SIZE + 1]; 24309585STim.Szeto@Sun.COM char ouiProp[OUI_ASCII_SIZE + 1]; 24319585STim.Szeto@Sun.COM unsigned int oui[OUI_SIZE]; 24329585STim.Szeto@Sun.COM unsigned int guid[LU_GUID_SIZE]; 24339585STim.Szeto@Sun.COM int propSize; 24349585STim.Szeto@Sun.COM 24359585STim.Szeto@Sun.COM 24369585STim.Szeto@Sun.COM if (propVal == NULL) { 24379585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24389585STim.Szeto@Sun.COM } 24399585STim.Szeto@Sun.COM 24409585STim.Szeto@Sun.COM switch (resourceProp) { 24419585STim.Szeto@Sun.COM case STMF_LU_PROP_ALIAS: 24429585STim.Szeto@Sun.COM if (strlcpy(diskLu->luAlias, propVal, 24439585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) >= 24449585STim.Szeto@Sun.COM sizeof (diskLu->luAlias)) { 24459585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24469585STim.Szeto@Sun.COM } 24479585STim.Szeto@Sun.COM diskLu->luAliasValid = B_TRUE; 24489585STim.Szeto@Sun.COM break; 24499585STim.Szeto@Sun.COM case STMF_LU_PROP_BLOCK_SIZE: 24509585STim.Szeto@Sun.COM (void) sscanf(propVal, "%llu", &numericProp); 24519585STim.Szeto@Sun.COM if (numericProp > UINT16_MAX) { 24529585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24539585STim.Szeto@Sun.COM } 24549585STim.Szeto@Sun.COM diskLu->blkSize = numericProp; 24559585STim.Szeto@Sun.COM diskLu->blkSizeValid = B_TRUE; 24569585STim.Szeto@Sun.COM break; 24579585STim.Szeto@Sun.COM case STMF_LU_PROP_COMPANY_ID: 24589585STim.Szeto@Sun.COM if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >= 24599585STim.Szeto@Sun.COM sizeof (ouiProp)) { 24609585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24619585STim.Szeto@Sun.COM } 24629585STim.Szeto@Sun.COM if (checkHexUpper(ouiProp) != 0) { 24639585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24649585STim.Szeto@Sun.COM } 24659585STim.Szeto@Sun.COM (void) sscanf(ouiProp, "%2X%2X%2X", 24669585STim.Szeto@Sun.COM &oui[0], &oui[1], &oui[2]); 24679585STim.Szeto@Sun.COM 24689585STim.Szeto@Sun.COM diskLu->companyId = 0; 24699585STim.Szeto@Sun.COM diskLu->companyId += oui[0] << 16; 24709585STim.Szeto@Sun.COM diskLu->companyId += oui[1] << 8; 24719585STim.Szeto@Sun.COM diskLu->companyId += oui[2]; 24729585STim.Szeto@Sun.COM diskLu->companyIdValid = B_TRUE; 24739585STim.Szeto@Sun.COM break; 24749585STim.Szeto@Sun.COM case STMF_LU_PROP_GUID: 24759585STim.Szeto@Sun.COM if (strlen(propVal) != LU_ASCII_GUID_SIZE) { 24769585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 24779585STim.Szeto@Sun.COM } 24789585STim.Szeto@Sun.COM 24799585STim.Szeto@Sun.COM if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >= 24809585STim.Szeto@Sun.COM sizeof (guidProp)) { 24819585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24829585STim.Szeto@Sun.COM } 24839585STim.Szeto@Sun.COM 24849585STim.Szeto@Sun.COM if (checkHexUpper(guidProp) != 0) { 24859585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 24869585STim.Szeto@Sun.COM } 24879585STim.Szeto@Sun.COM 24889585STim.Szeto@Sun.COM (void) sscanf(guidProp, 24899585STim.Szeto@Sun.COM "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X", 24909585STim.Szeto@Sun.COM &guid[0], &guid[1], &guid[2], &guid[3], &guid[4], 24919585STim.Szeto@Sun.COM &guid[5], &guid[6], &guid[7], &guid[8], &guid[9], 24929585STim.Szeto@Sun.COM &guid[10], &guid[11], &guid[12], &guid[13], 24939585STim.Szeto@Sun.COM &guid[14], &guid[15]); 24949585STim.Szeto@Sun.COM for (i = 0; i < sizeof (diskLu->luGuid); i++) { 24959585STim.Szeto@Sun.COM diskLu->luGuid[i] = guid[i]; 24969585STim.Szeto@Sun.COM } 24979585STim.Szeto@Sun.COM diskLu->luGuidValid = B_TRUE; 24989585STim.Szeto@Sun.COM break; 24999585STim.Szeto@Sun.COM case STMF_LU_PROP_FILENAME: 25009585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luDataFileName, propVal, 25019585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName))) >= 25029585STim.Szeto@Sun.COM sizeof (diskLu->luDataFileName)) { 25039585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 25049585STim.Szeto@Sun.COM } 25059585STim.Szeto@Sun.COM diskLu->luDataFileNameValid = B_TRUE; 25069585STim.Szeto@Sun.COM break; 25079585STim.Szeto@Sun.COM case STMF_LU_PROP_META_FILENAME: 25089585STim.Szeto@Sun.COM if ((strlcpy(diskLu->luMetaFileName, propVal, 25099585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName))) >= 25109585STim.Szeto@Sun.COM sizeof (diskLu->luMetaFileName)) { 25119585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 25129585STim.Szeto@Sun.COM } 25139585STim.Szeto@Sun.COM diskLu->luMetaFileNameValid = B_TRUE; 25149585STim.Szeto@Sun.COM break; 251510113SNattuvetty.Bhavyan@Sun.COM case STMF_LU_PROP_MGMT_URL: 251610113SNattuvetty.Bhavyan@Sun.COM if ((strlcpy(diskLu->luMgmtUrl, propVal, 251710113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl))) >= 251810113SNattuvetty.Bhavyan@Sun.COM sizeof (diskLu->luMgmtUrl)) { 251910113SNattuvetty.Bhavyan@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 252010113SNattuvetty.Bhavyan@Sun.COM } 252110113SNattuvetty.Bhavyan@Sun.COM diskLu->luMgmtUrlValid = B_TRUE; 252210113SNattuvetty.Bhavyan@Sun.COM break; 25239585STim.Szeto@Sun.COM case STMF_LU_PROP_PID: 25249585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 25259585STim.Szeto@Sun.COM sizeof (diskLu->pid)) { 25269585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 25279585STim.Szeto@Sun.COM } 25289585STim.Szeto@Sun.COM (void) strncpy(diskLu->pid, propVal, propSize); 25299585STim.Szeto@Sun.COM diskLu->pidValid = B_TRUE; 25309585STim.Szeto@Sun.COM break; 25319585STim.Szeto@Sun.COM case STMF_LU_PROP_SERIAL_NUM: 25329585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 25339585STim.Szeto@Sun.COM (sizeof (diskLu->serialNum) - 1)) { 25349585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 25359585STim.Szeto@Sun.COM } 25369585STim.Szeto@Sun.COM (void) strncpy(diskLu->serialNum, propVal, propSize); 25379585STim.Szeto@Sun.COM diskLu->serialNumValid = B_TRUE; 25389585STim.Szeto@Sun.COM break; 25399585STim.Szeto@Sun.COM case STMF_LU_PROP_SIZE: 25409585STim.Szeto@Sun.COM if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) { 25419585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25429585STim.Szeto@Sun.COM } 25439585STim.Szeto@Sun.COM diskLu->luSizeValid = B_TRUE; 25449585STim.Szeto@Sun.COM break; 25459585STim.Szeto@Sun.COM case STMF_LU_PROP_VID: 25469585STim.Szeto@Sun.COM if ((propSize = strlen(propVal)) > 25479585STim.Szeto@Sun.COM sizeof (diskLu->vid)) { 25489585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_PROPSIZE); 25499585STim.Szeto@Sun.COM } 25509585STim.Szeto@Sun.COM (void) strncpy(diskLu->vid, propVal, propSize); 25519585STim.Szeto@Sun.COM diskLu->vidValid = B_TRUE; 25529585STim.Szeto@Sun.COM break; 25539585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_PROTECT: 25549585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 25559585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_TRUE; 25569585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 25579585STim.Szeto@Sun.COM diskLu->writeProtectEnable = B_FALSE; 25589585STim.Szeto@Sun.COM } else { 25599585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25609585STim.Szeto@Sun.COM } 25619585STim.Szeto@Sun.COM diskLu->writeProtectEnableValid = B_TRUE; 25629585STim.Szeto@Sun.COM break; 25639585STim.Szeto@Sun.COM case STMF_LU_PROP_WRITE_CACHE_DISABLE: 25649585STim.Szeto@Sun.COM if (strcasecmp(propVal, "TRUE") == 0) { 25659585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_TRUE; 25669585STim.Szeto@Sun.COM } else if (strcasecmp(propVal, "FALSE") == 0) { 25679585STim.Szeto@Sun.COM diskLu->writebackCacheDisable = B_FALSE; 25689585STim.Szeto@Sun.COM } else { 25699585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 25709585STim.Szeto@Sun.COM } 25719585STim.Szeto@Sun.COM diskLu->writebackCacheDisableValid = B_TRUE; 25729585STim.Szeto@Sun.COM break; 25739585STim.Szeto@Sun.COM default: 25749585STim.Szeto@Sun.COM ret = STMF_ERROR_NO_PROP; 25759585STim.Szeto@Sun.COM break; 25769585STim.Szeto@Sun.COM } 25779585STim.Szeto@Sun.COM return (ret); 25789585STim.Szeto@Sun.COM } 25799585STim.Szeto@Sun.COM 25809585STim.Szeto@Sun.COM static int 25819585STim.Szeto@Sun.COM checkHexUpper(char *buf) 25829585STim.Szeto@Sun.COM { 25839585STim.Szeto@Sun.COM int i; 25849585STim.Szeto@Sun.COM 25859585STim.Szeto@Sun.COM for (i = 0; i < strlen(buf); i++) { 25869585STim.Szeto@Sun.COM if (isxdigit(buf[i])) { 25879585STim.Szeto@Sun.COM buf[i] = toupper(buf[i]); 25889585STim.Szeto@Sun.COM continue; 25899585STim.Szeto@Sun.COM } 25909585STim.Szeto@Sun.COM return (-1); 25919585STim.Szeto@Sun.COM } 25929585STim.Szeto@Sun.COM 25939585STim.Szeto@Sun.COM return (0); 25949585STim.Szeto@Sun.COM } 25959585STim.Szeto@Sun.COM 25969585STim.Szeto@Sun.COM /* 25979585STim.Szeto@Sun.COM * Given a numeric suffix, convert the value into a number of bits that the 25989585STim.Szeto@Sun.COM * resulting value must be shifted. 25999585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 26009585STim.Szeto@Sun.COM */ 26019585STim.Szeto@Sun.COM static int 26029585STim.Szeto@Sun.COM strToShift(const char *buf) 26039585STim.Szeto@Sun.COM { 26049585STim.Szeto@Sun.COM const char *ends = "BKMGTPE"; 26059585STim.Szeto@Sun.COM int i; 26069585STim.Szeto@Sun.COM 26079585STim.Szeto@Sun.COM if (buf[0] == '\0') 26089585STim.Szeto@Sun.COM return (0); 26099585STim.Szeto@Sun.COM 26109585STim.Szeto@Sun.COM for (i = 0; i < strlen(ends); i++) { 26119585STim.Szeto@Sun.COM if (toupper(buf[0]) == ends[i]) 26129585STim.Szeto@Sun.COM return (10*i); 26139585STim.Szeto@Sun.COM } 26149585STim.Szeto@Sun.COM 26159585STim.Szeto@Sun.COM return (-1); 26169585STim.Szeto@Sun.COM } 26179585STim.Szeto@Sun.COM 26189585STim.Szeto@Sun.COM int 26199585STim.Szeto@Sun.COM stmfFreeLuResource(luResource hdl) 26209585STim.Szeto@Sun.COM { 26219585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 26229585STim.Szeto@Sun.COM if (hdl == NULL) { 26239585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 26249585STim.Szeto@Sun.COM } 26259585STim.Szeto@Sun.COM 26269585STim.Szeto@Sun.COM luResourceImpl *hdlImpl = hdl; 26279585STim.Szeto@Sun.COM free(hdlImpl->resource); 26289585STim.Szeto@Sun.COM free(hdlImpl); 26299585STim.Szeto@Sun.COM return (ret); 26309585STim.Szeto@Sun.COM } 26319585STim.Szeto@Sun.COM 26329585STim.Szeto@Sun.COM /* 26339585STim.Szeto@Sun.COM * Convert a string of the form '100G' into a real number. Used when setting 26349585STim.Szeto@Sun.COM * the size of a logical unit. 26359585STim.Szeto@Sun.COM * Code lifted from libzfs_util.c 26369585STim.Szeto@Sun.COM */ 26379585STim.Szeto@Sun.COM static int 26389585STim.Szeto@Sun.COM niceStrToNum(const char *value, uint64_t *num) 26399585STim.Szeto@Sun.COM { 26409585STim.Szeto@Sun.COM char *end; 26419585STim.Szeto@Sun.COM int shift; 26429585STim.Szeto@Sun.COM 26439585STim.Szeto@Sun.COM *num = 0; 26449585STim.Szeto@Sun.COM 26459585STim.Szeto@Sun.COM /* Check to see if this looks like a number. */ 26469585STim.Szeto@Sun.COM if ((value[0] < '0' || value[0] > '9') && value[0] != '.') { 26479585STim.Szeto@Sun.COM return (-1); 26489585STim.Szeto@Sun.COM } 26499585STim.Szeto@Sun.COM 26509585STim.Szeto@Sun.COM /* Rely on stroull() to process the numeric portion. */ 26519585STim.Szeto@Sun.COM errno = 0; 26529585STim.Szeto@Sun.COM *num = strtoull(value, &end, 10); 26539585STim.Szeto@Sun.COM 26549585STim.Szeto@Sun.COM /* 26559585STim.Szeto@Sun.COM * Check for ERANGE, which indicates that the value is too large to fit 26569585STim.Szeto@Sun.COM * in a 64-bit value. 26579585STim.Szeto@Sun.COM */ 26589585STim.Szeto@Sun.COM if (errno == ERANGE) { 26599585STim.Szeto@Sun.COM return (-1); 26609585STim.Szeto@Sun.COM } 26619585STim.Szeto@Sun.COM 26629585STim.Szeto@Sun.COM /* 26639585STim.Szeto@Sun.COM * If we have a decimal value, then do the computation with floating 26649585STim.Szeto@Sun.COM * point arithmetic. Otherwise, use standard arithmetic. 26659585STim.Szeto@Sun.COM */ 26669585STim.Szeto@Sun.COM if (*end == '.') { 26679585STim.Szeto@Sun.COM double fval = strtod(value, &end); 26689585STim.Szeto@Sun.COM 26699585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 26709585STim.Szeto@Sun.COM return (-1); 26719585STim.Szeto@Sun.COM } 26729585STim.Szeto@Sun.COM 26739585STim.Szeto@Sun.COM fval *= pow(2, shift); 26749585STim.Szeto@Sun.COM 26759585STim.Szeto@Sun.COM if (fval > UINT64_MAX) { 26769585STim.Szeto@Sun.COM return (-1); 26779585STim.Szeto@Sun.COM } 26789585STim.Szeto@Sun.COM 26799585STim.Szeto@Sun.COM *num = (uint64_t)fval; 26809585STim.Szeto@Sun.COM } else { 26819585STim.Szeto@Sun.COM if ((shift = strToShift(end)) == -1) { 26829585STim.Szeto@Sun.COM return (-1); 26839585STim.Szeto@Sun.COM } 26849585STim.Szeto@Sun.COM 26859585STim.Szeto@Sun.COM /* Check for overflow */ 26869585STim.Szeto@Sun.COM if (shift >= 64 || (*num << shift) >> shift != *num) { 26879585STim.Szeto@Sun.COM return (-1); 26889585STim.Szeto@Sun.COM } 26899585STim.Szeto@Sun.COM 26909585STim.Szeto@Sun.COM *num <<= shift; 26919585STim.Szeto@Sun.COM } 26929585STim.Szeto@Sun.COM 26939585STim.Szeto@Sun.COM return (0); 26949585STim.Szeto@Sun.COM } 26959585STim.Szeto@Sun.COM 26969585STim.Szeto@Sun.COM /* 26977836SJohn.Forte@Sun.COM * stmfCreateTargetGroup 26987836SJohn.Forte@Sun.COM * 26997836SJohn.Forte@Sun.COM * Purpose: Create a local port group 27007836SJohn.Forte@Sun.COM * 27017836SJohn.Forte@Sun.COM * targetGroupName - name of local port group to create 27027836SJohn.Forte@Sun.COM */ 27037836SJohn.Forte@Sun.COM int 27047836SJohn.Forte@Sun.COM stmfCreateTargetGroup(stmfGroupName *targetGroupName) 27057836SJohn.Forte@Sun.COM { 27067836SJohn.Forte@Sun.COM int ret; 27077836SJohn.Forte@Sun.COM int fd; 27087836SJohn.Forte@Sun.COM 27097836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 27107836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 27117836SJohn.Forte@Sun.COM == sizeof (stmfGroupName))) { 27127836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 27137836SJohn.Forte@Sun.COM } 27147836SJohn.Forte@Sun.COM 27157836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 27167836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 27177836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 27187836SJohn.Forte@Sun.COM } 27197836SJohn.Forte@Sun.COM 27207836SJohn.Forte@Sun.COM /* call init */ 27217836SJohn.Forte@Sun.COM ret = initializeConfig(); 27227836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 27237836SJohn.Forte@Sun.COM return (ret); 27247836SJohn.Forte@Sun.COM } 27257836SJohn.Forte@Sun.COM 27267836SJohn.Forte@Sun.COM /* 27277836SJohn.Forte@Sun.COM * Open control node for stmf 27287836SJohn.Forte@Sun.COM */ 27297836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 27307836SJohn.Forte@Sun.COM return (ret); 27317836SJohn.Forte@Sun.COM 27327836SJohn.Forte@Sun.COM /* 27337836SJohn.Forte@Sun.COM * Add the group to the driver 27347836SJohn.Forte@Sun.COM */ 27357836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 27367836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 27377836SJohn.Forte@Sun.COM goto done; 27387836SJohn.Forte@Sun.COM } 27397836SJohn.Forte@Sun.COM 27409585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 27419585STim.Szeto@Sun.COM goto done; 27429585STim.Szeto@Sun.COM } 27439585STim.Szeto@Sun.COM 27447836SJohn.Forte@Sun.COM /* 27457836SJohn.Forte@Sun.COM * If the add to the driver was successful, add it to the persistent 27467836SJohn.Forte@Sun.COM * store. 27477836SJohn.Forte@Sun.COM */ 27487836SJohn.Forte@Sun.COM ret = psCreateTargetGroup((char *)targetGroupName); 27497836SJohn.Forte@Sun.COM switch (ret) { 27507836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 27517836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 27527836SJohn.Forte@Sun.COM break; 27537836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 27547836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 27557836SJohn.Forte@Sun.COM break; 27567836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 27577836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 27587836SJohn.Forte@Sun.COM break; 27597836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 27607836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 27617836SJohn.Forte@Sun.COM break; 27627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 27637836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 27647836SJohn.Forte@Sun.COM break; 27657836SJohn.Forte@Sun.COM default: 27667836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 27677836SJohn.Forte@Sun.COM "stmfCreateTargetGroup:psCreateTargetGroup" 27687836SJohn.Forte@Sun.COM ":error(%d)", ret); 27697836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 27707836SJohn.Forte@Sun.COM break; 27717836SJohn.Forte@Sun.COM } 27727836SJohn.Forte@Sun.COM 27737836SJohn.Forte@Sun.COM done: 27747836SJohn.Forte@Sun.COM (void) close(fd); 27757836SJohn.Forte@Sun.COM return (ret); 27767836SJohn.Forte@Sun.COM } 27777836SJohn.Forte@Sun.COM 27787836SJohn.Forte@Sun.COM /* 27797836SJohn.Forte@Sun.COM * stmfDeleteHostGroup 27807836SJohn.Forte@Sun.COM * 27817836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 27827836SJohn.Forte@Sun.COM * 27837836SJohn.Forte@Sun.COM * hostGroupName - group to delete 27847836SJohn.Forte@Sun.COM */ 27857836SJohn.Forte@Sun.COM int 27867836SJohn.Forte@Sun.COM stmfDeleteHostGroup(stmfGroupName *hostGroupName) 27877836SJohn.Forte@Sun.COM { 27887836SJohn.Forte@Sun.COM int ret; 27897836SJohn.Forte@Sun.COM int fd; 27907836SJohn.Forte@Sun.COM 27917836SJohn.Forte@Sun.COM if (hostGroupName == NULL) { 27927836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 27937836SJohn.Forte@Sun.COM } 27947836SJohn.Forte@Sun.COM 27957836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 27967836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 27977836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 27987836SJohn.Forte@Sun.COM } 27997836SJohn.Forte@Sun.COM 28007836SJohn.Forte@Sun.COM /* call init */ 28017836SJohn.Forte@Sun.COM ret = initializeConfig(); 28027836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 28037836SJohn.Forte@Sun.COM return (ret); 28047836SJohn.Forte@Sun.COM } 28057836SJohn.Forte@Sun.COM 28067836SJohn.Forte@Sun.COM /* 28077836SJohn.Forte@Sun.COM * Open control node for stmf 28087836SJohn.Forte@Sun.COM */ 28097836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 28107836SJohn.Forte@Sun.COM return (ret); 28117836SJohn.Forte@Sun.COM 28127836SJohn.Forte@Sun.COM /* 28137836SJohn.Forte@Sun.COM * Remove the group from the driver 28147836SJohn.Forte@Sun.COM */ 28157836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP, 28167836SJohn.Forte@Sun.COM hostGroupName)) != STMF_STATUS_SUCCESS) { 28177836SJohn.Forte@Sun.COM goto done; 28187836SJohn.Forte@Sun.COM } 28197836SJohn.Forte@Sun.COM 28209585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 28219585STim.Szeto@Sun.COM goto done; 28229585STim.Szeto@Sun.COM } 28239585STim.Szeto@Sun.COM 28247836SJohn.Forte@Sun.COM /* 28257836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 28267836SJohn.Forte@Sun.COM * persistent store. 28277836SJohn.Forte@Sun.COM */ 28287836SJohn.Forte@Sun.COM ret = psDeleteHostGroup((char *)hostGroupName); 28297836SJohn.Forte@Sun.COM switch (ret) { 28307836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 28317836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 28327836SJohn.Forte@Sun.COM break; 28337836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 28347836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 28357836SJohn.Forte@Sun.COM break; 28367836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 28377836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 28387836SJohn.Forte@Sun.COM break; 28397836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 28407836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 28417836SJohn.Forte@Sun.COM break; 28427836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 28437836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 28447836SJohn.Forte@Sun.COM break; 28457836SJohn.Forte@Sun.COM default: 28467836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 28477836SJohn.Forte@Sun.COM "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)", 28487836SJohn.Forte@Sun.COM ret); 28497836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 28507836SJohn.Forte@Sun.COM break; 28517836SJohn.Forte@Sun.COM } 28527836SJohn.Forte@Sun.COM 28537836SJohn.Forte@Sun.COM done: 28547836SJohn.Forte@Sun.COM (void) close(fd); 28557836SJohn.Forte@Sun.COM return (ret); 28567836SJohn.Forte@Sun.COM } 28577836SJohn.Forte@Sun.COM 28587836SJohn.Forte@Sun.COM /* 28597836SJohn.Forte@Sun.COM * stmfDeleteTargetGroup 28607836SJohn.Forte@Sun.COM * 28617836SJohn.Forte@Sun.COM * Purpose: Delete an initiator or local port group 28627836SJohn.Forte@Sun.COM * 28637836SJohn.Forte@Sun.COM * targetGroupName - group to delete 28647836SJohn.Forte@Sun.COM */ 28657836SJohn.Forte@Sun.COM int 28667836SJohn.Forte@Sun.COM stmfDeleteTargetGroup(stmfGroupName *targetGroupName) 28677836SJohn.Forte@Sun.COM { 28687836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 28697836SJohn.Forte@Sun.COM int fd; 28707836SJohn.Forte@Sun.COM 28717836SJohn.Forte@Sun.COM if (targetGroupName == NULL) { 28727836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 28737836SJohn.Forte@Sun.COM } 28747836SJohn.Forte@Sun.COM 28757836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 28767836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 28777836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 28787836SJohn.Forte@Sun.COM } 28797836SJohn.Forte@Sun.COM 28807836SJohn.Forte@Sun.COM /* call init */ 28817836SJohn.Forte@Sun.COM ret = initializeConfig(); 28827836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 28837836SJohn.Forte@Sun.COM return (ret); 28847836SJohn.Forte@Sun.COM } 28857836SJohn.Forte@Sun.COM 28867836SJohn.Forte@Sun.COM /* 28877836SJohn.Forte@Sun.COM * Open control node for stmf 28887836SJohn.Forte@Sun.COM */ 28897836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 28907836SJohn.Forte@Sun.COM return (ret); 28917836SJohn.Forte@Sun.COM 28927836SJohn.Forte@Sun.COM /* 28937836SJohn.Forte@Sun.COM * Remove the group from the driver 28947836SJohn.Forte@Sun.COM */ 28957836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP, 28967836SJohn.Forte@Sun.COM targetGroupName)) != STMF_STATUS_SUCCESS) { 28977836SJohn.Forte@Sun.COM goto done; 28987836SJohn.Forte@Sun.COM } 28997836SJohn.Forte@Sun.COM 29009585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 29019585STim.Szeto@Sun.COM goto done; 29029585STim.Szeto@Sun.COM } 29039585STim.Szeto@Sun.COM 29047836SJohn.Forte@Sun.COM /* 29057836SJohn.Forte@Sun.COM * If the remove from the driver was successful, remove it from the 29067836SJohn.Forte@Sun.COM * persistent store. 29077836SJohn.Forte@Sun.COM */ 29087836SJohn.Forte@Sun.COM ret = psDeleteTargetGroup((char *)targetGroupName); 29097836SJohn.Forte@Sun.COM switch (ret) { 29107836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 29117836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 29127836SJohn.Forte@Sun.COM break; 29137836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 29147836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 29157836SJohn.Forte@Sun.COM break; 29167836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 29177836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 29187836SJohn.Forte@Sun.COM break; 29197836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 29207836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 29217836SJohn.Forte@Sun.COM break; 29227836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 29237836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 29247836SJohn.Forte@Sun.COM break; 29257836SJohn.Forte@Sun.COM default: 29267836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 29277836SJohn.Forte@Sun.COM "stmfDeleteTargetGroup:psDeleteTargetGroup" 29287836SJohn.Forte@Sun.COM ":error(%d)", ret); 29297836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 29307836SJohn.Forte@Sun.COM break; 29317836SJohn.Forte@Sun.COM } 29327836SJohn.Forte@Sun.COM 29337836SJohn.Forte@Sun.COM done: 29347836SJohn.Forte@Sun.COM (void) close(fd); 29357836SJohn.Forte@Sun.COM return (ret); 29367836SJohn.Forte@Sun.COM } 29377836SJohn.Forte@Sun.COM 29387836SJohn.Forte@Sun.COM /* 29397836SJohn.Forte@Sun.COM * stmfDevidFromIscsiName 29407836SJohn.Forte@Sun.COM * 29417836SJohn.Forte@Sun.COM * Purpose: convert an iSCSI name to an stmf devid 29427836SJohn.Forte@Sun.COM * 29437836SJohn.Forte@Sun.COM * iscsiName - unicode nul terminated utf-8 encoded iSCSI name 29447836SJohn.Forte@Sun.COM * devid - on success, contains the converted iscsi name 29457836SJohn.Forte@Sun.COM */ 29467836SJohn.Forte@Sun.COM int 29477836SJohn.Forte@Sun.COM stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid) 29487836SJohn.Forte@Sun.COM { 29497836SJohn.Forte@Sun.COM if (devid == NULL || iscsiName == NULL) 29507836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29517836SJohn.Forte@Sun.COM 29527836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 29537836SJohn.Forte@Sun.COM 29547836SJohn.Forte@Sun.COM /* Validate size of target */ 29557836SJohn.Forte@Sun.COM if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME || 29567836SJohn.Forte@Sun.COM devid->identLength < strlen(EUI) || 29577836SJohn.Forte@Sun.COM devid->identLength < strlen(IQN)) { 29587836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29597836SJohn.Forte@Sun.COM } 29607836SJohn.Forte@Sun.COM 29617836SJohn.Forte@Sun.COM if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) && 29627836SJohn.Forte@Sun.COM strncmp(iscsiName, IQN, strlen(IQN)) != 0) { 29637836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29647836SJohn.Forte@Sun.COM } 29657836SJohn.Forte@Sun.COM 29667836SJohn.Forte@Sun.COM /* copy UTF-8 bytes to ident */ 29677836SJohn.Forte@Sun.COM bcopy(iscsiName, devid->ident, devid->identLength); 29687836SJohn.Forte@Sun.COM 29697836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 29707836SJohn.Forte@Sun.COM } 29717836SJohn.Forte@Sun.COM 29727836SJohn.Forte@Sun.COM /* 29737836SJohn.Forte@Sun.COM * stmfDevidFromWwn 29747836SJohn.Forte@Sun.COM * 29757836SJohn.Forte@Sun.COM * Purpose: convert a WWN to an stmf devid 29767836SJohn.Forte@Sun.COM * 29777836SJohn.Forte@Sun.COM * wwn - 8-byte wwn identifier 29787836SJohn.Forte@Sun.COM * devid - on success, contains the converted wwn 29797836SJohn.Forte@Sun.COM */ 29807836SJohn.Forte@Sun.COM int 29817836SJohn.Forte@Sun.COM stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid) 29827836SJohn.Forte@Sun.COM { 29837836SJohn.Forte@Sun.COM if (wwn == NULL || devid == NULL) 29847836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 29857836SJohn.Forte@Sun.COM 29867836SJohn.Forte@Sun.COM bzero(devid, sizeof (stmfDevid)); 29877836SJohn.Forte@Sun.COM 29887836SJohn.Forte@Sun.COM /* Copy eui prefix */ 29897836SJohn.Forte@Sun.COM (void) bcopy(WWN, devid->ident, strlen(WWN)); 29907836SJohn.Forte@Sun.COM 29917836SJohn.Forte@Sun.COM /* Convert to ASCII uppercase hexadecimal string */ 29927836SJohn.Forte@Sun.COM (void) snprintf((char *)&devid->ident[strlen(WWN)], 29937836SJohn.Forte@Sun.COM sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X", 29947836SJohn.Forte@Sun.COM wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]); 29957836SJohn.Forte@Sun.COM 29967836SJohn.Forte@Sun.COM devid->identLength = strlen((char *)devid->ident); 29977836SJohn.Forte@Sun.COM 29987836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 29997836SJohn.Forte@Sun.COM } 30007836SJohn.Forte@Sun.COM 30017836SJohn.Forte@Sun.COM /* 30027836SJohn.Forte@Sun.COM * stmfFreeMemory 30037836SJohn.Forte@Sun.COM * 30047836SJohn.Forte@Sun.COM * Purpose: Free memory allocated by this library 30057836SJohn.Forte@Sun.COM * 30067836SJohn.Forte@Sun.COM * memory - previously allocated pointer of memory managed by library 30077836SJohn.Forte@Sun.COM */ 30087836SJohn.Forte@Sun.COM void 30097836SJohn.Forte@Sun.COM stmfFreeMemory(void *memory) 30107836SJohn.Forte@Sun.COM { 30117836SJohn.Forte@Sun.COM free(memory); 30127836SJohn.Forte@Sun.COM } 30137836SJohn.Forte@Sun.COM 30147836SJohn.Forte@Sun.COM /* 30159585STim.Szeto@Sun.COM * get host group, target group list from stmf 30167836SJohn.Forte@Sun.COM * 30179585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 30187836SJohn.Forte@Sun.COM */ 30199585STim.Szeto@Sun.COM static int 30209585STim.Szeto@Sun.COM groupListIoctl(stmfGroupList **groupList, int groupType) 30219585STim.Szeto@Sun.COM { 30229585STim.Szeto@Sun.COM int ret; 30239585STim.Szeto@Sun.COM int fd; 30249585STim.Szeto@Sun.COM int ioctlRet; 30259585STim.Szeto@Sun.COM int i; 30269585STim.Szeto@Sun.COM int cmd; 30279585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 30289585STim.Szeto@Sun.COM /* framework group list */ 30299585STim.Szeto@Sun.COM stmf_group_name_t *iGroupList = NULL; 30309585STim.Szeto@Sun.COM uint32_t groupListSize; 30319585STim.Szeto@Sun.COM 30329585STim.Szeto@Sun.COM if (groupList == NULL) { 30339585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30349585STim.Szeto@Sun.COM } 30359585STim.Szeto@Sun.COM 30369585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 30379585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_LIST; 30389585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 30399585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_LIST; 30409585STim.Szeto@Sun.COM } else { 30419585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 30429585STim.Szeto@Sun.COM } 30439585STim.Szeto@Sun.COM 30449585STim.Szeto@Sun.COM /* call init */ 30459585STim.Szeto@Sun.COM ret = initializeConfig(); 30469585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 30479585STim.Szeto@Sun.COM return (ret); 30489585STim.Szeto@Sun.COM } 30499585STim.Szeto@Sun.COM 30509585STim.Szeto@Sun.COM /* 30519585STim.Szeto@Sun.COM * Open control node for stmf 30529585STim.Szeto@Sun.COM */ 30539585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 30549585STim.Szeto@Sun.COM return (ret); 30559585STim.Szeto@Sun.COM 30569585STim.Szeto@Sun.COM /* 30579585STim.Szeto@Sun.COM * Allocate ioctl input buffer 30589585STim.Szeto@Sun.COM */ 30599585STim.Szeto@Sun.COM groupListSize = ALLOC_GROUP; 30609585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_group_name_t)); 30619585STim.Szeto@Sun.COM iGroupList = (stmf_group_name_t *)calloc(1, groupListSize); 30629585STim.Szeto@Sun.COM if (iGroupList == NULL) { 30639585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 30649585STim.Szeto@Sun.COM goto done; 30659585STim.Szeto@Sun.COM } 30669585STim.Szeto@Sun.COM 30679585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 30689585STim.Szeto@Sun.COM /* 30699585STim.Szeto@Sun.COM * Issue ioctl to get the group list 30709585STim.Szeto@Sun.COM */ 30719585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 30729585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 30739585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 30749585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 30759585STim.Szeto@Sun.COM if (ioctlRet != 0) { 30769585STim.Szeto@Sun.COM switch (errno) { 30779585STim.Szeto@Sun.COM case EBUSY: 30789585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 30799585STim.Szeto@Sun.COM break; 30809585STim.Szeto@Sun.COM case EPERM: 30819585STim.Szeto@Sun.COM case EACCES: 30829585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 30839585STim.Szeto@Sun.COM break; 30849585STim.Szeto@Sun.COM default: 30859585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 30869585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 30879585STim.Szeto@Sun.COM errno); 30889585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 30899585STim.Szeto@Sun.COM break; 30909585STim.Szeto@Sun.COM } 30919585STim.Szeto@Sun.COM goto done; 30929585STim.Szeto@Sun.COM } 30939585STim.Szeto@Sun.COM /* 30949585STim.Szeto@Sun.COM * Check whether input buffer was large enough 30959585STim.Szeto@Sun.COM */ 30969585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) { 30979585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 30989585STim.Szeto@Sun.COM sizeof (stmf_group_name_t); 30999585STim.Szeto@Sun.COM iGroupList = realloc(iGroupList, groupListSize); 31009585STim.Szeto@Sun.COM if (iGroupList == NULL) { 31019585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 31029585STim.Szeto@Sun.COM goto done; 31039585STim.Szeto@Sun.COM } 31049585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 31059585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList; 31069585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 31079585STim.Szeto@Sun.COM if (ioctlRet != 0) { 31089585STim.Szeto@Sun.COM switch (errno) { 31099585STim.Szeto@Sun.COM case EBUSY: 31109585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 31119585STim.Szeto@Sun.COM break; 31129585STim.Szeto@Sun.COM case EPERM: 31139585STim.Szeto@Sun.COM case EACCES: 31149585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 31159585STim.Szeto@Sun.COM break; 31169585STim.Szeto@Sun.COM default: 31179585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 31189585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 31199585STim.Szeto@Sun.COM errno); 31209585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 31219585STim.Szeto@Sun.COM break; 31229585STim.Szeto@Sun.COM } 31239585STim.Szeto@Sun.COM goto done; 31249585STim.Szeto@Sun.COM } 31259585STim.Szeto@Sun.COM } 31269585STim.Szeto@Sun.COM 31279585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 312810236SSrivijitha.Dugganapalli@Sun.COM *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) + 312910236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries); 31309585STim.Szeto@Sun.COM if (*groupList == NULL) { 31319585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 31329585STim.Szeto@Sun.COM goto done; 31339585STim.Szeto@Sun.COM } 31349585STim.Szeto@Sun.COM (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries; 31359585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 313610113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupList[i].name, (*groupList)->name[i], 31379585STim.Szeto@Sun.COM sizeof (stmfGroupName)); 31389585STim.Szeto@Sun.COM } 31399585STim.Szeto@Sun.COM 31409585STim.Szeto@Sun.COM done: 31419585STim.Szeto@Sun.COM free(iGroupList); 31429585STim.Szeto@Sun.COM (void) close(fd); 31439585STim.Szeto@Sun.COM return (ret); 31449585STim.Szeto@Sun.COM } 31459585STim.Szeto@Sun.COM 31469585STim.Szeto@Sun.COM /* 31479585STim.Szeto@Sun.COM * get host group members, target group members from stmf 31489585STim.Szeto@Sun.COM * 31499585STim.Szeto@Sun.COM * groupProps - allocated on success 31509585STim.Szeto@Sun.COM * 31519585STim.Szeto@Sun.COM * groupType - HOST_GROUP, TARGET_GROUP 31529585STim.Szeto@Sun.COM */ 31539585STim.Szeto@Sun.COM static int 31549585STim.Szeto@Sun.COM groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps, 31559585STim.Szeto@Sun.COM int groupType) 31567836SJohn.Forte@Sun.COM { 31577836SJohn.Forte@Sun.COM int ret; 31589585STim.Szeto@Sun.COM int fd; 31599585STim.Szeto@Sun.COM int ioctlRet; 31609585STim.Szeto@Sun.COM int i; 31619585STim.Szeto@Sun.COM int cmd; 31629585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 31639585STim.Szeto@Sun.COM /* framework group list */ 31649585STim.Szeto@Sun.COM stmf_group_name_t iGroupName; 31659585STim.Szeto@Sun.COM stmf_ge_ident_t *iGroupMembers; 31669585STim.Szeto@Sun.COM uint32_t groupListSize; 31679585STim.Szeto@Sun.COM 31689585STim.Szeto@Sun.COM if (groupName == NULL) { 31699585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 31709585STim.Szeto@Sun.COM } 31719585STim.Szeto@Sun.COM 31729585STim.Szeto@Sun.COM if (groupType == HOST_GROUP) { 31739585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_HG_ENTRIES; 31749585STim.Szeto@Sun.COM } else if (groupType == TARGET_GROUP) { 31759585STim.Szeto@Sun.COM cmd = STMF_IOCTL_GET_TG_ENTRIES; 31769585STim.Szeto@Sun.COM } else { 31777836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 31787836SJohn.Forte@Sun.COM } 31797836SJohn.Forte@Sun.COM 31809585STim.Szeto@Sun.COM /* call init */ 31819585STim.Szeto@Sun.COM ret = initializeConfig(); 31829585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 31839585STim.Szeto@Sun.COM return (ret); 31849585STim.Szeto@Sun.COM } 31859585STim.Szeto@Sun.COM 31869585STim.Szeto@Sun.COM /* 31879585STim.Szeto@Sun.COM * Open control node for stmf 31889585STim.Szeto@Sun.COM */ 31899585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 31909585STim.Szeto@Sun.COM return (ret); 31919585STim.Szeto@Sun.COM 31929585STim.Szeto@Sun.COM bzero(&iGroupName, sizeof (iGroupName)); 31939585STim.Szeto@Sun.COM 31949585STim.Szeto@Sun.COM bcopy(groupName, &iGroupName.name, strlen((char *)groupName)); 31959585STim.Szeto@Sun.COM 31969585STim.Szeto@Sun.COM iGroupName.name_size = strlen((char *)groupName); 31979585STim.Szeto@Sun.COM 31989585STim.Szeto@Sun.COM /* 31999585STim.Szeto@Sun.COM * Allocate ioctl input buffer 32009585STim.Szeto@Sun.COM */ 32019585STim.Szeto@Sun.COM groupListSize = ALLOC_GRP_MEMBER; 32029585STim.Szeto@Sun.COM groupListSize = groupListSize * (sizeof (stmf_ge_ident_t)); 32039585STim.Szeto@Sun.COM iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize); 32049585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 32059585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32069585STim.Szeto@Sun.COM goto done; 32079585STim.Szeto@Sun.COM } 32089585STim.Szeto@Sun.COM 32099585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 32109585STim.Szeto@Sun.COM /* 32119585STim.Szeto@Sun.COM * Issue ioctl to get the group list 32129585STim.Szeto@Sun.COM */ 32139585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 32149585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 32159585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 32169585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 32179585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 32189585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 32199585STim.Szeto@Sun.COM if (ioctlRet != 0) { 32209585STim.Szeto@Sun.COM switch (errno) { 32219585STim.Szeto@Sun.COM case EBUSY: 32229585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 32239585STim.Szeto@Sun.COM break; 32249585STim.Szeto@Sun.COM case EPERM: 32259585STim.Szeto@Sun.COM case EACCES: 32269585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 32279585STim.Szeto@Sun.COM break; 32289585STim.Szeto@Sun.COM default: 32299585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 32309585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 32319585STim.Szeto@Sun.COM errno); 32329585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 32339585STim.Szeto@Sun.COM break; 32349585STim.Szeto@Sun.COM } 32359585STim.Szeto@Sun.COM goto done; 32369585STim.Szeto@Sun.COM } 32379585STim.Szeto@Sun.COM /* 32389585STim.Szeto@Sun.COM * Check whether input buffer was large enough 32399585STim.Szeto@Sun.COM */ 32409585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) { 32419585STim.Szeto@Sun.COM groupListSize = stmfIoctl.stmf_obuf_max_nentries * 32429585STim.Szeto@Sun.COM sizeof (stmf_ge_ident_t); 32439585STim.Szeto@Sun.COM iGroupMembers = realloc(iGroupMembers, groupListSize); 32449585STim.Szeto@Sun.COM if (iGroupMembers == NULL) { 32459585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32469585STim.Szeto@Sun.COM goto done; 32479585STim.Szeto@Sun.COM } 32489585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName; 32499585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t); 32509585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = groupListSize; 32519585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers; 32529585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 32539585STim.Szeto@Sun.COM if (ioctlRet != 0) { 32549585STim.Szeto@Sun.COM switch (errno) { 32559585STim.Szeto@Sun.COM case EBUSY: 32569585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 32579585STim.Szeto@Sun.COM break; 32589585STim.Szeto@Sun.COM case EPERM: 32599585STim.Szeto@Sun.COM case EACCES: 32609585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 32619585STim.Szeto@Sun.COM break; 32629585STim.Szeto@Sun.COM default: 32639585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 32649585STim.Szeto@Sun.COM "groupListIoctl:ioctl errno(%d)", 32659585STim.Szeto@Sun.COM errno); 32669585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 32679585STim.Szeto@Sun.COM break; 32689585STim.Szeto@Sun.COM } 32699585STim.Szeto@Sun.COM goto done; 32709585STim.Szeto@Sun.COM } 32719585STim.Szeto@Sun.COM } 32729585STim.Szeto@Sun.COM 32739585STim.Szeto@Sun.COM /* allocate and copy to caller's buffer */ 32749585STim.Szeto@Sun.COM *groupProps = (stmfGroupProperties *)calloc(1, 327510236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfGroupProperties) + 327610236SSrivijitha.Dugganapalli@Sun.COM sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries); 32779585STim.Szeto@Sun.COM if (*groupProps == NULL) { 32789585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 32799585STim.Szeto@Sun.COM goto done; 32809585STim.Szeto@Sun.COM } 32819585STim.Szeto@Sun.COM (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries; 32829585STim.Szeto@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) { 32839585STim.Szeto@Sun.COM (*groupProps)->name[i].identLength = 328410113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size; 328510113SNattuvetty.Bhavyan@Sun.COM bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident, 328610113SNattuvetty.Bhavyan@Sun.COM iGroupMembers[i].ident_size); 32879585STim.Szeto@Sun.COM } 32889585STim.Szeto@Sun.COM 32899585STim.Szeto@Sun.COM done: 32909585STim.Szeto@Sun.COM free(iGroupMembers); 32919585STim.Szeto@Sun.COM (void) close(fd); 32929585STim.Szeto@Sun.COM return (ret); 32939585STim.Szeto@Sun.COM } 32949585STim.Szeto@Sun.COM 32959585STim.Szeto@Sun.COM /* 32969585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 32979585STim.Szeto@Sun.COM */ 32989585STim.Szeto@Sun.COM static int 32999585STim.Szeto@Sun.COM iLoadGroupFromPs(stmfGroupList **groupList, int type) 33009585STim.Szeto@Sun.COM { 33019585STim.Szeto@Sun.COM int ret; 33029585STim.Szeto@Sun.COM 33039585STim.Szeto@Sun.COM if (groupList == NULL) { 33049585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33059585STim.Szeto@Sun.COM } 33069585STim.Szeto@Sun.COM 33079585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 33089585STim.Szeto@Sun.COM ret = psGetHostGroupList(groupList); 33099585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 33109585STim.Szeto@Sun.COM ret = psGetTargetGroupList(groupList); 33119585STim.Szeto@Sun.COM } else { 33129585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33139585STim.Szeto@Sun.COM } 33147836SJohn.Forte@Sun.COM switch (ret) { 33157836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 33167836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 33177836SJohn.Forte@Sun.COM break; 33187836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 33197836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 33207836SJohn.Forte@Sun.COM break; 33217836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 33227836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 33237836SJohn.Forte@Sun.COM break; 33247836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33257836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33267836SJohn.Forte@Sun.COM break; 33277836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33287836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33297836SJohn.Forte@Sun.COM break; 33307836SJohn.Forte@Sun.COM default: 33317836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 33327836SJohn.Forte@Sun.COM "stmfGetHostGroupList:psGetHostGroupList:error(%d)", 33337836SJohn.Forte@Sun.COM ret); 33347836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 33357836SJohn.Forte@Sun.COM break; 33367836SJohn.Forte@Sun.COM } 33377836SJohn.Forte@Sun.COM 33387836SJohn.Forte@Sun.COM return (ret); 33397836SJohn.Forte@Sun.COM } 33407836SJohn.Forte@Sun.COM 33417836SJohn.Forte@Sun.COM /* 33429585STim.Szeto@Sun.COM * stmfGetHostGroupList 33437836SJohn.Forte@Sun.COM * 33449585STim.Szeto@Sun.COM * Purpose: Retrieves the list of initiator group oids 33459585STim.Szeto@Sun.COM * 33469585STim.Szeto@Sun.COM * hostGroupList - pointer to pointer to hostGroupList structure 33479585STim.Szeto@Sun.COM * on success, this contains the host group list. 33487836SJohn.Forte@Sun.COM */ 33497836SJohn.Forte@Sun.COM int 33509585STim.Szeto@Sun.COM stmfGetHostGroupList(stmfGroupList **hostGroupList) 33519585STim.Szeto@Sun.COM { 33529585STim.Szeto@Sun.COM int ret = STMF_STATUS_ERROR; 33539585STim.Szeto@Sun.COM 33549585STim.Szeto@Sun.COM if (hostGroupList == NULL) { 33559585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33569585STim.Szeto@Sun.COM } 33579585STim.Szeto@Sun.COM 33589585STim.Szeto@Sun.COM ret = groupListIoctl(hostGroupList, HOST_GROUP); 33599585STim.Szeto@Sun.COM return (ret); 33609585STim.Szeto@Sun.COM } 33619585STim.Szeto@Sun.COM 33629585STim.Szeto@Sun.COM 33639585STim.Szeto@Sun.COM /* 33649585STim.Szeto@Sun.COM * Purpose: access persistent config data for host groups and target groups 33659585STim.Szeto@Sun.COM */ 33669585STim.Szeto@Sun.COM static int 33679585STim.Szeto@Sun.COM iLoadGroupMembersFromPs(stmfGroupName *groupName, 33689585STim.Szeto@Sun.COM stmfGroupProperties **groupProp, int type) 33697836SJohn.Forte@Sun.COM { 33707836SJohn.Forte@Sun.COM int ret; 33717836SJohn.Forte@Sun.COM 33729585STim.Szeto@Sun.COM if (groupName == NULL) { 33737836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 33747836SJohn.Forte@Sun.COM } 33757836SJohn.Forte@Sun.COM 33769585STim.Szeto@Sun.COM if (type == HOST_GROUP) { 33779585STim.Szeto@Sun.COM ret = psGetHostGroupMemberList((char *)groupName, groupProp); 33789585STim.Szeto@Sun.COM } else if (type == TARGET_GROUP) { 33799585STim.Szeto@Sun.COM ret = psGetTargetGroupMemberList((char *)groupName, groupProp); 33809585STim.Szeto@Sun.COM } else { 33819585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 33829585STim.Szeto@Sun.COM } 33837836SJohn.Forte@Sun.COM switch (ret) { 33847836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 33857836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 33867836SJohn.Forte@Sun.COM break; 33877836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 33887836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 33897836SJohn.Forte@Sun.COM break; 33907836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 33917836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 33927836SJohn.Forte@Sun.COM break; 33937836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 33947836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 33957836SJohn.Forte@Sun.COM break; 33967836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 33977836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 33987836SJohn.Forte@Sun.COM break; 33997836SJohn.Forte@Sun.COM default: 34007836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 34019585STim.Szeto@Sun.COM "iLoadGroupMembersFromPs:psGetHostGroupList:" 34029585STim.Szeto@Sun.COM "error(%d)", ret); 34037836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 34047836SJohn.Forte@Sun.COM break; 34057836SJohn.Forte@Sun.COM } 34067836SJohn.Forte@Sun.COM 34077836SJohn.Forte@Sun.COM return (ret); 34087836SJohn.Forte@Sun.COM } 34097836SJohn.Forte@Sun.COM 34107836SJohn.Forte@Sun.COM /* 34119585STim.Szeto@Sun.COM * stmfGetHostGroupMembers 34129585STim.Szeto@Sun.COM * 34139585STim.Szeto@Sun.COM * Purpose: Retrieves the group properties for a host group 34149585STim.Szeto@Sun.COM * 34159585STim.Szeto@Sun.COM * groupName - name of group for which to retrieve host group members. 34169585STim.Szeto@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 34179585STim.Szeto@Sun.COM * on success, this contains the list of group members. 34189585STim.Szeto@Sun.COM */ 34199585STim.Szeto@Sun.COM int 34209585STim.Szeto@Sun.COM stmfGetHostGroupMembers(stmfGroupName *groupName, 34219585STim.Szeto@Sun.COM stmfGroupProperties **groupProp) 34229585STim.Szeto@Sun.COM { 34239585STim.Szeto@Sun.COM int ret; 34249585STim.Szeto@Sun.COM 34259585STim.Szeto@Sun.COM if (groupName == NULL || groupProp == NULL) { 34269585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 34279585STim.Szeto@Sun.COM } 34289585STim.Szeto@Sun.COM 34299585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP); 34309585STim.Szeto@Sun.COM 34319585STim.Szeto@Sun.COM return (ret); 34329585STim.Szeto@Sun.COM } 34339585STim.Szeto@Sun.COM 34349585STim.Szeto@Sun.COM /* 34357836SJohn.Forte@Sun.COM * stmfGetProviderData 34367836SJohn.Forte@Sun.COM * 34377836SJohn.Forte@Sun.COM * Purpose: Get provider data list 34387836SJohn.Forte@Sun.COM * 34397836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 34407836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 34417836SJohn.Forte@Sun.COM * retrieved. 34427836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 34437836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 34447836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 34457836SJohn.Forte@Sun.COM */ 34467836SJohn.Forte@Sun.COM int 34477836SJohn.Forte@Sun.COM stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType) 34487836SJohn.Forte@Sun.COM { 34497836SJohn.Forte@Sun.COM return (stmfGetProviderDataProt(providerName, nvl, providerType, 34507836SJohn.Forte@Sun.COM NULL)); 34517836SJohn.Forte@Sun.COM } 34527836SJohn.Forte@Sun.COM 34537836SJohn.Forte@Sun.COM /* 34547836SJohn.Forte@Sun.COM * stmfGetProviderDataProt 34557836SJohn.Forte@Sun.COM * 34567836SJohn.Forte@Sun.COM * Purpose: Get provider data list with token 34577836SJohn.Forte@Sun.COM * 34587836SJohn.Forte@Sun.COM * providerName - name of provider for which to retrieve the data 34597836SJohn.Forte@Sun.COM * nvl - pointer to nvlist_t pointer which will contain the nvlist data 34607836SJohn.Forte@Sun.COM * retrieved. 34617836SJohn.Forte@Sun.COM * providerType - type of provider for which to retrieve data. 34627836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 34637836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 34647836SJohn.Forte@Sun.COM * setToken - Returns the stale data token 34657836SJohn.Forte@Sun.COM */ 34667836SJohn.Forte@Sun.COM int 34677836SJohn.Forte@Sun.COM stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType, 34687836SJohn.Forte@Sun.COM uint64_t *setToken) 34697836SJohn.Forte@Sun.COM { 34707836SJohn.Forte@Sun.COM int ret; 34717836SJohn.Forte@Sun.COM 34727836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 34737836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34747836SJohn.Forte@Sun.COM } 34757836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 34767836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 34777836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 34787836SJohn.Forte@Sun.COM } 34797836SJohn.Forte@Sun.COM /* call init */ 34807836SJohn.Forte@Sun.COM ret = initializeConfig(); 34817836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 34827836SJohn.Forte@Sun.COM return (ret); 34837836SJohn.Forte@Sun.COM } 34849585STim.Szeto@Sun.COM return (getProviderData(providerName, nvl, providerType, setToken)); 34857836SJohn.Forte@Sun.COM } 34867836SJohn.Forte@Sun.COM 34877836SJohn.Forte@Sun.COM /* 34887836SJohn.Forte@Sun.COM * stmfGetProviderDataList 34897836SJohn.Forte@Sun.COM * 34907836SJohn.Forte@Sun.COM * Purpose: Get the list of providers currently persisting data 34917836SJohn.Forte@Sun.COM * 34927836SJohn.Forte@Sun.COM * providerList - pointer to pointer to an stmfProviderList structure allocated 34937836SJohn.Forte@Sun.COM * by the caller. Will contain the list of providers on success. 34947836SJohn.Forte@Sun.COM */ 34957836SJohn.Forte@Sun.COM int 34967836SJohn.Forte@Sun.COM stmfGetProviderDataList(stmfProviderList **providerList) 34977836SJohn.Forte@Sun.COM { 34987836SJohn.Forte@Sun.COM int ret; 34997836SJohn.Forte@Sun.COM 35007836SJohn.Forte@Sun.COM ret = psGetProviderDataList(providerList); 35017836SJohn.Forte@Sun.COM switch (ret) { 35027836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 35037836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 35047836SJohn.Forte@Sun.COM break; 35057836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 35067836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35077836SJohn.Forte@Sun.COM break; 35087836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 35097836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 35107836SJohn.Forte@Sun.COM break; 35117836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 35127836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 35137836SJohn.Forte@Sun.COM break; 35147836SJohn.Forte@Sun.COM default: 35157836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 35167836SJohn.Forte@Sun.COM "stmfGetProviderDataList:psGetProviderDataList" 35177836SJohn.Forte@Sun.COM ":error(%d)", ret); 35187836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 35197836SJohn.Forte@Sun.COM break; 35207836SJohn.Forte@Sun.COM } 35217836SJohn.Forte@Sun.COM 35227836SJohn.Forte@Sun.COM return (ret); 35237836SJohn.Forte@Sun.COM } 35247836SJohn.Forte@Sun.COM 35257836SJohn.Forte@Sun.COM 35267836SJohn.Forte@Sun.COM /* 35277836SJohn.Forte@Sun.COM * stmfGetSessionList 35287836SJohn.Forte@Sun.COM * 35297836SJohn.Forte@Sun.COM * Purpose: Retrieves the session list for a target (devid) 35307836SJohn.Forte@Sun.COM * 35317836SJohn.Forte@Sun.COM * devid - devid of target for which to retrieve session information. 35327836SJohn.Forte@Sun.COM * sessionList - pointer to pointer to stmfSessionList structure 35337836SJohn.Forte@Sun.COM * on success, this contains the list of initiator sessions. 35347836SJohn.Forte@Sun.COM */ 35357836SJohn.Forte@Sun.COM int 35367836SJohn.Forte@Sun.COM stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList) 35377836SJohn.Forte@Sun.COM { 35387836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 35397836SJohn.Forte@Sun.COM int fd; 35407836SJohn.Forte@Sun.COM int ioctlRet; 35417836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_SESSION_LIST; 35427836SJohn.Forte@Sun.COM int i; 35437836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 354410261SCharles.Ting@Sun.COM slist_scsi_session_t *fSessionList, *fSessionListP = NULL; 35457836SJohn.Forte@Sun.COM uint8_t ident[260]; 35467836SJohn.Forte@Sun.COM uint32_t fSessionListSize; 35477836SJohn.Forte@Sun.COM 35487836SJohn.Forte@Sun.COM if (sessionList == NULL || devid == NULL) { 35497836SJohn.Forte@Sun.COM ret = STMF_ERROR_INVALID_ARG; 35507836SJohn.Forte@Sun.COM } 35517836SJohn.Forte@Sun.COM 35527836SJohn.Forte@Sun.COM /* call init */ 35537836SJohn.Forte@Sun.COM ret = initializeConfig(); 35547836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 35557836SJohn.Forte@Sun.COM return (ret); 35567836SJohn.Forte@Sun.COM } 35577836SJohn.Forte@Sun.COM 35587836SJohn.Forte@Sun.COM /* 35597836SJohn.Forte@Sun.COM * Open control node for stmf 35607836SJohn.Forte@Sun.COM */ 35617836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 35627836SJohn.Forte@Sun.COM return (ret); 35637836SJohn.Forte@Sun.COM 35647836SJohn.Forte@Sun.COM /* 35657836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 35667836SJohn.Forte@Sun.COM */ 35679585STim.Szeto@Sun.COM fSessionListSize = ALLOC_SESSION; 35687836SJohn.Forte@Sun.COM fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t)); 35697836SJohn.Forte@Sun.COM fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize); 357010261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 35717836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 357210261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 357310261SCharles.Ting@Sun.COM goto done; 35747836SJohn.Forte@Sun.COM } 35757836SJohn.Forte@Sun.COM 35767836SJohn.Forte@Sun.COM ident[IDENT_LENGTH_BYTE] = devid->identLength; 35777836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1], 35787836SJohn.Forte@Sun.COM devid->identLength); 35797836SJohn.Forte@Sun.COM 35807836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 35817836SJohn.Forte@Sun.COM /* 35827836SJohn.Forte@Sun.COM * Issue ioctl to get the session list 35837836SJohn.Forte@Sun.COM */ 35847836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 35857836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident; 35867836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ident); 35877836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 35887836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 35897836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 35907836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 35917836SJohn.Forte@Sun.COM switch (errno) { 35927836SJohn.Forte@Sun.COM case EBUSY: 35937836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 35947836SJohn.Forte@Sun.COM break; 35959585STim.Szeto@Sun.COM case EPERM: 35967836SJohn.Forte@Sun.COM case EACCES: 35977836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 35987836SJohn.Forte@Sun.COM break; 35997836SJohn.Forte@Sun.COM default: 36007836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 36017836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl errno(%d)", 36027836SJohn.Forte@Sun.COM errno); 36037836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 36047836SJohn.Forte@Sun.COM break; 36057836SJohn.Forte@Sun.COM } 36067836SJohn.Forte@Sun.COM goto done; 36077836SJohn.Forte@Sun.COM } 36087836SJohn.Forte@Sun.COM /* 36097836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 36107836SJohn.Forte@Sun.COM */ 36119585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) { 36127836SJohn.Forte@Sun.COM fSessionListSize = stmfIoctl.stmf_obuf_max_nentries * 36137836SJohn.Forte@Sun.COM sizeof (slist_scsi_session_t); 36147836SJohn.Forte@Sun.COM fSessionList = realloc(fSessionList, fSessionListSize); 36157836SJohn.Forte@Sun.COM if (fSessionList == NULL) { 361610261SCharles.Ting@Sun.COM ret = STMF_ERROR_NOMEM; 361710261SCharles.Ting@Sun.COM goto done; 36187836SJohn.Forte@Sun.COM } 361910261SCharles.Ting@Sun.COM fSessionListP = fSessionList; 36207836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fSessionListSize; 36217836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList; 36227836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 36237836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 36247836SJohn.Forte@Sun.COM switch (errno) { 36257836SJohn.Forte@Sun.COM case EBUSY: 36267836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 36277836SJohn.Forte@Sun.COM break; 36289585STim.Szeto@Sun.COM case EPERM: 36297836SJohn.Forte@Sun.COM case EACCES: 36307836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 36317836SJohn.Forte@Sun.COM break; 36327836SJohn.Forte@Sun.COM default: 36337836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 36347836SJohn.Forte@Sun.COM "stmfGetSessionList:ioctl " 36357836SJohn.Forte@Sun.COM "errno(%d)", errno); 36367836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 36377836SJohn.Forte@Sun.COM break; 36387836SJohn.Forte@Sun.COM } 36397836SJohn.Forte@Sun.COM goto done; 36407836SJohn.Forte@Sun.COM } 36417836SJohn.Forte@Sun.COM } 36427836SJohn.Forte@Sun.COM 36437836SJohn.Forte@Sun.COM /* 36447836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 36457836SJohn.Forte@Sun.COM */ 36467836SJohn.Forte@Sun.COM *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) + 36477836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession)); 36487836SJohn.Forte@Sun.COM if (*sessionList == NULL) { 36497836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 36507836SJohn.Forte@Sun.COM free(sessionList); 36517836SJohn.Forte@Sun.COM goto done; 36527836SJohn.Forte@Sun.COM } 36537836SJohn.Forte@Sun.COM 36547836SJohn.Forte@Sun.COM (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 36557836SJohn.Forte@Sun.COM 36567836SJohn.Forte@Sun.COM /* 36577836SJohn.Forte@Sun.COM * copy session info to caller's buffer 36587836SJohn.Forte@Sun.COM */ 36597836SJohn.Forte@Sun.COM for (i = 0; i < (*sessionList)->cnt; i++) { 36607836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.identLength = 36617836SJohn.Forte@Sun.COM fSessionList->initiator[IDENT_LENGTH_BYTE]; 36627836SJohn.Forte@Sun.COM bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]), 36637836SJohn.Forte@Sun.COM (*sessionList)->session[i].initiator.ident, 36647836SJohn.Forte@Sun.COM STMF_IDENT_LENGTH); 36657836SJohn.Forte@Sun.COM bcopy(&(fSessionList->alias), 36667836SJohn.Forte@Sun.COM &((*sessionList)->session[i].alias), 36677836SJohn.Forte@Sun.COM sizeof ((*sessionList)->session[i].alias)); 36687836SJohn.Forte@Sun.COM bcopy(&(fSessionList++->creation_time), 36697836SJohn.Forte@Sun.COM &((*sessionList)->session[i].creationTime), 36707836SJohn.Forte@Sun.COM sizeof (time_t)); 36717836SJohn.Forte@Sun.COM } 36727836SJohn.Forte@Sun.COM done: 36737836SJohn.Forte@Sun.COM (void) close(fd); 367410261SCharles.Ting@Sun.COM free(fSessionListP); 36757836SJohn.Forte@Sun.COM return (ret); 36767836SJohn.Forte@Sun.COM } 36777836SJohn.Forte@Sun.COM 36787836SJohn.Forte@Sun.COM /* 36797836SJohn.Forte@Sun.COM * stmfGetTargetGroupList 36807836SJohn.Forte@Sun.COM * 36817836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target groups 36827836SJohn.Forte@Sun.COM * 36837836SJohn.Forte@Sun.COM * targetGroupList - pointer to a pointer to an stmfGroupList structure. On 36847836SJohn.Forte@Sun.COM * success, it contains the list of target groups. 36857836SJohn.Forte@Sun.COM */ 36867836SJohn.Forte@Sun.COM int 36877836SJohn.Forte@Sun.COM stmfGetTargetGroupList(stmfGroupList **targetGroupList) 36887836SJohn.Forte@Sun.COM { 36897836SJohn.Forte@Sun.COM int ret; 36907836SJohn.Forte@Sun.COM 36917836SJohn.Forte@Sun.COM if (targetGroupList == NULL) { 36927836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 36937836SJohn.Forte@Sun.COM } 36947836SJohn.Forte@Sun.COM 36959585STim.Szeto@Sun.COM ret = groupListIoctl(targetGroupList, TARGET_GROUP); 36967836SJohn.Forte@Sun.COM return (ret); 36977836SJohn.Forte@Sun.COM } 36987836SJohn.Forte@Sun.COM 36997836SJohn.Forte@Sun.COM /* 37007836SJohn.Forte@Sun.COM * stmfGetTargetGroupMembers 37017836SJohn.Forte@Sun.COM * 37027836SJohn.Forte@Sun.COM * Purpose: Retrieves the group members for a target group 37037836SJohn.Forte@Sun.COM * 37047836SJohn.Forte@Sun.COM * groupName - name of target group for which to retrieve members. 37057836SJohn.Forte@Sun.COM * groupProp - pointer to pointer to stmfGroupProperties structure 37067836SJohn.Forte@Sun.COM * on success, this contains the list of group members. 37077836SJohn.Forte@Sun.COM */ 37087836SJohn.Forte@Sun.COM int 37097836SJohn.Forte@Sun.COM stmfGetTargetGroupMembers(stmfGroupName *groupName, 37107836SJohn.Forte@Sun.COM stmfGroupProperties **groupProp) 37117836SJohn.Forte@Sun.COM { 37127836SJohn.Forte@Sun.COM int ret; 37137836SJohn.Forte@Sun.COM 37147836SJohn.Forte@Sun.COM if (groupName == NULL || groupProp == NULL) { 37157836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 37167836SJohn.Forte@Sun.COM } 37177836SJohn.Forte@Sun.COM 37189585STim.Szeto@Sun.COM ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP); 37197836SJohn.Forte@Sun.COM 37207836SJohn.Forte@Sun.COM return (ret); 37217836SJohn.Forte@Sun.COM } 37227836SJohn.Forte@Sun.COM 37237836SJohn.Forte@Sun.COM /* 37247836SJohn.Forte@Sun.COM * stmfGetTargetList 37257836SJohn.Forte@Sun.COM * 37267836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of target ports 37277836SJohn.Forte@Sun.COM * 37287836SJohn.Forte@Sun.COM * targetList - pointer to a pointer to an stmfDevidList structure. 37297836SJohn.Forte@Sun.COM * On success, it contains the list of local ports (target). 37307836SJohn.Forte@Sun.COM */ 37317836SJohn.Forte@Sun.COM int 37327836SJohn.Forte@Sun.COM stmfGetTargetList(stmfDevidList **targetList) 37337836SJohn.Forte@Sun.COM { 37347836SJohn.Forte@Sun.COM int ret; 37357836SJohn.Forte@Sun.COM int fd; 37367836SJohn.Forte@Sun.COM int ioctlRet; 37377836SJohn.Forte@Sun.COM int i; 37387836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 37397836SJohn.Forte@Sun.COM /* framework target port list */ 37409585STim.Szeto@Sun.COM slist_target_port_t *fTargetList, *fTargetListP = NULL; 37417836SJohn.Forte@Sun.COM uint32_t fTargetListSize; 37427836SJohn.Forte@Sun.COM 37437836SJohn.Forte@Sun.COM if (targetList == NULL) { 37447836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 37457836SJohn.Forte@Sun.COM } 37467836SJohn.Forte@Sun.COM 37477836SJohn.Forte@Sun.COM /* call init */ 37487836SJohn.Forte@Sun.COM ret = initializeConfig(); 37497836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 37507836SJohn.Forte@Sun.COM return (ret); 37517836SJohn.Forte@Sun.COM } 37527836SJohn.Forte@Sun.COM 37537836SJohn.Forte@Sun.COM /* 37547836SJohn.Forte@Sun.COM * Open control node for stmf 37557836SJohn.Forte@Sun.COM */ 37567836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 37577836SJohn.Forte@Sun.COM return (ret); 37587836SJohn.Forte@Sun.COM 37597836SJohn.Forte@Sun.COM /* 37607836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 37617836SJohn.Forte@Sun.COM */ 37629585STim.Szeto@Sun.COM fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t); 37638252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 37648252SJohn.Forte@Sun.COM (slist_target_port_t *)calloc(1, fTargetListSize); 37657836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 37669585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 37677836SJohn.Forte@Sun.COM goto done; 37687836SJohn.Forte@Sun.COM } 37697836SJohn.Forte@Sun.COM 37707836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 37717836SJohn.Forte@Sun.COM /* 37728252SJohn.Forte@Sun.COM * Issue ioctl to retrieve target list 37737836SJohn.Forte@Sun.COM */ 37747836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 37757836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 37767836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 37777836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl); 37787836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 37797836SJohn.Forte@Sun.COM switch (errno) { 37807836SJohn.Forte@Sun.COM case EBUSY: 37817836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 37827836SJohn.Forte@Sun.COM break; 37839585STim.Szeto@Sun.COM case EPERM: 37847836SJohn.Forte@Sun.COM case EACCES: 37857836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 37867836SJohn.Forte@Sun.COM break; 37877836SJohn.Forte@Sun.COM default: 37887836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 37897836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", errno); 37907836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 37917836SJohn.Forte@Sun.COM break; 37927836SJohn.Forte@Sun.COM } 37937836SJohn.Forte@Sun.COM goto done; 37947836SJohn.Forte@Sun.COM } 37957836SJohn.Forte@Sun.COM /* 37967836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 37977836SJohn.Forte@Sun.COM */ 37989585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) { 37997836SJohn.Forte@Sun.COM fTargetListSize = stmfIoctl.stmf_obuf_max_nentries * 38008116SJohn.Forte@Sun.COM sizeof (slist_target_port_t); 38018252SJohn.Forte@Sun.COM fTargetListP = fTargetList = 38028252SJohn.Forte@Sun.COM realloc(fTargetList, fTargetListSize); 38037836SJohn.Forte@Sun.COM if (fTargetList == NULL) { 38049585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 38059585STim.Szeto@Sun.COM goto done; 38067836SJohn.Forte@Sun.COM } 38077836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fTargetListSize; 38087836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList; 38097836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, 38107836SJohn.Forte@Sun.COM &stmfIoctl); 38117836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 38127836SJohn.Forte@Sun.COM switch (errno) { 38137836SJohn.Forte@Sun.COM case EBUSY: 38147836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 38157836SJohn.Forte@Sun.COM break; 38169585STim.Szeto@Sun.COM case EPERM: 38177836SJohn.Forte@Sun.COM case EACCES: 38187836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 38197836SJohn.Forte@Sun.COM break; 38207836SJohn.Forte@Sun.COM default: 38217836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 38227836SJohn.Forte@Sun.COM "stmfGetTargetList:ioctl errno(%d)", 38237836SJohn.Forte@Sun.COM errno); 38247836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 38257836SJohn.Forte@Sun.COM break; 38267836SJohn.Forte@Sun.COM } 38277836SJohn.Forte@Sun.COM goto done; 38287836SJohn.Forte@Sun.COM } 38297836SJohn.Forte@Sun.COM } 38307836SJohn.Forte@Sun.COM 38317836SJohn.Forte@Sun.COM *targetList = (stmfDevidList *)calloc(1, 38327836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) + 38337836SJohn.Forte@Sun.COM sizeof (stmfDevidList)); 38349585STim.Szeto@Sun.COM if (*targetList == NULL) { 38359585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 38369585STim.Szeto@Sun.COM goto done; 38379585STim.Szeto@Sun.COM } 38387836SJohn.Forte@Sun.COM 38397836SJohn.Forte@Sun.COM (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries; 38407836SJohn.Forte@Sun.COM for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) { 38417836SJohn.Forte@Sun.COM (*targetList)->devid[i].identLength = 38427836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]; 38437836SJohn.Forte@Sun.COM bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1], 38447836SJohn.Forte@Sun.COM &(*targetList)->devid[i].ident, 38457836SJohn.Forte@Sun.COM fTargetList->target[IDENT_LENGTH_BYTE]); 38467836SJohn.Forte@Sun.COM } 38477836SJohn.Forte@Sun.COM 38487836SJohn.Forte@Sun.COM done: 38497836SJohn.Forte@Sun.COM (void) close(fd); 38508252SJohn.Forte@Sun.COM free(fTargetListP); 38517836SJohn.Forte@Sun.COM return (ret); 38527836SJohn.Forte@Sun.COM } 38537836SJohn.Forte@Sun.COM 38547836SJohn.Forte@Sun.COM /* 38557836SJohn.Forte@Sun.COM * stmfGetTargetProperties 38567836SJohn.Forte@Sun.COM * 38577836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 38587836SJohn.Forte@Sun.COM * 38597836SJohn.Forte@Sun.COM * devid - devid of the target for which to retrieve properties 38607836SJohn.Forte@Sun.COM * targetProps - pointer to an stmfTargetProperties structure. 38617836SJohn.Forte@Sun.COM * On success, it contains the target properties for 38627836SJohn.Forte@Sun.COM * the specified devid. 38637836SJohn.Forte@Sun.COM */ 38647836SJohn.Forte@Sun.COM int 38657836SJohn.Forte@Sun.COM stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps) 38667836SJohn.Forte@Sun.COM { 38677836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 38687836SJohn.Forte@Sun.COM int fd; 38697836SJohn.Forte@Sun.COM int ioctlRet; 38707836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 38717836SJohn.Forte@Sun.COM sioc_target_port_props_t targetProperties; 38727836SJohn.Forte@Sun.COM 38737836SJohn.Forte@Sun.COM if (devid == NULL || targetProps == NULL) { 38747836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 38757836SJohn.Forte@Sun.COM } 38767836SJohn.Forte@Sun.COM 38777836SJohn.Forte@Sun.COM /* call init */ 38787836SJohn.Forte@Sun.COM ret = initializeConfig(); 38797836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 38807836SJohn.Forte@Sun.COM return (ret); 38817836SJohn.Forte@Sun.COM } 38827836SJohn.Forte@Sun.COM 38837836SJohn.Forte@Sun.COM /* 38847836SJohn.Forte@Sun.COM * Open control node for stmf 38857836SJohn.Forte@Sun.COM */ 38867836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 38877836SJohn.Forte@Sun.COM return (ret); 38887836SJohn.Forte@Sun.COM 38897836SJohn.Forte@Sun.COM targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength; 38907836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1], 38917836SJohn.Forte@Sun.COM devid->identLength); 38927836SJohn.Forte@Sun.COM 38937836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 38947836SJohn.Forte@Sun.COM /* 38957836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 38967836SJohn.Forte@Sun.COM */ 38977836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 38987836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id); 38997836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id; 39007836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties; 39017836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (targetProperties); 39027836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES, 39037836SJohn.Forte@Sun.COM &stmfIoctl); 39047836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 39057836SJohn.Forte@Sun.COM switch (errno) { 39067836SJohn.Forte@Sun.COM case EBUSY: 39077836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 39087836SJohn.Forte@Sun.COM break; 39099585STim.Szeto@Sun.COM case EPERM: 39107836SJohn.Forte@Sun.COM case EACCES: 39117836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 39127836SJohn.Forte@Sun.COM break; 39137836SJohn.Forte@Sun.COM case ENOENT: 39147836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 39157836SJohn.Forte@Sun.COM break; 39167836SJohn.Forte@Sun.COM default: 39177836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 39187836SJohn.Forte@Sun.COM "stmfGetTargetProperties:ioctl errno(%d)", 39197836SJohn.Forte@Sun.COM errno); 39207836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 39217836SJohn.Forte@Sun.COM break; 39227836SJohn.Forte@Sun.COM } 39237836SJohn.Forte@Sun.COM goto done; 39247836SJohn.Forte@Sun.COM } 39257836SJohn.Forte@Sun.COM 39267836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_provider_name, targetProps->providerName, 39277836SJohn.Forte@Sun.COM sizeof (targetProperties.tgt_provider_name)); 39287836SJohn.Forte@Sun.COM if (targetProperties.tgt_state == STMF_STATE_ONLINE) { 39297836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINE; 39307836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) { 39317836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINE; 39327836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) { 39337836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_ONLINING; 39347836SJohn.Forte@Sun.COM } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) { 39357836SJohn.Forte@Sun.COM targetProps->status = STMF_TARGET_PORT_OFFLINING; 39367836SJohn.Forte@Sun.COM } 39377836SJohn.Forte@Sun.COM bcopy(targetProperties.tgt_alias, targetProps->alias, 39387836SJohn.Forte@Sun.COM sizeof (targetProps->alias)); 39397836SJohn.Forte@Sun.COM done: 39407836SJohn.Forte@Sun.COM (void) close(fd); 39417836SJohn.Forte@Sun.COM return (ret); 39427836SJohn.Forte@Sun.COM } 39437836SJohn.Forte@Sun.COM 39447836SJohn.Forte@Sun.COM /* 39457836SJohn.Forte@Sun.COM * stmfGetLogicalUnitList 39467836SJohn.Forte@Sun.COM * 39477836SJohn.Forte@Sun.COM * Purpose: Retrieves list of logical unit Object IDs 39487836SJohn.Forte@Sun.COM * 39497836SJohn.Forte@Sun.COM * luList - pointer to a pointer to a stmfGuidList structure. On success, 39507836SJohn.Forte@Sun.COM * it contains the list of logical unit guids. 39517836SJohn.Forte@Sun.COM * 39527836SJohn.Forte@Sun.COM */ 39537836SJohn.Forte@Sun.COM int 39547836SJohn.Forte@Sun.COM stmfGetLogicalUnitList(stmfGuidList **luList) 39557836SJohn.Forte@Sun.COM { 39567836SJohn.Forte@Sun.COM int ret; 39577836SJohn.Forte@Sun.COM int fd; 39587836SJohn.Forte@Sun.COM int ioctlRet; 39597836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_LU_LIST; 39609585STim.Szeto@Sun.COM int i; 39617836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 39627836SJohn.Forte@Sun.COM slist_lu_t *fLuList; 39637836SJohn.Forte@Sun.COM uint32_t fLuListSize; 39649585STim.Szeto@Sun.COM uint32_t listCnt; 39657836SJohn.Forte@Sun.COM 39667836SJohn.Forte@Sun.COM if (luList == NULL) { 39677836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 39687836SJohn.Forte@Sun.COM } 39697836SJohn.Forte@Sun.COM 39707836SJohn.Forte@Sun.COM /* call init */ 39717836SJohn.Forte@Sun.COM ret = initializeConfig(); 39727836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 39737836SJohn.Forte@Sun.COM return (ret); 39747836SJohn.Forte@Sun.COM } 39757836SJohn.Forte@Sun.COM 39767836SJohn.Forte@Sun.COM /* 39777836SJohn.Forte@Sun.COM * Open control node for stmf 39787836SJohn.Forte@Sun.COM */ 39797836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 39807836SJohn.Forte@Sun.COM return (ret); 39817836SJohn.Forte@Sun.COM 39827836SJohn.Forte@Sun.COM /* 39837836SJohn.Forte@Sun.COM * Allocate ioctl input buffer 39847836SJohn.Forte@Sun.COM */ 39859585STim.Szeto@Sun.COM fLuListSize = ALLOC_LU; 39867836SJohn.Forte@Sun.COM fLuListSize = fLuListSize * (sizeof (slist_lu_t)); 39877836SJohn.Forte@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 39887836SJohn.Forte@Sun.COM if (fLuList == NULL) { 39899585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 39909585STim.Szeto@Sun.COM goto done; 39917836SJohn.Forte@Sun.COM } 39927836SJohn.Forte@Sun.COM 39937836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 39947836SJohn.Forte@Sun.COM /* 39957836SJohn.Forte@Sun.COM * Issue ioctl to get the LU list 39967836SJohn.Forte@Sun.COM */ 39977836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 39987836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 39997836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 40007836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40017836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40027836SJohn.Forte@Sun.COM switch (errno) { 40037836SJohn.Forte@Sun.COM case EBUSY: 40047836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40057836SJohn.Forte@Sun.COM break; 40069585STim.Szeto@Sun.COM case EPERM: 40077836SJohn.Forte@Sun.COM case EACCES: 40087836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40097836SJohn.Forte@Sun.COM break; 40107836SJohn.Forte@Sun.COM default: 40117836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40127836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:ioctl errno(%d)", 40137836SJohn.Forte@Sun.COM errno); 40147836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40157836SJohn.Forte@Sun.COM break; 40167836SJohn.Forte@Sun.COM } 40177836SJohn.Forte@Sun.COM goto done; 40187836SJohn.Forte@Sun.COM } 40197836SJohn.Forte@Sun.COM /* 40207836SJohn.Forte@Sun.COM * Check whether input buffer was large enough 40217836SJohn.Forte@Sun.COM */ 40229585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) { 40237836SJohn.Forte@Sun.COM fLuListSize = stmfIoctl.stmf_obuf_max_nentries * 40247836SJohn.Forte@Sun.COM sizeof (slist_lu_t); 40259585STim.Szeto@Sun.COM free(fLuList); 40269585STim.Szeto@Sun.COM fLuList = (slist_lu_t *)calloc(1, fLuListSize); 40277836SJohn.Forte@Sun.COM if (fLuList == NULL) { 40289585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 40299585STim.Szeto@Sun.COM goto done; 40307836SJohn.Forte@Sun.COM } 40317836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = fLuListSize; 40327836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList; 40337836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 40347836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 40357836SJohn.Forte@Sun.COM switch (errno) { 40367836SJohn.Forte@Sun.COM case EBUSY: 40377836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 40387836SJohn.Forte@Sun.COM break; 40399585STim.Szeto@Sun.COM case EPERM: 40407836SJohn.Forte@Sun.COM case EACCES: 40417836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 40427836SJohn.Forte@Sun.COM break; 40437836SJohn.Forte@Sun.COM default: 40447836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 40457836SJohn.Forte@Sun.COM "stmfGetLogicalUnitList:" 40467836SJohn.Forte@Sun.COM "ioctl errno(%d)", errno); 40477836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 40487836SJohn.Forte@Sun.COM break; 40497836SJohn.Forte@Sun.COM } 40507836SJohn.Forte@Sun.COM goto done; 40517836SJohn.Forte@Sun.COM } 40527836SJohn.Forte@Sun.COM } 40537836SJohn.Forte@Sun.COM 40547836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 40557836SJohn.Forte@Sun.COM goto done; 40567836SJohn.Forte@Sun.COM } 40577836SJohn.Forte@Sun.COM 40589585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 40597836SJohn.Forte@Sun.COM 40607836SJohn.Forte@Sun.COM /* 40617836SJohn.Forte@Sun.COM * allocate caller's buffer with the final size 40627836SJohn.Forte@Sun.COM */ 40637836SJohn.Forte@Sun.COM *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) + 40649585STim.Szeto@Sun.COM listCnt * sizeof (stmfGuid)); 40657836SJohn.Forte@Sun.COM if (*luList == NULL) { 40667836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOMEM; 40677836SJohn.Forte@Sun.COM goto done; 40687836SJohn.Forte@Sun.COM } 40697836SJohn.Forte@Sun.COM 40709585STim.Szeto@Sun.COM (*luList)->cnt = listCnt; 40719585STim.Szeto@Sun.COM 40729585STim.Szeto@Sun.COM /* copy to caller's buffer */ 40739585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 40749585STim.Szeto@Sun.COM bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid, 40759585STim.Szeto@Sun.COM sizeof (stmfGuid)); 40769585STim.Szeto@Sun.COM } 40779585STim.Szeto@Sun.COM 40787836SJohn.Forte@Sun.COM /* 40799585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 40807836SJohn.Forte@Sun.COM */ 40819585STim.Szeto@Sun.COM qsort((void *)&((*luList)->guid[0]), (*luList)->cnt, 40829585STim.Szeto@Sun.COM sizeof (stmfGuid), guidCompare); 40837836SJohn.Forte@Sun.COM 40847836SJohn.Forte@Sun.COM done: 40857836SJohn.Forte@Sun.COM (void) close(fd); 40867836SJohn.Forte@Sun.COM /* 40877836SJohn.Forte@Sun.COM * free internal buffers 40887836SJohn.Forte@Sun.COM */ 40897836SJohn.Forte@Sun.COM free(fLuList); 40907836SJohn.Forte@Sun.COM return (ret); 40917836SJohn.Forte@Sun.COM } 40927836SJohn.Forte@Sun.COM 40937836SJohn.Forte@Sun.COM /* 40947836SJohn.Forte@Sun.COM * stmfGetLogicalUnitProperties 40957836SJohn.Forte@Sun.COM * 40967836SJohn.Forte@Sun.COM * Purpose: Retrieves the properties for a logical unit 40977836SJohn.Forte@Sun.COM * 40987836SJohn.Forte@Sun.COM * lu - guid of the logical unit for which to retrieve properties 40997836SJohn.Forte@Sun.COM * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success, 41007836SJohn.Forte@Sun.COM * it contains the logical unit properties for the specified guid. 41017836SJohn.Forte@Sun.COM */ 41027836SJohn.Forte@Sun.COM int 41037836SJohn.Forte@Sun.COM stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps) 41047836SJohn.Forte@Sun.COM { 41057836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 41067836SJohn.Forte@Sun.COM int stmfRet; 41077836SJohn.Forte@Sun.COM int fd; 41087836SJohn.Forte@Sun.COM int ioctlRet; 41097836SJohn.Forte@Sun.COM int cmd = STMF_IOCTL_GET_LU_PROPERTIES; 41107836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 41117836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 41127836SJohn.Forte@Sun.COM sioc_lu_props_t fLuProps; 41137836SJohn.Forte@Sun.COM 41149585STim.Szeto@Sun.COM if (lu == NULL || luProps == NULL) { 41159585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 41167836SJohn.Forte@Sun.COM } 41177836SJohn.Forte@Sun.COM 41187836SJohn.Forte@Sun.COM bzero(luProps, sizeof (stmfLogicalUnitProperties)); 41197836SJohn.Forte@Sun.COM 41207836SJohn.Forte@Sun.COM /* call init */ 41217836SJohn.Forte@Sun.COM ret = initializeConfig(); 41227836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 41237836SJohn.Forte@Sun.COM return (ret); 41247836SJohn.Forte@Sun.COM } 41257836SJohn.Forte@Sun.COM 41267836SJohn.Forte@Sun.COM /* 41277836SJohn.Forte@Sun.COM * Open control node for stmf 41287836SJohn.Forte@Sun.COM */ 41297836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 41307836SJohn.Forte@Sun.COM return (ret); 41317836SJohn.Forte@Sun.COM 41327836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 41337836SJohn.Forte@Sun.COM /* 41347836SJohn.Forte@Sun.COM * Issue ioctl to add to the host group 41357836SJohn.Forte@Sun.COM */ 41367836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 41377836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 41387836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 41397836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps; 41407836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (fLuProps); 41417836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 41427836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 41437836SJohn.Forte@Sun.COM switch (errno) { 41447836SJohn.Forte@Sun.COM case EBUSY: 41457836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 41467836SJohn.Forte@Sun.COM break; 41479585STim.Szeto@Sun.COM case EPERM: 41487836SJohn.Forte@Sun.COM case EACCES: 41497836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 41507836SJohn.Forte@Sun.COM break; 41517836SJohn.Forte@Sun.COM case ENOENT: 41527836SJohn.Forte@Sun.COM stmfRet = stmfGetViewEntryList(lu, 41537836SJohn.Forte@Sun.COM &viewEntryList); 41547836SJohn.Forte@Sun.COM if (stmfRet == STMF_STATUS_SUCCESS) { 41557836SJohn.Forte@Sun.COM luProps->status = 41567836SJohn.Forte@Sun.COM STMF_LOGICAL_UNIT_UNREGISTERED; 41577836SJohn.Forte@Sun.COM if (viewEntryList->cnt > 0) { 41587836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 41597836SJohn.Forte@Sun.COM } else { 41607836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 41617836SJohn.Forte@Sun.COM } 41627836SJohn.Forte@Sun.COM } else { 41637836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 41647836SJohn.Forte@Sun.COM } 41657836SJohn.Forte@Sun.COM stmfFreeMemory(viewEntryList); 41667836SJohn.Forte@Sun.COM break; 41677836SJohn.Forte@Sun.COM default: 41687836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 41697836SJohn.Forte@Sun.COM "stmfGetLogicalUnit:ioctl errno(%d)", 41707836SJohn.Forte@Sun.COM errno); 41717836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 41727836SJohn.Forte@Sun.COM break; 41737836SJohn.Forte@Sun.COM } 41747836SJohn.Forte@Sun.COM goto done; 41757836SJohn.Forte@Sun.COM } 41767836SJohn.Forte@Sun.COM 41777836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_provider_name, luProps->providerName, 41787836SJohn.Forte@Sun.COM sizeof (fLuProps.lu_provider_name)); 41797836SJohn.Forte@Sun.COM if (fLuProps.lu_state == STMF_STATE_ONLINE) { 41807836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINE; 41817836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) { 41827836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINE; 41837836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_ONLINING) { 41847836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_ONLINING; 41857836SJohn.Forte@Sun.COM } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) { 41867836SJohn.Forte@Sun.COM luProps->status = STMF_LOGICAL_UNIT_OFFLINING; 41877836SJohn.Forte@Sun.COM } 41887836SJohn.Forte@Sun.COM bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias)); 41897836SJohn.Forte@Sun.COM done: 41907836SJohn.Forte@Sun.COM (void) close(fd); 41917836SJohn.Forte@Sun.COM return (ret); 41927836SJohn.Forte@Sun.COM } 41937836SJohn.Forte@Sun.COM 41947836SJohn.Forte@Sun.COM /* 41957836SJohn.Forte@Sun.COM * stmfGetState 41967836SJohn.Forte@Sun.COM * 41977836SJohn.Forte@Sun.COM * Purpose: retrieve the current state of the stmf module 41987836SJohn.Forte@Sun.COM * 41997836SJohn.Forte@Sun.COM * state - pointer to stmfState structure allocated by the caller 42007836SJohn.Forte@Sun.COM * On success, contains the state of stmf 42017836SJohn.Forte@Sun.COM */ 42027836SJohn.Forte@Sun.COM int 42037836SJohn.Forte@Sun.COM stmfGetState(stmfState *state) 42047836SJohn.Forte@Sun.COM { 42057836SJohn.Forte@Sun.COM int ret; 42067836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 42077836SJohn.Forte@Sun.COM 42087836SJohn.Forte@Sun.COM if (state == NULL) { 42097836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 42107836SJohn.Forte@Sun.COM } 42117836SJohn.Forte@Sun.COM 42127836SJohn.Forte@Sun.COM ret = getStmfState(&iState); 42137836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42147836SJohn.Forte@Sun.COM return (ret); 42157836SJohn.Forte@Sun.COM } 42167836SJohn.Forte@Sun.COM switch (iState.state) { 42177836SJohn.Forte@Sun.COM case STMF_STATE_ONLINE: 42187836SJohn.Forte@Sun.COM state->operationalState = 42197836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINE; 42207836SJohn.Forte@Sun.COM break; 42217836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINE: 42227836SJohn.Forte@Sun.COM state->operationalState = 42237836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINE; 42247836SJohn.Forte@Sun.COM break; 42257836SJohn.Forte@Sun.COM case STMF_STATE_ONLINING: 42267836SJohn.Forte@Sun.COM state->operationalState = 42277836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_ONLINING; 42287836SJohn.Forte@Sun.COM break; 42297836SJohn.Forte@Sun.COM case STMF_STATE_OFFLINING: 42307836SJohn.Forte@Sun.COM state->operationalState = 42317836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_OFFLINING; 42327836SJohn.Forte@Sun.COM break; 42337836SJohn.Forte@Sun.COM default: 42347836SJohn.Forte@Sun.COM state->operationalState = 42357836SJohn.Forte@Sun.COM STMF_SERVICE_STATE_UNKNOWN; 42367836SJohn.Forte@Sun.COM break; 42377836SJohn.Forte@Sun.COM } 42387836SJohn.Forte@Sun.COM switch (iState.config_state) { 42397836SJohn.Forte@Sun.COM case STMF_CONFIG_NONE: 42407836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_NONE; 42417836SJohn.Forte@Sun.COM break; 42427836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT: 42437836SJohn.Forte@Sun.COM state->configState = STMF_CONFIG_STATE_INIT; 42447836SJohn.Forte@Sun.COM break; 42457836SJohn.Forte@Sun.COM case STMF_CONFIG_INIT_DONE: 42467836SJohn.Forte@Sun.COM state->configState = 42477836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_INIT_DONE; 42487836SJohn.Forte@Sun.COM break; 42497836SJohn.Forte@Sun.COM default: 42507836SJohn.Forte@Sun.COM state->configState = 42517836SJohn.Forte@Sun.COM STMF_CONFIG_STATE_UNKNOWN; 42527836SJohn.Forte@Sun.COM break; 42537836SJohn.Forte@Sun.COM } 42547836SJohn.Forte@Sun.COM return (STMF_STATUS_SUCCESS); 42557836SJohn.Forte@Sun.COM } 42567836SJohn.Forte@Sun.COM 42577836SJohn.Forte@Sun.COM /* 42587836SJohn.Forte@Sun.COM * stmfGetViewEntryList 42597836SJohn.Forte@Sun.COM * 42607836SJohn.Forte@Sun.COM * Purpose: Retrieves the list of view entries for the specified 42617836SJohn.Forte@Sun.COM * logical unit. 42627836SJohn.Forte@Sun.COM * 42637836SJohn.Forte@Sun.COM * lu - the guid of the logical unit for which to retrieve the view entry list 42647836SJohn.Forte@Sun.COM * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On 42657836SJohn.Forte@Sun.COM * success, contains the list of view entries. 42667836SJohn.Forte@Sun.COM */ 42677836SJohn.Forte@Sun.COM int 42687836SJohn.Forte@Sun.COM stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList) 42697836SJohn.Forte@Sun.COM { 42707836SJohn.Forte@Sun.COM int ret; 42719585STim.Szeto@Sun.COM int fd; 42729585STim.Szeto@Sun.COM int ioctlRet; 42739585STim.Szeto@Sun.COM int cmd = STMF_IOCTL_LU_VE_LIST; 42749585STim.Szeto@Sun.COM int i; 42759585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 42769585STim.Szeto@Sun.COM stmf_view_op_entry_t *fVeList; 42779585STim.Szeto@Sun.COM uint32_t fVeListSize; 42789585STim.Szeto@Sun.COM uint32_t listCnt; 42797836SJohn.Forte@Sun.COM 42807836SJohn.Forte@Sun.COM if (lu == NULL || viewEntryList == NULL) { 42817836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 42827836SJohn.Forte@Sun.COM } 42837836SJohn.Forte@Sun.COM 42849585STim.Szeto@Sun.COM /* call init */ 42859585STim.Szeto@Sun.COM ret = initializeConfig(); 42869585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 42879585STim.Szeto@Sun.COM return (ret); 42889585STim.Szeto@Sun.COM } 42899585STim.Szeto@Sun.COM 42909585STim.Szeto@Sun.COM /* 42919585STim.Szeto@Sun.COM * Open control node for stmf 42929585STim.Szeto@Sun.COM */ 42939585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 42949585STim.Szeto@Sun.COM return (ret); 42959585STim.Szeto@Sun.COM 42969585STim.Szeto@Sun.COM /* 42979585STim.Szeto@Sun.COM * Allocate ioctl input buffer 42989585STim.Szeto@Sun.COM */ 42999585STim.Szeto@Sun.COM fVeListSize = ALLOC_VE; 43009585STim.Szeto@Sun.COM fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t)); 43019585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 43029585STim.Szeto@Sun.COM if (fVeList == NULL) { 43039585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 43049585STim.Szeto@Sun.COM goto done; 43059585STim.Szeto@Sun.COM } 43069585STim.Szeto@Sun.COM 43079585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 43089585STim.Szeto@Sun.COM /* 43099585STim.Szeto@Sun.COM * Issue ioctl to get the LU list 43109585STim.Szeto@Sun.COM */ 43119585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 43129585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu; 43139585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid); 43149585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 43159585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 43169585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 43179585STim.Szeto@Sun.COM if (ioctlRet != 0) { 43189585STim.Szeto@Sun.COM switch (errno) { 43199585STim.Szeto@Sun.COM case EBUSY: 43209585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 43219585STim.Szeto@Sun.COM break; 43229585STim.Szeto@Sun.COM case EPERM: 43239585STim.Szeto@Sun.COM case EACCES: 43249585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 43259585STim.Szeto@Sun.COM break; 43269585STim.Szeto@Sun.COM default: 43279585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 43289585STim.Szeto@Sun.COM "stmfGetViewEntryList:ioctl errno(%d)", 43299585STim.Szeto@Sun.COM errno); 43309585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 43319585STim.Szeto@Sun.COM break; 43329585STim.Szeto@Sun.COM } 43339585STim.Szeto@Sun.COM goto done; 43349585STim.Szeto@Sun.COM } 43359585STim.Szeto@Sun.COM /* 43369585STim.Szeto@Sun.COM * Check whether input buffer was large enough 43379585STim.Szeto@Sun.COM */ 43389585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) { 43399585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 43409585STim.Szeto@Sun.COM fVeListSize = stmfIoctl.stmf_obuf_max_nentries * 43419585STim.Szeto@Sun.COM sizeof (stmf_view_op_entry_t); 43429585STim.Szeto@Sun.COM free(fVeList); 43439585STim.Szeto@Sun.COM fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize); 43449585STim.Szeto@Sun.COM if (fVeList == NULL) { 43459585STim.Szeto@Sun.COM return (STMF_ERROR_NOMEM); 43469585STim.Szeto@Sun.COM } 43479585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = fVeListSize; 43489585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList; 43499585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 43509585STim.Szeto@Sun.COM if (ioctlRet != 0) { 43519585STim.Szeto@Sun.COM switch (errno) { 43529585STim.Szeto@Sun.COM case EBUSY: 43539585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 43549585STim.Szeto@Sun.COM break; 43559585STim.Szeto@Sun.COM case EPERM: 43569585STim.Szeto@Sun.COM case EACCES: 43579585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 43589585STim.Szeto@Sun.COM break; 43599585STim.Szeto@Sun.COM default: 43609585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 43619585STim.Szeto@Sun.COM "stmfGetLogicalUnitList:" 43629585STim.Szeto@Sun.COM "ioctl errno(%d)", errno); 43639585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 43649585STim.Szeto@Sun.COM break; 43659585STim.Szeto@Sun.COM } 43669585STim.Szeto@Sun.COM goto done; 43679585STim.Szeto@Sun.COM } 43689585STim.Szeto@Sun.COM } 43699585STim.Szeto@Sun.COM 43709585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 43719585STim.Szeto@Sun.COM goto done; 43729585STim.Szeto@Sun.COM } 43739585STim.Szeto@Sun.COM 43749585STim.Szeto@Sun.COM if (stmfIoctl.stmf_obuf_nentries == 0) { 43759585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 43769585STim.Szeto@Sun.COM goto done; 43779585STim.Szeto@Sun.COM } 43789585STim.Szeto@Sun.COM 43799585STim.Szeto@Sun.COM listCnt = stmfIoctl.stmf_obuf_nentries; 43809585STim.Szeto@Sun.COM 43819585STim.Szeto@Sun.COM /* 43829585STim.Szeto@Sun.COM * allocate caller's buffer with the final size 43839585STim.Szeto@Sun.COM */ 43849585STim.Szeto@Sun.COM *viewEntryList = (stmfViewEntryList *)calloc(1, 43859585STim.Szeto@Sun.COM sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry)); 43869585STim.Szeto@Sun.COM if (*viewEntryList == NULL) { 43879585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 43889585STim.Szeto@Sun.COM goto done; 43899585STim.Szeto@Sun.COM } 43909585STim.Szeto@Sun.COM 43919585STim.Szeto@Sun.COM (*viewEntryList)->cnt = listCnt; 43929585STim.Szeto@Sun.COM 43939585STim.Szeto@Sun.COM /* copy to caller's buffer */ 43949585STim.Szeto@Sun.COM for (i = 0; i < listCnt; i++) { 43959585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndexValid = B_TRUE; 43969585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx; 43979585STim.Szeto@Sun.COM if (fVeList[i].ve_all_hosts == 1) { 43989585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allHosts = B_TRUE; 43999585STim.Szeto@Sun.COM } else { 44009585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_host_group.name, 44019585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].hostGroup, 44029585STim.Szeto@Sun.COM fVeList[i].ve_host_group.name_size); 44039585STim.Szeto@Sun.COM } 44049585STim.Szeto@Sun.COM if (fVeList[i].ve_all_targets == 1) { 44059585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].allTargets = B_TRUE; 44069585STim.Szeto@Sun.COM } else { 44079585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_target_group.name, 44089585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].targetGroup, 44099585STim.Szeto@Sun.COM fVeList[i].ve_target_group.name_size); 44109585STim.Szeto@Sun.COM } 44119585STim.Szeto@Sun.COM bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr, 44129585STim.Szeto@Sun.COM sizeof ((*viewEntryList)->ve[i].luNbr)); 44139585STim.Szeto@Sun.COM (*viewEntryList)->ve[i].luNbrValid = B_TRUE; 44149585STim.Szeto@Sun.COM } 44159585STim.Szeto@Sun.COM 44169585STim.Szeto@Sun.COM /* 44179585STim.Szeto@Sun.COM * sort the list. This gives a consistent view across gets 44189585STim.Szeto@Sun.COM */ 44199585STim.Szeto@Sun.COM qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt, 44209585STim.Szeto@Sun.COM sizeof (stmfViewEntry), viewEntryCompare); 44219585STim.Szeto@Sun.COM 44229585STim.Szeto@Sun.COM done: 44239585STim.Szeto@Sun.COM (void) close(fd); 44249585STim.Szeto@Sun.COM /* 44259585STim.Szeto@Sun.COM * free internal buffers 44269585STim.Szeto@Sun.COM */ 44279585STim.Szeto@Sun.COM free(fVeList); 44287836SJohn.Forte@Sun.COM return (ret); 44297836SJohn.Forte@Sun.COM } 44307836SJohn.Forte@Sun.COM 44319585STim.Szeto@Sun.COM 44327836SJohn.Forte@Sun.COM /* 44337836SJohn.Forte@Sun.COM * loadHostGroups 44347836SJohn.Forte@Sun.COM * 44357836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the host groups into stmf 44367836SJohn.Forte@Sun.COM * 44377836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 44387836SJohn.Forte@Sun.COM * groupList - populated host group list 44397836SJohn.Forte@Sun.COM */ 44407836SJohn.Forte@Sun.COM static int 44417836SJohn.Forte@Sun.COM loadHostGroups(int fd, stmfGroupList *groupList) 44427836SJohn.Forte@Sun.COM { 44437836SJohn.Forte@Sun.COM int i, j; 44447836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 44457836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 44467836SJohn.Forte@Sun.COM 44477836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 44487836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP, 44497836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 44507836SJohn.Forte@Sun.COM goto out; 44517836SJohn.Forte@Sun.COM } 44529585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 44539585STim.Szeto@Sun.COM &groupProps, HOST_GROUP); 44547836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 44557836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, 44567836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 44577836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 44587836SJohn.Forte@Sun.COM goto out; 44597836SJohn.Forte@Sun.COM } 44607836SJohn.Forte@Sun.COM } 44617836SJohn.Forte@Sun.COM } 44627836SJohn.Forte@Sun.COM 44637836SJohn.Forte@Sun.COM 44647836SJohn.Forte@Sun.COM out: 44657836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 44667836SJohn.Forte@Sun.COM return (ret); 44677836SJohn.Forte@Sun.COM } 44687836SJohn.Forte@Sun.COM 44697836SJohn.Forte@Sun.COM /* 44707836SJohn.Forte@Sun.COM * loadTargetGroups 44717836SJohn.Forte@Sun.COM * 44727836SJohn.Forte@Sun.COM * Purpose - issues the ioctl to load the target groups into stmf 44737836SJohn.Forte@Sun.COM * 44747836SJohn.Forte@Sun.COM * fd - file descriptor for the control node of stmf. 44757836SJohn.Forte@Sun.COM * groupList - populated target group list. 44767836SJohn.Forte@Sun.COM */ 44777836SJohn.Forte@Sun.COM static int 44787836SJohn.Forte@Sun.COM loadTargetGroups(int fd, stmfGroupList *groupList) 44797836SJohn.Forte@Sun.COM { 44807836SJohn.Forte@Sun.COM int i, j; 44817836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 44827836SJohn.Forte@Sun.COM stmfGroupProperties *groupProps = NULL; 44837836SJohn.Forte@Sun.COM 44847836SJohn.Forte@Sun.COM for (i = 0; i < groupList->cnt; i++) { 44857836SJohn.Forte@Sun.COM if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP, 44867836SJohn.Forte@Sun.COM &(groupList->name[i]))) != STMF_STATUS_SUCCESS) { 44877836SJohn.Forte@Sun.COM goto out; 44887836SJohn.Forte@Sun.COM } 44899585STim.Szeto@Sun.COM ret = iLoadGroupMembersFromPs(&(groupList->name[i]), 44909585STim.Szeto@Sun.COM &groupProps, TARGET_GROUP); 44917836SJohn.Forte@Sun.COM for (j = 0; j < groupProps->cnt; j++) { 44927836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY, 44937836SJohn.Forte@Sun.COM &(groupList->name[i]), &(groupProps->name[j]))) 44947836SJohn.Forte@Sun.COM != STMF_STATUS_SUCCESS) { 44957836SJohn.Forte@Sun.COM goto out; 44967836SJohn.Forte@Sun.COM } 44977836SJohn.Forte@Sun.COM } 44987836SJohn.Forte@Sun.COM } 44997836SJohn.Forte@Sun.COM 45007836SJohn.Forte@Sun.COM 45017836SJohn.Forte@Sun.COM out: 45027836SJohn.Forte@Sun.COM stmfFreeMemory(groupProps); 45037836SJohn.Forte@Sun.COM return (ret); 45047836SJohn.Forte@Sun.COM } 45057836SJohn.Forte@Sun.COM 45067836SJohn.Forte@Sun.COM 45077836SJohn.Forte@Sun.COM /* 45087836SJohn.Forte@Sun.COM * loadStore 45097836SJohn.Forte@Sun.COM * 45107836SJohn.Forte@Sun.COM * Purpose: Load the configuration data from the store 45117836SJohn.Forte@Sun.COM * 45127836SJohn.Forte@Sun.COM * First load the host groups and target groups, then the view entries 45137836SJohn.Forte@Sun.COM * and finally the provider data 45147836SJohn.Forte@Sun.COM * 45157836SJohn.Forte@Sun.COM * fd - file descriptor of control node for stmf. 45167836SJohn.Forte@Sun.COM */ 45177836SJohn.Forte@Sun.COM static int 45187836SJohn.Forte@Sun.COM loadStore(int fd) 45197836SJohn.Forte@Sun.COM { 45207836SJohn.Forte@Sun.COM int ret; 45217836SJohn.Forte@Sun.COM int i, j; 45227836SJohn.Forte@Sun.COM stmfGroupList *groupList = NULL; 45237836SJohn.Forte@Sun.COM stmfGuidList *guidList = NULL; 45247836SJohn.Forte@Sun.COM stmfViewEntryList *viewEntryList = NULL; 45257836SJohn.Forte@Sun.COM stmfProviderList *providerList = NULL; 45267836SJohn.Forte@Sun.COM int providerType; 45277836SJohn.Forte@Sun.COM nvlist_t *nvl = NULL; 45287836SJohn.Forte@Sun.COM 45297836SJohn.Forte@Sun.COM 45307836SJohn.Forte@Sun.COM 45317836SJohn.Forte@Sun.COM /* load host groups */ 45329585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, HOST_GROUP); 45337836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45347836SJohn.Forte@Sun.COM return (ret); 45357836SJohn.Forte@Sun.COM } 45367836SJohn.Forte@Sun.COM ret = loadHostGroups(fd, groupList); 45377836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45387836SJohn.Forte@Sun.COM goto out; 45397836SJohn.Forte@Sun.COM } 45407836SJohn.Forte@Sun.COM 45417836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 45427836SJohn.Forte@Sun.COM groupList = NULL; 45437836SJohn.Forte@Sun.COM 45447836SJohn.Forte@Sun.COM /* load target groups */ 45459585STim.Szeto@Sun.COM ret = iLoadGroupFromPs(&groupList, TARGET_GROUP); 45467836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45477836SJohn.Forte@Sun.COM goto out; 45487836SJohn.Forte@Sun.COM } 45497836SJohn.Forte@Sun.COM ret = loadTargetGroups(fd, groupList); 45507836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45517836SJohn.Forte@Sun.COM goto out; 45527836SJohn.Forte@Sun.COM } 45537836SJohn.Forte@Sun.COM 45547836SJohn.Forte@Sun.COM stmfFreeMemory(groupList); 45557836SJohn.Forte@Sun.COM groupList = NULL; 45567836SJohn.Forte@Sun.COM 45577836SJohn.Forte@Sun.COM /* Get the guid list */ 45587836SJohn.Forte@Sun.COM ret = psGetLogicalUnitList(&guidList); 45597836SJohn.Forte@Sun.COM switch (ret) { 45607836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45617836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45627836SJohn.Forte@Sun.COM break; 45637836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45647836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45657836SJohn.Forte@Sun.COM break; 45667836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45677836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45687836SJohn.Forte@Sun.COM break; 45697836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 45707836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 45717836SJohn.Forte@Sun.COM break; 45727836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 45737836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 45747836SJohn.Forte@Sun.COM break; 45757836SJohn.Forte@Sun.COM default: 45767836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 45777836SJohn.Forte@Sun.COM break; 45787836SJohn.Forte@Sun.COM } 45797836SJohn.Forte@Sun.COM 45807836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 45817836SJohn.Forte@Sun.COM goto out; 45827836SJohn.Forte@Sun.COM } 45837836SJohn.Forte@Sun.COM 45847836SJohn.Forte@Sun.COM /* 45857836SJohn.Forte@Sun.COM * We have the guid list, now get the corresponding 45867836SJohn.Forte@Sun.COM * view entries for each guid 45877836SJohn.Forte@Sun.COM */ 45887836SJohn.Forte@Sun.COM for (i = 0; i < guidList->cnt; i++) { 45897836SJohn.Forte@Sun.COM ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList); 45907836SJohn.Forte@Sun.COM switch (ret) { 45917836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 45927836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 45937836SJohn.Forte@Sun.COM break; 45947836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 45957836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 45967836SJohn.Forte@Sun.COM break; 45977836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 45987836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 45997836SJohn.Forte@Sun.COM break; 46007836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46017836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46027836SJohn.Forte@Sun.COM break; 46037836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46047836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46057836SJohn.Forte@Sun.COM break; 46067836SJohn.Forte@Sun.COM default: 46077836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46087836SJohn.Forte@Sun.COM break; 46097836SJohn.Forte@Sun.COM } 46107836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46117836SJohn.Forte@Sun.COM goto out; 46127836SJohn.Forte@Sun.COM } 46137836SJohn.Forte@Sun.COM for (j = 0; j < viewEntryList->cnt; j++) { 46147836SJohn.Forte@Sun.COM ret = addViewEntryIoctl(fd, &guidList->guid[i], 46157836SJohn.Forte@Sun.COM &viewEntryList->ve[j]); 46167836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46177836SJohn.Forte@Sun.COM goto out; 46187836SJohn.Forte@Sun.COM } 46197836SJohn.Forte@Sun.COM } 46207836SJohn.Forte@Sun.COM } 46217836SJohn.Forte@Sun.COM 46227836SJohn.Forte@Sun.COM /* get the list of providers that have data */ 46237836SJohn.Forte@Sun.COM ret = psGetProviderDataList(&providerList); 46247836SJohn.Forte@Sun.COM switch (ret) { 46257836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 46267836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46277836SJohn.Forte@Sun.COM break; 46287836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 46297836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46307836SJohn.Forte@Sun.COM break; 46317836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 46327836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46337836SJohn.Forte@Sun.COM break; 46347836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46357836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46367836SJohn.Forte@Sun.COM break; 46377836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46387836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46397836SJohn.Forte@Sun.COM break; 46407836SJohn.Forte@Sun.COM default: 46417836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46427836SJohn.Forte@Sun.COM break; 46437836SJohn.Forte@Sun.COM } 46447836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46457836SJohn.Forte@Sun.COM goto out; 46467836SJohn.Forte@Sun.COM } 46477836SJohn.Forte@Sun.COM 46487836SJohn.Forte@Sun.COM for (i = 0; i < providerList->cnt; i++) { 46497836SJohn.Forte@Sun.COM providerType = providerList->provider[i].providerType; 46507836SJohn.Forte@Sun.COM ret = psGetProviderData(providerList->provider[i].name, 46517836SJohn.Forte@Sun.COM &nvl, providerType, NULL); 46527836SJohn.Forte@Sun.COM switch (ret) { 46537836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 46547836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46557836SJohn.Forte@Sun.COM break; 46567836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 46577836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46587836SJohn.Forte@Sun.COM break; 46597836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 46607836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46617836SJohn.Forte@Sun.COM break; 46627836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46637836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46647836SJohn.Forte@Sun.COM break; 46657836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46667836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46677836SJohn.Forte@Sun.COM break; 46687836SJohn.Forte@Sun.COM default: 46697836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46707836SJohn.Forte@Sun.COM break; 46717836SJohn.Forte@Sun.COM } 46727836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 46737836SJohn.Forte@Sun.COM goto out; 46747836SJohn.Forte@Sun.COM } 46757836SJohn.Forte@Sun.COM 46767836SJohn.Forte@Sun.COM /* call setProviderData */ 46777836SJohn.Forte@Sun.COM ret = setProviderData(fd, providerList->provider[i].name, nvl, 46789585STim.Szeto@Sun.COM providerType, NULL); 46797836SJohn.Forte@Sun.COM switch (ret) { 46807836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 46817836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 46827836SJohn.Forte@Sun.COM break; 46837836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 46847836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 46857836SJohn.Forte@Sun.COM break; 46867836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 46877836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 46887836SJohn.Forte@Sun.COM break; 46897836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 46907836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 46917836SJohn.Forte@Sun.COM break; 46927836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 46937836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 46947836SJohn.Forte@Sun.COM break; 46957836SJohn.Forte@Sun.COM default: 46967836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 46977836SJohn.Forte@Sun.COM break; 46987836SJohn.Forte@Sun.COM } 46997836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47007836SJohn.Forte@Sun.COM goto out; 47017836SJohn.Forte@Sun.COM } 47027836SJohn.Forte@Sun.COM 47037836SJohn.Forte@Sun.COM nvlist_free(nvl); 47047836SJohn.Forte@Sun.COM nvl = NULL; 47057836SJohn.Forte@Sun.COM } 47067836SJohn.Forte@Sun.COM out: 47077836SJohn.Forte@Sun.COM if (groupList != NULL) { 47087836SJohn.Forte@Sun.COM free(groupList); 47097836SJohn.Forte@Sun.COM } 47107836SJohn.Forte@Sun.COM if (guidList != NULL) { 47117836SJohn.Forte@Sun.COM free(guidList); 47127836SJohn.Forte@Sun.COM } 47137836SJohn.Forte@Sun.COM if (viewEntryList != NULL) { 47147836SJohn.Forte@Sun.COM free(viewEntryList); 47157836SJohn.Forte@Sun.COM } 47167836SJohn.Forte@Sun.COM if (nvl != NULL) { 47177836SJohn.Forte@Sun.COM nvlist_free(nvl); 47187836SJohn.Forte@Sun.COM } 47197836SJohn.Forte@Sun.COM return (ret); 47207836SJohn.Forte@Sun.COM } 47217836SJohn.Forte@Sun.COM 47227836SJohn.Forte@Sun.COM /* 47237836SJohn.Forte@Sun.COM * stmfLoadConfig 47247836SJohn.Forte@Sun.COM * 47257836SJohn.Forte@Sun.COM * Purpose - load the configuration data from smf into stmf 47267836SJohn.Forte@Sun.COM * 47277836SJohn.Forte@Sun.COM */ 47287836SJohn.Forte@Sun.COM int 47297836SJohn.Forte@Sun.COM stmfLoadConfig(void) 47307836SJohn.Forte@Sun.COM { 47319585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 47327836SJohn.Forte@Sun.COM int fd; 47337836SJohn.Forte@Sun.COM stmf_state_desc_t stmfStateSet; 47347836SJohn.Forte@Sun.COM stmfState state; 47357836SJohn.Forte@Sun.COM 47369585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 47379585STim.Szeto@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 473810560SSusan.Gleeson@Sun.COM 47399585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) 47409585STim.Szeto@Sun.COM != STMF_STATUS_SUCCESS) { 47419585STim.Szeto@Sun.COM return (ret); 47429585STim.Szeto@Sun.COM } 474310560SSusan.Gleeson@Sun.COM /* 474410560SSusan.Gleeson@Sun.COM * Configuration not stored persistently; nothing to 474510560SSusan.Gleeson@Sun.COM * initialize so do not set to STMF_CONFIG_INIT. 474610560SSusan.Gleeson@Sun.COM */ 47479585STim.Szeto@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 47489585STim.Szeto@Sun.COM goto done; 47499585STim.Szeto@Sun.COM } 47507836SJohn.Forte@Sun.COM 47517836SJohn.Forte@Sun.COM /* Check to ensure service exists */ 47527836SJohn.Forte@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 47537836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 47547836SJohn.Forte@Sun.COM } 47557836SJohn.Forte@Sun.COM 47567836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 47577836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 47587836SJohn.Forte@Sun.COM if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) { 47597836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 47607836SJohn.Forte@Sun.COM } 47617836SJohn.Forte@Sun.COM } else { 47627836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 47637836SJohn.Forte@Sun.COM } 47647836SJohn.Forte@Sun.COM 47657836SJohn.Forte@Sun.COM 47667836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 47677836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT; 47687836SJohn.Forte@Sun.COM 47697836SJohn.Forte@Sun.COM /* 47707836SJohn.Forte@Sun.COM * Open control node for stmf 47717836SJohn.Forte@Sun.COM */ 47727836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 47737836SJohn.Forte@Sun.COM return (ret); 47747836SJohn.Forte@Sun.COM 47757836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 47767836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 47777836SJohn.Forte@Sun.COM goto done; 47787836SJohn.Forte@Sun.COM } 47797836SJohn.Forte@Sun.COM 47807836SJohn.Forte@Sun.COM /* Load the persistent configuration data */ 47817836SJohn.Forte@Sun.COM ret = loadStore(fd); 47827836SJohn.Forte@Sun.COM if (ret != 0) { 47837836SJohn.Forte@Sun.COM goto done; 47847836SJohn.Forte@Sun.COM } 47857836SJohn.Forte@Sun.COM 47867836SJohn.Forte@Sun.COM stmfStateSet.state = STMF_STATE_OFFLINE; 47877836SJohn.Forte@Sun.COM stmfStateSet.config_state = STMF_CONFIG_INIT_DONE; 47887836SJohn.Forte@Sun.COM 47897836SJohn.Forte@Sun.COM done: 47907836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 47917836SJohn.Forte@Sun.COM ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE); 47927836SJohn.Forte@Sun.COM } 47937836SJohn.Forte@Sun.COM (void) close(fd); 47947836SJohn.Forte@Sun.COM return (ret); 47957836SJohn.Forte@Sun.COM } 47967836SJohn.Forte@Sun.COM 47979585STim.Szeto@Sun.COM 47987836SJohn.Forte@Sun.COM /* 47997836SJohn.Forte@Sun.COM * getStmfState 48007836SJohn.Forte@Sun.COM * 48017836SJohn.Forte@Sun.COM * stmfState - pointer to stmf_state_desc_t structure. Will contain the state 48027836SJohn.Forte@Sun.COM * information of the stmf service on success. 48037836SJohn.Forte@Sun.COM */ 48047836SJohn.Forte@Sun.COM static int 48057836SJohn.Forte@Sun.COM getStmfState(stmf_state_desc_t *stmfState) 48067836SJohn.Forte@Sun.COM { 48077836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 48087836SJohn.Forte@Sun.COM int fd; 48097836SJohn.Forte@Sun.COM int ioctlRet; 48107836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 48117836SJohn.Forte@Sun.COM 48127836SJohn.Forte@Sun.COM /* 48137836SJohn.Forte@Sun.COM * Open control node for stmf 48147836SJohn.Forte@Sun.COM */ 48157836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 48167836SJohn.Forte@Sun.COM return (ret); 48177836SJohn.Forte@Sun.COM 48187836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 48197836SJohn.Forte@Sun.COM /* 48207836SJohn.Forte@Sun.COM * Issue ioctl to get the stmf state 48217836SJohn.Forte@Sun.COM */ 48227836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 48237836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 48247836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 48257836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t); 48267836SJohn.Forte@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState; 48277836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl); 48287836SJohn.Forte@Sun.COM 48297836SJohn.Forte@Sun.COM (void) close(fd); 48307836SJohn.Forte@Sun.COM 48317836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 48327836SJohn.Forte@Sun.COM switch (errno) { 48337836SJohn.Forte@Sun.COM case EBUSY: 48347836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48357836SJohn.Forte@Sun.COM break; 48367836SJohn.Forte@Sun.COM case EPERM: 48377836SJohn.Forte@Sun.COM case EACCES: 48387836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 48397836SJohn.Forte@Sun.COM break; 48407836SJohn.Forte@Sun.COM default: 48417836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 48427836SJohn.Forte@Sun.COM "getStmfState:ioctl errno(%d)", errno); 48437836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48447836SJohn.Forte@Sun.COM break; 48457836SJohn.Forte@Sun.COM } 48467836SJohn.Forte@Sun.COM } 48477836SJohn.Forte@Sun.COM return (ret); 48487836SJohn.Forte@Sun.COM } 48497836SJohn.Forte@Sun.COM 48507836SJohn.Forte@Sun.COM 48517836SJohn.Forte@Sun.COM /* 48527836SJohn.Forte@Sun.COM * setStmfState 48537836SJohn.Forte@Sun.COM * 48547836SJohn.Forte@Sun.COM * stmfState - pointer to caller set state structure 48557836SJohn.Forte@Sun.COM * objectType - one of: 48567836SJohn.Forte@Sun.COM * LOGICAL_UNIT_TYPE 48577836SJohn.Forte@Sun.COM * TARGET_TYPE 48587836SJohn.Forte@Sun.COM * STMF_SERVICE_TYPE 48597836SJohn.Forte@Sun.COM */ 48607836SJohn.Forte@Sun.COM static int 48617836SJohn.Forte@Sun.COM setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType) 48627836SJohn.Forte@Sun.COM { 48637836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 48647836SJohn.Forte@Sun.COM int ioctlRet; 48657836SJohn.Forte@Sun.COM int cmd; 48667836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 48677836SJohn.Forte@Sun.COM 48687836SJohn.Forte@Sun.COM switch (objectType) { 48697836SJohn.Forte@Sun.COM case LOGICAL_UNIT_TYPE: 48707836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_LU_STATE; 48717836SJohn.Forte@Sun.COM break; 48727836SJohn.Forte@Sun.COM case TARGET_TYPE: 48737836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_TARGET_PORT_STATE; 48747836SJohn.Forte@Sun.COM break; 48757836SJohn.Forte@Sun.COM case STMF_SERVICE_TYPE: 48767836SJohn.Forte@Sun.COM cmd = STMF_IOCTL_SET_STMF_STATE; 48777836SJohn.Forte@Sun.COM break; 48787836SJohn.Forte@Sun.COM default: 48797836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 48807836SJohn.Forte@Sun.COM goto done; 48817836SJohn.Forte@Sun.COM } 48827836SJohn.Forte@Sun.COM 48837836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 48847836SJohn.Forte@Sun.COM /* 48857836SJohn.Forte@Sun.COM * Issue ioctl to set the stmf state 48867836SJohn.Forte@Sun.COM */ 48877836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 48887836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t); 48897836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState; 48907836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, cmd, &stmfIoctl); 48917836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 48927836SJohn.Forte@Sun.COM switch (errno) { 48937836SJohn.Forte@Sun.COM case EBUSY: 48947836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 48957836SJohn.Forte@Sun.COM break; 48969585STim.Szeto@Sun.COM case EPERM: 48977836SJohn.Forte@Sun.COM case EACCES: 48987836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 48997836SJohn.Forte@Sun.COM break; 49007836SJohn.Forte@Sun.COM case ENOENT: 49017836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 49027836SJohn.Forte@Sun.COM break; 49037836SJohn.Forte@Sun.COM default: 49047836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 49057836SJohn.Forte@Sun.COM "setStmfState:ioctl errno(%d)", errno); 49067836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 49077836SJohn.Forte@Sun.COM break; 49087836SJohn.Forte@Sun.COM } 49097836SJohn.Forte@Sun.COM } 49107836SJohn.Forte@Sun.COM done: 49117836SJohn.Forte@Sun.COM return (ret); 49127836SJohn.Forte@Sun.COM } 49137836SJohn.Forte@Sun.COM 49147836SJohn.Forte@Sun.COM /* 49157836SJohn.Forte@Sun.COM * stmfOnline 49167836SJohn.Forte@Sun.COM * 49177836SJohn.Forte@Sun.COM * Purpose: Online stmf service 49187836SJohn.Forte@Sun.COM * 49197836SJohn.Forte@Sun.COM */ 49207836SJohn.Forte@Sun.COM int 49217836SJohn.Forte@Sun.COM stmfOnline(void) 49227836SJohn.Forte@Sun.COM { 49237836SJohn.Forte@Sun.COM int ret; 49247836SJohn.Forte@Sun.COM int fd; 49257836SJohn.Forte@Sun.COM stmfState state; 49267836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 49277836SJohn.Forte@Sun.COM 49287836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 49297836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 49307836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_ONLINE) { 49317836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_ONLINE); 49327836SJohn.Forte@Sun.COM } 49337836SJohn.Forte@Sun.COM } else { 49347836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 49357836SJohn.Forte@Sun.COM } 49367836SJohn.Forte@Sun.COM iState.state = STMF_STATE_ONLINE; 49377836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 49387836SJohn.Forte@Sun.COM /* 49397836SJohn.Forte@Sun.COM * Open control node for stmf 49407836SJohn.Forte@Sun.COM * to make call to setStmfState() 49417836SJohn.Forte@Sun.COM */ 49427836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49437836SJohn.Forte@Sun.COM return (ret); 49447836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 49457836SJohn.Forte@Sun.COM (void) close(fd); 49467836SJohn.Forte@Sun.COM return (ret); 49477836SJohn.Forte@Sun.COM } 49487836SJohn.Forte@Sun.COM 49497836SJohn.Forte@Sun.COM /* 49507836SJohn.Forte@Sun.COM * stmfOffline 49517836SJohn.Forte@Sun.COM * 49527836SJohn.Forte@Sun.COM * Purpose: Offline stmf service 49537836SJohn.Forte@Sun.COM * 49547836SJohn.Forte@Sun.COM */ 49557836SJohn.Forte@Sun.COM int 49567836SJohn.Forte@Sun.COM stmfOffline(void) 49577836SJohn.Forte@Sun.COM { 49587836SJohn.Forte@Sun.COM int ret; 49597836SJohn.Forte@Sun.COM int fd; 49607836SJohn.Forte@Sun.COM stmfState state; 49617836SJohn.Forte@Sun.COM stmf_state_desc_t iState; 49627836SJohn.Forte@Sun.COM 49637836SJohn.Forte@Sun.COM ret = stmfGetState(&state); 49647836SJohn.Forte@Sun.COM if (ret == STMF_STATUS_SUCCESS) { 49657836SJohn.Forte@Sun.COM if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) { 49667836SJohn.Forte@Sun.COM return (STMF_ERROR_SERVICE_OFFLINE); 49677836SJohn.Forte@Sun.COM } 49687836SJohn.Forte@Sun.COM } else { 49697836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 49707836SJohn.Forte@Sun.COM } 49717836SJohn.Forte@Sun.COM iState.state = STMF_STATE_OFFLINE; 49727836SJohn.Forte@Sun.COM iState.config_state = STMF_CONFIG_NONE; 49737836SJohn.Forte@Sun.COM 49747836SJohn.Forte@Sun.COM /* 49757836SJohn.Forte@Sun.COM * Open control node for stmf 49767836SJohn.Forte@Sun.COM * to make call to setStmfState() 49777836SJohn.Forte@Sun.COM */ 49787836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 49797836SJohn.Forte@Sun.COM return (ret); 49807836SJohn.Forte@Sun.COM ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE); 49817836SJohn.Forte@Sun.COM (void) close(fd); 49827836SJohn.Forte@Sun.COM return (ret); 49837836SJohn.Forte@Sun.COM } 49847836SJohn.Forte@Sun.COM 49857836SJohn.Forte@Sun.COM 49867836SJohn.Forte@Sun.COM /* 49877836SJohn.Forte@Sun.COM * stmfOfflineTarget 49887836SJohn.Forte@Sun.COM * 49897836SJohn.Forte@Sun.COM * Purpose: Change state of target to offline 49907836SJohn.Forte@Sun.COM * 49917836SJohn.Forte@Sun.COM * devid - devid of the target to offline 49927836SJohn.Forte@Sun.COM */ 49937836SJohn.Forte@Sun.COM int 49947836SJohn.Forte@Sun.COM stmfOfflineTarget(stmfDevid *devid) 49957836SJohn.Forte@Sun.COM { 49967836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 49977836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 49987836SJohn.Forte@Sun.COM int fd; 49997836SJohn.Forte@Sun.COM 50007836SJohn.Forte@Sun.COM if (devid == NULL) { 50017836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50027836SJohn.Forte@Sun.COM } 50037836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 50047836SJohn.Forte@Sun.COM 50057836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_OFFLINE; 50067836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 50077836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 50087836SJohn.Forte@Sun.COM devid->identLength); 50097836SJohn.Forte@Sun.COM /* 50107836SJohn.Forte@Sun.COM * Open control node for stmf 50117836SJohn.Forte@Sun.COM * to make call to setStmfState() 50127836SJohn.Forte@Sun.COM */ 50137836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50147836SJohn.Forte@Sun.COM return (ret); 50157836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 50167836SJohn.Forte@Sun.COM (void) close(fd); 50177836SJohn.Forte@Sun.COM return (ret); 50187836SJohn.Forte@Sun.COM } 50197836SJohn.Forte@Sun.COM 50207836SJohn.Forte@Sun.COM /* 50217836SJohn.Forte@Sun.COM * stmfOfflineLogicalUnit 50227836SJohn.Forte@Sun.COM * 50237836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to offline 50247836SJohn.Forte@Sun.COM * 50257836SJohn.Forte@Sun.COM * lu - guid of the logical unit to offline 50267836SJohn.Forte@Sun.COM */ 50277836SJohn.Forte@Sun.COM int 50287836SJohn.Forte@Sun.COM stmfOfflineLogicalUnit(stmfGuid *lu) 50297836SJohn.Forte@Sun.COM { 50307836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 50317836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50327836SJohn.Forte@Sun.COM int fd; 50337836SJohn.Forte@Sun.COM 50347836SJohn.Forte@Sun.COM if (lu == NULL) { 50357836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50367836SJohn.Forte@Sun.COM } 50377836SJohn.Forte@Sun.COM 50387836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 50397836SJohn.Forte@Sun.COM 50407836SJohn.Forte@Sun.COM luState.state = STMF_STATE_OFFLINE; 50417836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 50427836SJohn.Forte@Sun.COM /* 50437836SJohn.Forte@Sun.COM * Open control node for stmf 50447836SJohn.Forte@Sun.COM * to make call to setStmfState() 50457836SJohn.Forte@Sun.COM */ 50467836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50477836SJohn.Forte@Sun.COM return (ret); 50487836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 50497836SJohn.Forte@Sun.COM (void) close(fd); 50507836SJohn.Forte@Sun.COM return (ret); 50517836SJohn.Forte@Sun.COM } 50527836SJohn.Forte@Sun.COM 50537836SJohn.Forte@Sun.COM /* 50547836SJohn.Forte@Sun.COM * stmfOnlineTarget 50557836SJohn.Forte@Sun.COM * 50567836SJohn.Forte@Sun.COM * Purpose: Change state of target to online 50577836SJohn.Forte@Sun.COM * 50587836SJohn.Forte@Sun.COM * devid - devid of the target to online 50597836SJohn.Forte@Sun.COM */ 50607836SJohn.Forte@Sun.COM int 50617836SJohn.Forte@Sun.COM stmfOnlineTarget(stmfDevid *devid) 50627836SJohn.Forte@Sun.COM { 50637836SJohn.Forte@Sun.COM stmf_state_desc_t targetState; 50647836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50657836SJohn.Forte@Sun.COM int fd; 50667836SJohn.Forte@Sun.COM 50677836SJohn.Forte@Sun.COM if (devid == NULL) { 50687836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 50697836SJohn.Forte@Sun.COM } 50707836SJohn.Forte@Sun.COM bzero(&targetState, sizeof (targetState)); 50717836SJohn.Forte@Sun.COM 50727836SJohn.Forte@Sun.COM targetState.state = STMF_STATE_ONLINE; 50737836SJohn.Forte@Sun.COM targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength; 50747836SJohn.Forte@Sun.COM bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1], 50757836SJohn.Forte@Sun.COM devid->identLength); 50767836SJohn.Forte@Sun.COM /* 50777836SJohn.Forte@Sun.COM * Open control node for stmf 50787836SJohn.Forte@Sun.COM * to make call to setStmfState() 50797836SJohn.Forte@Sun.COM */ 50807836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 50817836SJohn.Forte@Sun.COM return (ret); 50827836SJohn.Forte@Sun.COM ret = setStmfState(fd, &targetState, TARGET_TYPE); 50837836SJohn.Forte@Sun.COM (void) close(fd); 50847836SJohn.Forte@Sun.COM return (ret); 50857836SJohn.Forte@Sun.COM } 50867836SJohn.Forte@Sun.COM 50877836SJohn.Forte@Sun.COM /* 50887836SJohn.Forte@Sun.COM * stmfOnlineLogicalUnit 50897836SJohn.Forte@Sun.COM * 50907836SJohn.Forte@Sun.COM * Purpose: Change state of logical unit to online 50917836SJohn.Forte@Sun.COM * 50927836SJohn.Forte@Sun.COM * lu - guid of the logical unit to online 50937836SJohn.Forte@Sun.COM */ 50947836SJohn.Forte@Sun.COM int 50957836SJohn.Forte@Sun.COM stmfOnlineLogicalUnit(stmfGuid *lu) 50967836SJohn.Forte@Sun.COM { 50977836SJohn.Forte@Sun.COM stmf_state_desc_t luState; 50987836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 50997836SJohn.Forte@Sun.COM int fd; 51007836SJohn.Forte@Sun.COM 51017836SJohn.Forte@Sun.COM if (lu == NULL) { 51027836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 51037836SJohn.Forte@Sun.COM } 51047836SJohn.Forte@Sun.COM 51057836SJohn.Forte@Sun.COM bzero(&luState, sizeof (luState)); 51067836SJohn.Forte@Sun.COM 51077836SJohn.Forte@Sun.COM luState.state = STMF_STATE_ONLINE; 51087836SJohn.Forte@Sun.COM bcopy(lu, &luState.ident, sizeof (stmfGuid)); 51097836SJohn.Forte@Sun.COM /* 51107836SJohn.Forte@Sun.COM * Open control node for stmf 51117836SJohn.Forte@Sun.COM * to make call to setStmfState() 51127836SJohn.Forte@Sun.COM */ 51137836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS) 51147836SJohn.Forte@Sun.COM return (ret); 51157836SJohn.Forte@Sun.COM ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE); 51167836SJohn.Forte@Sun.COM (void) close(fd); 51177836SJohn.Forte@Sun.COM return (ret); 51187836SJohn.Forte@Sun.COM } 51197836SJohn.Forte@Sun.COM 51207836SJohn.Forte@Sun.COM /* 51217836SJohn.Forte@Sun.COM * stmfRemoveFromHostGroup 51227836SJohn.Forte@Sun.COM * 51237836SJohn.Forte@Sun.COM * Purpose: Removes an initiator from an initiator group 51247836SJohn.Forte@Sun.COM * 51257836SJohn.Forte@Sun.COM * hostGroupName - name of an initiator group 51267836SJohn.Forte@Sun.COM * hostName - name of host group member to remove 51277836SJohn.Forte@Sun.COM */ 51287836SJohn.Forte@Sun.COM int 51297836SJohn.Forte@Sun.COM stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName) 51307836SJohn.Forte@Sun.COM { 51317836SJohn.Forte@Sun.COM int ret; 51327836SJohn.Forte@Sun.COM int fd; 51337836SJohn.Forte@Sun.COM 51347836SJohn.Forte@Sun.COM if (hostGroupName == NULL || 51357836SJohn.Forte@Sun.COM (strnlen((char *)hostGroupName, sizeof (stmfGroupName)) 51367836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || hostName == NULL) { 51377836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 51387836SJohn.Forte@Sun.COM } 51397836SJohn.Forte@Sun.COM 51407836SJohn.Forte@Sun.COM /* call init */ 51417836SJohn.Forte@Sun.COM ret = initializeConfig(); 51427836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 51437836SJohn.Forte@Sun.COM return (ret); 51447836SJohn.Forte@Sun.COM } 51457836SJohn.Forte@Sun.COM 51467836SJohn.Forte@Sun.COM /* 51477836SJohn.Forte@Sun.COM * Open control node for stmf 51487836SJohn.Forte@Sun.COM */ 51497836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 51507836SJohn.Forte@Sun.COM return (ret); 51517836SJohn.Forte@Sun.COM 51527836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY, 51537836SJohn.Forte@Sun.COM hostGroupName, hostName)) != STMF_STATUS_SUCCESS) { 51547836SJohn.Forte@Sun.COM goto done; 51557836SJohn.Forte@Sun.COM } 51567836SJohn.Forte@Sun.COM 51579585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 51589585STim.Szeto@Sun.COM goto done; 51599585STim.Szeto@Sun.COM } 51609585STim.Szeto@Sun.COM 51617836SJohn.Forte@Sun.COM ret = psRemoveHostGroupMember((char *)hostGroupName, 51627836SJohn.Forte@Sun.COM (char *)hostName->ident); 51637836SJohn.Forte@Sun.COM switch (ret) { 51647836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 51657836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 51667836SJohn.Forte@Sun.COM break; 51677836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 51687836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 51697836SJohn.Forte@Sun.COM break; 51707836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 51717836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 51727836SJohn.Forte@Sun.COM break; 51737836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 51747836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 51757836SJohn.Forte@Sun.COM break; 51767836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 51777836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 51787836SJohn.Forte@Sun.COM break; 51797836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 51807836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 51817836SJohn.Forte@Sun.COM break; 51827836SJohn.Forte@Sun.COM default: 51837836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 51847836SJohn.Forte@Sun.COM "stmfRemoveFromHostGroup" 51857836SJohn.Forte@Sun.COM "psRemoveHostGroupMember:error(%d)", ret); 51867836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 51877836SJohn.Forte@Sun.COM break; 51887836SJohn.Forte@Sun.COM } 51897836SJohn.Forte@Sun.COM 51907836SJohn.Forte@Sun.COM done: 51917836SJohn.Forte@Sun.COM (void) close(fd); 51927836SJohn.Forte@Sun.COM return (ret); 51937836SJohn.Forte@Sun.COM } 51947836SJohn.Forte@Sun.COM 51957836SJohn.Forte@Sun.COM /* 51967836SJohn.Forte@Sun.COM * stmfRemoveFromTargetGroup 51977836SJohn.Forte@Sun.COM * 51987836SJohn.Forte@Sun.COM * Purpose: Removes a local port from a local port group 51997836SJohn.Forte@Sun.COM * 52007836SJohn.Forte@Sun.COM * targetGroupName - name of a target group 52017836SJohn.Forte@Sun.COM * targetName - name of target to remove 52027836SJohn.Forte@Sun.COM */ 52037836SJohn.Forte@Sun.COM int 52047836SJohn.Forte@Sun.COM stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName) 52057836SJohn.Forte@Sun.COM { 52067836SJohn.Forte@Sun.COM int ret; 52077836SJohn.Forte@Sun.COM int fd; 52087836SJohn.Forte@Sun.COM 52097836SJohn.Forte@Sun.COM if (targetGroupName == NULL || 52107836SJohn.Forte@Sun.COM (strnlen((char *)targetGroupName, sizeof (stmfGroupName)) 52117836SJohn.Forte@Sun.COM == sizeof (stmfGroupName)) || targetName == NULL) { 52127836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 52137836SJohn.Forte@Sun.COM } 52147836SJohn.Forte@Sun.COM 52157836SJohn.Forte@Sun.COM /* call init */ 52167836SJohn.Forte@Sun.COM ret = initializeConfig(); 52177836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 52187836SJohn.Forte@Sun.COM return (ret); 52197836SJohn.Forte@Sun.COM } 52207836SJohn.Forte@Sun.COM 52217836SJohn.Forte@Sun.COM /* 52227836SJohn.Forte@Sun.COM * Open control node for stmf 52237836SJohn.Forte@Sun.COM */ 52247836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 52257836SJohn.Forte@Sun.COM return (ret); 52267836SJohn.Forte@Sun.COM 52277836SJohn.Forte@Sun.COM if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY, 52287836SJohn.Forte@Sun.COM targetGroupName, targetName)) != STMF_STATUS_SUCCESS) { 52297836SJohn.Forte@Sun.COM goto done; 52307836SJohn.Forte@Sun.COM } 52317836SJohn.Forte@Sun.COM 52329585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 52339585STim.Szeto@Sun.COM goto done; 52349585STim.Szeto@Sun.COM } 52359585STim.Szeto@Sun.COM 52367836SJohn.Forte@Sun.COM ret = psRemoveTargetGroupMember((char *)targetGroupName, 52377836SJohn.Forte@Sun.COM (char *)targetName->ident); 52387836SJohn.Forte@Sun.COM switch (ret) { 52397836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 52407836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 52417836SJohn.Forte@Sun.COM break; 52427836SJohn.Forte@Sun.COM case STMF_PS_ERROR_MEMBER_NOT_FOUND: 52437836SJohn.Forte@Sun.COM ret = STMF_ERROR_MEMBER_NOT_FOUND; 52447836SJohn.Forte@Sun.COM break; 52457836SJohn.Forte@Sun.COM case STMF_PS_ERROR_GROUP_NOT_FOUND: 52467836SJohn.Forte@Sun.COM ret = STMF_ERROR_GROUP_NOT_FOUND; 52477836SJohn.Forte@Sun.COM break; 52487836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 52497836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 52507836SJohn.Forte@Sun.COM break; 52517836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 52527836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 52537836SJohn.Forte@Sun.COM break; 52547836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 52557836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 52567836SJohn.Forte@Sun.COM break; 52577836SJohn.Forte@Sun.COM default: 52587836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 52597836SJohn.Forte@Sun.COM "stmfRemoveFromTargetGroup" 52607836SJohn.Forte@Sun.COM "psRemoveTargetGroupMember:error(%d)", ret); 52617836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 52627836SJohn.Forte@Sun.COM break; 52637836SJohn.Forte@Sun.COM } 52647836SJohn.Forte@Sun.COM 52657836SJohn.Forte@Sun.COM done: 52667836SJohn.Forte@Sun.COM (void) close(fd); 52677836SJohn.Forte@Sun.COM return (ret); 52687836SJohn.Forte@Sun.COM } 52697836SJohn.Forte@Sun.COM 52707836SJohn.Forte@Sun.COM /* 52717836SJohn.Forte@Sun.COM * stmfRemoveViewEntry 52727836SJohn.Forte@Sun.COM * 52737836SJohn.Forte@Sun.COM * Purpose: Removes a view entry from a logical unit 52747836SJohn.Forte@Sun.COM * 52757836SJohn.Forte@Sun.COM * lu - guid of lu for which view entry is being removed 52767836SJohn.Forte@Sun.COM * viewEntryIndex - index of view entry to remove 52777836SJohn.Forte@Sun.COM * 52787836SJohn.Forte@Sun.COM */ 52797836SJohn.Forte@Sun.COM int 52807836SJohn.Forte@Sun.COM stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex) 52817836SJohn.Forte@Sun.COM { 52827836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 52837836SJohn.Forte@Sun.COM int fd; 52847836SJohn.Forte@Sun.COM int ioctlRet; 52857836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 52867836SJohn.Forte@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 52877836SJohn.Forte@Sun.COM 52887836SJohn.Forte@Sun.COM if (lu == NULL) { 52897836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 52907836SJohn.Forte@Sun.COM } 52917836SJohn.Forte@Sun.COM 52927836SJohn.Forte@Sun.COM /* call init */ 52937836SJohn.Forte@Sun.COM ret = initializeConfig(); 52947836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 52957836SJohn.Forte@Sun.COM return (ret); 52967836SJohn.Forte@Sun.COM } 52977836SJohn.Forte@Sun.COM 52987836SJohn.Forte@Sun.COM /* 52997836SJohn.Forte@Sun.COM * Open control node for stmf 53007836SJohn.Forte@Sun.COM */ 53017836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 53027836SJohn.Forte@Sun.COM return (ret); 53037836SJohn.Forte@Sun.COM 53047836SJohn.Forte@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 53057836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx_valid = B_TRUE; 53067836SJohn.Forte@Sun.COM ioctlViewEntry.ve_ndx = viewEntryIndex; 53077836SJohn.Forte@Sun.COM bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid)); 53087836SJohn.Forte@Sun.COM 53097836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 53107836SJohn.Forte@Sun.COM /* 53117836SJohn.Forte@Sun.COM * Issue ioctl to add to the view entry 53127836SJohn.Forte@Sun.COM */ 53137836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 53147836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 53157836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 53167836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl); 53177836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 53187836SJohn.Forte@Sun.COM switch (errno) { 53197836SJohn.Forte@Sun.COM case EBUSY: 53207836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 53217836SJohn.Forte@Sun.COM break; 53229585STim.Szeto@Sun.COM case EPERM: 53239585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 53249585STim.Szeto@Sun.COM break; 53257836SJohn.Forte@Sun.COM case EACCES: 53267836SJohn.Forte@Sun.COM switch (stmfIoctl.stmf_error) { 53277836SJohn.Forte@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 53287836SJohn.Forte@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 53297836SJohn.Forte@Sun.COM break; 53307836SJohn.Forte@Sun.COM default: 53317836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 53327836SJohn.Forte@Sun.COM break; 53337836SJohn.Forte@Sun.COM } 53347836SJohn.Forte@Sun.COM break; 53357836SJohn.Forte@Sun.COM case ENODEV: 53367836SJohn.Forte@Sun.COM case ENOENT: 53377836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 53387836SJohn.Forte@Sun.COM break; 53397836SJohn.Forte@Sun.COM default: 53407836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 53417836SJohn.Forte@Sun.COM "stmfRemoveViewEntry:ioctl errno(%d)", 53427836SJohn.Forte@Sun.COM errno); 53437836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 53447836SJohn.Forte@Sun.COM break; 53457836SJohn.Forte@Sun.COM } 53467836SJohn.Forte@Sun.COM goto done; 53477836SJohn.Forte@Sun.COM } 53487836SJohn.Forte@Sun.COM 53499585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 53509585STim.Szeto@Sun.COM goto done; 53519585STim.Szeto@Sun.COM } 53529585STim.Szeto@Sun.COM 53537836SJohn.Forte@Sun.COM ret = psRemoveViewEntry(lu, viewEntryIndex); 53547836SJohn.Forte@Sun.COM switch (ret) { 53557836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 53567836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 53577836SJohn.Forte@Sun.COM break; 53587836SJohn.Forte@Sun.COM case STMF_PS_ERROR_NOT_FOUND: 53597836SJohn.Forte@Sun.COM ret = STMF_ERROR_NOT_FOUND; 53607836SJohn.Forte@Sun.COM break; 53617836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 53627836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 53637836SJohn.Forte@Sun.COM break; 53647836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 53657836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 53667836SJohn.Forte@Sun.COM break; 53677836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 53687836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 53697836SJohn.Forte@Sun.COM break; 53707836SJohn.Forte@Sun.COM default: 53717836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 53727836SJohn.Forte@Sun.COM "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)", 53737836SJohn.Forte@Sun.COM ret); 53747836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 53757836SJohn.Forte@Sun.COM break; 53767836SJohn.Forte@Sun.COM } 53777836SJohn.Forte@Sun.COM 53787836SJohn.Forte@Sun.COM done: 53797836SJohn.Forte@Sun.COM (void) close(fd); 53807836SJohn.Forte@Sun.COM return (ret); 53817836SJohn.Forte@Sun.COM } 53827836SJohn.Forte@Sun.COM 53837836SJohn.Forte@Sun.COM /* 53847836SJohn.Forte@Sun.COM * stmfSetProviderData 53857836SJohn.Forte@Sun.COM * 53867836SJohn.Forte@Sun.COM * Purpose: set the provider data 53877836SJohn.Forte@Sun.COM * 53887836SJohn.Forte@Sun.COM * providerName - unique name of provider 53897836SJohn.Forte@Sun.COM * nvl - nvlist to set 53907836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 53917836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 53927836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 53937836SJohn.Forte@Sun.COM */ 53947836SJohn.Forte@Sun.COM int 53957836SJohn.Forte@Sun.COM stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType) 53967836SJohn.Forte@Sun.COM { 53977836SJohn.Forte@Sun.COM return (stmfSetProviderDataProt(providerName, nvl, providerType, 53987836SJohn.Forte@Sun.COM NULL)); 53997836SJohn.Forte@Sun.COM } 54007836SJohn.Forte@Sun.COM 54017836SJohn.Forte@Sun.COM /* 54027836SJohn.Forte@Sun.COM * stmfSetProviderDataProt 54037836SJohn.Forte@Sun.COM * 54047836SJohn.Forte@Sun.COM * Purpose: set the provider data 54057836SJohn.Forte@Sun.COM * 54067836SJohn.Forte@Sun.COM * providerName - unique name of provider 54077836SJohn.Forte@Sun.COM * nvl - nvlist to set 54087836SJohn.Forte@Sun.COM * providerType - type of provider for which to set data 54097836SJohn.Forte@Sun.COM * STMF_LU_PROVIDER_TYPE 54107836SJohn.Forte@Sun.COM * STMF_PORT_PROVIDER_TYPE 54117836SJohn.Forte@Sun.COM * setToken - Stale data token returned in the stmfGetProviderDataProt() 54127836SJohn.Forte@Sun.COM * call or NULL. 54137836SJohn.Forte@Sun.COM */ 54147836SJohn.Forte@Sun.COM int 54157836SJohn.Forte@Sun.COM stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType, 54167836SJohn.Forte@Sun.COM uint64_t *setToken) 54177836SJohn.Forte@Sun.COM { 54187836SJohn.Forte@Sun.COM int ret; 54197836SJohn.Forte@Sun.COM int fd; 54207836SJohn.Forte@Sun.COM 54217836SJohn.Forte@Sun.COM if (providerName == NULL || nvl == NULL) { 54227836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 54237836SJohn.Forte@Sun.COM } 54247836SJohn.Forte@Sun.COM 54257836SJohn.Forte@Sun.COM if (providerType != STMF_LU_PROVIDER_TYPE && 54267836SJohn.Forte@Sun.COM providerType != STMF_PORT_PROVIDER_TYPE) { 54277836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 54287836SJohn.Forte@Sun.COM } 54297836SJohn.Forte@Sun.COM 54307836SJohn.Forte@Sun.COM /* call init */ 54317836SJohn.Forte@Sun.COM ret = initializeConfig(); 54327836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 54337836SJohn.Forte@Sun.COM return (ret); 54347836SJohn.Forte@Sun.COM } 54357836SJohn.Forte@Sun.COM 54367836SJohn.Forte@Sun.COM /* 54377836SJohn.Forte@Sun.COM * Open control node for stmf 54387836SJohn.Forte@Sun.COM */ 54397836SJohn.Forte@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 54407836SJohn.Forte@Sun.COM return (ret); 54417836SJohn.Forte@Sun.COM 54429585STim.Szeto@Sun.COM ret = setProviderData(fd, providerName, nvl, providerType, setToken); 54437836SJohn.Forte@Sun.COM 54447836SJohn.Forte@Sun.COM (void) close(fd); 54457836SJohn.Forte@Sun.COM 54467836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 54477836SJohn.Forte@Sun.COM goto done; 54487836SJohn.Forte@Sun.COM } 54497836SJohn.Forte@Sun.COM 54509585STim.Szeto@Sun.COM if (iGetPersistMethod() == STMF_PERSIST_NONE) { 54519585STim.Szeto@Sun.COM goto done; 54529585STim.Szeto@Sun.COM } 54539585STim.Szeto@Sun.COM 54547836SJohn.Forte@Sun.COM /* setting driver provider data successful. Now persist it */ 54559585STim.Szeto@Sun.COM ret = psSetProviderData(providerName, nvl, providerType, NULL); 54567836SJohn.Forte@Sun.COM switch (ret) { 54577836SJohn.Forte@Sun.COM case STMF_PS_SUCCESS: 54587836SJohn.Forte@Sun.COM ret = STMF_STATUS_SUCCESS; 54597836SJohn.Forte@Sun.COM break; 54607836SJohn.Forte@Sun.COM case STMF_PS_ERROR_EXISTS: 54617836SJohn.Forte@Sun.COM ret = STMF_ERROR_EXISTS; 54627836SJohn.Forte@Sun.COM break; 54637836SJohn.Forte@Sun.COM case STMF_PS_ERROR_BUSY: 54647836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 54657836SJohn.Forte@Sun.COM break; 54667836SJohn.Forte@Sun.COM case STMF_PS_ERROR_SERVICE_NOT_FOUND: 54677836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_NOT_FOUND; 54687836SJohn.Forte@Sun.COM break; 54697836SJohn.Forte@Sun.COM case STMF_PS_ERROR_VERSION_MISMATCH: 54707836SJohn.Forte@Sun.COM ret = STMF_ERROR_SERVICE_DATA_VERSION; 54717836SJohn.Forte@Sun.COM break; 54727836SJohn.Forte@Sun.COM case STMF_PS_ERROR_PROV_DATA_STALE: 54737836SJohn.Forte@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 54747836SJohn.Forte@Sun.COM break; 54757836SJohn.Forte@Sun.COM default: 54767836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 54777836SJohn.Forte@Sun.COM "stmfSetProviderData" 54787836SJohn.Forte@Sun.COM "psSetProviderData:error(%d)", ret); 54797836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 54807836SJohn.Forte@Sun.COM break; 54817836SJohn.Forte@Sun.COM } 54827836SJohn.Forte@Sun.COM 54837836SJohn.Forte@Sun.COM done: 54847836SJohn.Forte@Sun.COM return (ret); 54857836SJohn.Forte@Sun.COM } 54867836SJohn.Forte@Sun.COM 54877836SJohn.Forte@Sun.COM /* 54889585STim.Szeto@Sun.COM * getProviderData 54899585STim.Szeto@Sun.COM * 54909585STim.Szeto@Sun.COM * Purpose: set the provider data from stmf 54919585STim.Szeto@Sun.COM * 54929585STim.Szeto@Sun.COM * providerName - unique name of provider 54939585STim.Szeto@Sun.COM * nvl - nvlist to load/retrieve 54949585STim.Szeto@Sun.COM * providerType - logical unit or port provider 54959585STim.Szeto@Sun.COM * setToken - returned stale data token 54969585STim.Szeto@Sun.COM */ 54979585STim.Szeto@Sun.COM int 54989585STim.Szeto@Sun.COM getProviderData(char *providerName, nvlist_t **nvl, int providerType, 54999585STim.Szeto@Sun.COM uint64_t *setToken) 55009585STim.Szeto@Sun.COM { 55019585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 55029585STim.Szeto@Sun.COM int fd; 55039585STim.Szeto@Sun.COM int ioctlRet; 55049585STim.Szeto@Sun.COM size_t nvlistSize = ALLOC_PP_DATA_SIZE; 55059585STim.Szeto@Sun.COM int retryCnt = 0; 55069585STim.Szeto@Sun.COM int retryCntMax = MAX_PROVIDER_RETRY; 55079585STim.Szeto@Sun.COM stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL; 55089585STim.Szeto@Sun.COM boolean_t retry = B_TRUE; 55099585STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 55109585STim.Szeto@Sun.COM 55119585STim.Szeto@Sun.COM if (providerName == NULL) { 55129585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 55139585STim.Szeto@Sun.COM } 55149585STim.Szeto@Sun.COM 55159585STim.Szeto@Sun.COM /* 55169585STim.Szeto@Sun.COM * Open control node for stmf 55179585STim.Szeto@Sun.COM */ 55189585STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 55199585STim.Szeto@Sun.COM return (ret); 55209585STim.Szeto@Sun.COM 55219585STim.Szeto@Sun.COM /* set provider name and provider type */ 55229585STim.Szeto@Sun.COM if (strlcpy(ppi.ppi_name, providerName, 55239585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) >= 55249585STim.Szeto@Sun.COM sizeof (ppi.ppi_name)) { 55259585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 55269585STim.Szeto@Sun.COM goto done; 55279585STim.Szeto@Sun.COM } 55289585STim.Szeto@Sun.COM switch (providerType) { 55299585STim.Szeto@Sun.COM case STMF_LU_PROVIDER_TYPE: 55309585STim.Szeto@Sun.COM ppi.ppi_lu_provider = 1; 55319585STim.Szeto@Sun.COM break; 55329585STim.Szeto@Sun.COM case STMF_PORT_PROVIDER_TYPE: 55339585STim.Szeto@Sun.COM ppi.ppi_port_provider = 1; 55349585STim.Szeto@Sun.COM break; 55359585STim.Szeto@Sun.COM default: 55369585STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_ARG; 55379585STim.Szeto@Sun.COM goto done; 55389585STim.Szeto@Sun.COM } 55399585STim.Szeto@Sun.COM 55409585STim.Szeto@Sun.COM do { 55419585STim.Szeto@Sun.COM /* allocate memory for ioctl */ 55429585STim.Szeto@Sun.COM ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize + 55439585STim.Szeto@Sun.COM sizeof (stmf_ppioctl_data_t)); 55449585STim.Szeto@Sun.COM if (ppi_out == NULL) { 55459585STim.Szeto@Sun.COM ret = STMF_ERROR_NOMEM; 55469585STim.Szeto@Sun.COM goto done; 55479585STim.Szeto@Sun.COM 55489585STim.Szeto@Sun.COM } 55499585STim.Szeto@Sun.COM 55509585STim.Szeto@Sun.COM /* set the size of the ioctl data to allocated buffer */ 55519585STim.Szeto@Sun.COM ppi.ppi_data_size = nvlistSize; 55529585STim.Szeto@Sun.COM 55539585STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 55549585STim.Szeto@Sun.COM 55559585STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 55569585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t); 55579585STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi; 55589585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) + 55599585STim.Szeto@Sun.COM nvlistSize; 55609585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out; 55619585STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl); 55629585STim.Szeto@Sun.COM if (ioctlRet != 0) { 55639585STim.Szeto@Sun.COM switch (errno) { 55649585STim.Szeto@Sun.COM case EBUSY: 55659585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 55669585STim.Szeto@Sun.COM break; 55679585STim.Szeto@Sun.COM case EPERM: 55689585STim.Szeto@Sun.COM case EACCES: 55699585STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 55709585STim.Szeto@Sun.COM break; 55719585STim.Szeto@Sun.COM case EINVAL: 55729585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 55739585STim.Szeto@Sun.COM STMF_IOCERR_INSUFFICIENT_BUF) { 55749585STim.Szeto@Sun.COM nvlistSize = 55759585STim.Szeto@Sun.COM ppi_out->ppi_data_size; 55769585STim.Szeto@Sun.COM free(ppi_out); 55779585STim.Szeto@Sun.COM ppi_out = NULL; 55789585STim.Szeto@Sun.COM if (retryCnt++ > retryCntMax) { 55799585STim.Szeto@Sun.COM retry = B_FALSE; 55809585STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 55819585STim.Szeto@Sun.COM } else { 55829585STim.Szeto@Sun.COM ret = 55839585STim.Szeto@Sun.COM STMF_STATUS_SUCCESS; 55849585STim.Szeto@Sun.COM } 55859585STim.Szeto@Sun.COM } else { 55869585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 55879585STim.Szeto@Sun.COM "getProviderData:ioctl" 55889585STim.Szeto@Sun.COM "unable to retrieve " 55899585STim.Szeto@Sun.COM "nvlist"); 55909585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 55919585STim.Szeto@Sun.COM } 55929585STim.Szeto@Sun.COM break; 55939585STim.Szeto@Sun.COM case ENOENT: 55949585STim.Szeto@Sun.COM ret = STMF_ERROR_NOT_FOUND; 55959585STim.Szeto@Sun.COM break; 55969585STim.Szeto@Sun.COM default: 55979585STim.Szeto@Sun.COM syslog(LOG_DEBUG, 55989585STim.Szeto@Sun.COM "getProviderData:ioctl errno(%d)", 55999585STim.Szeto@Sun.COM errno); 56009585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 56019585STim.Szeto@Sun.COM break; 56029585STim.Szeto@Sun.COM } 56039585STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) 56049585STim.Szeto@Sun.COM goto done; 56059585STim.Szeto@Sun.COM } 56069585STim.Szeto@Sun.COM } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF); 56079585STim.Szeto@Sun.COM 56089585STim.Szeto@Sun.COM if ((ret = nvlist_unpack((char *)ppi_out->ppi_data, 56099585STim.Szeto@Sun.COM ppi_out->ppi_data_size, nvl, 0)) != 0) { 56109585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 56119585STim.Szeto@Sun.COM goto done; 56129585STim.Szeto@Sun.COM } 56139585STim.Szeto@Sun.COM 56149585STim.Szeto@Sun.COM /* caller has asked for new token */ 56159585STim.Szeto@Sun.COM if (setToken) { 56169585STim.Szeto@Sun.COM *setToken = ppi_out->ppi_token; 56179585STim.Szeto@Sun.COM } 56189585STim.Szeto@Sun.COM done: 56199585STim.Szeto@Sun.COM free(ppi_out); 56209585STim.Szeto@Sun.COM (void) close(fd); 56219585STim.Szeto@Sun.COM return (ret); 56229585STim.Szeto@Sun.COM } 56239585STim.Szeto@Sun.COM 56249585STim.Szeto@Sun.COM /* 56257836SJohn.Forte@Sun.COM * setProviderData 56267836SJohn.Forte@Sun.COM * 56279585STim.Szeto@Sun.COM * Purpose: set the provider data in stmf 56287836SJohn.Forte@Sun.COM * 56297836SJohn.Forte@Sun.COM * providerName - unique name of provider 56307836SJohn.Forte@Sun.COM * nvl - nvlist to set 56317836SJohn.Forte@Sun.COM * providerType - logical unit or port provider 56329585STim.Szeto@Sun.COM * setToken - stale data token to check if not NULL 56337836SJohn.Forte@Sun.COM */ 56347836SJohn.Forte@Sun.COM static int 56359585STim.Szeto@Sun.COM setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType, 56369585STim.Szeto@Sun.COM uint64_t *setToken) 56377836SJohn.Forte@Sun.COM { 56387836SJohn.Forte@Sun.COM int ret = STMF_STATUS_SUCCESS; 56397836SJohn.Forte@Sun.COM int ioctlRet; 56407836SJohn.Forte@Sun.COM size_t nvlistEncodedSize; 56417836SJohn.Forte@Sun.COM stmf_ppioctl_data_t *ppi = NULL; 56429585STim.Szeto@Sun.COM uint64_t outToken; 56437836SJohn.Forte@Sun.COM char *allocatedNvBuffer; 56447836SJohn.Forte@Sun.COM stmf_iocdata_t stmfIoctl; 56457836SJohn.Forte@Sun.COM 56467836SJohn.Forte@Sun.COM if (providerName == NULL) { 56477836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56487836SJohn.Forte@Sun.COM } 56497836SJohn.Forte@Sun.COM 56507836SJohn.Forte@Sun.COM /* get size of encoded nvlist */ 56517836SJohn.Forte@Sun.COM if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) { 56527836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 56537836SJohn.Forte@Sun.COM } 56547836SJohn.Forte@Sun.COM 56557836SJohn.Forte@Sun.COM /* allocate memory for ioctl */ 56567836SJohn.Forte@Sun.COM ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize + 56577836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t)); 56587836SJohn.Forte@Sun.COM if (ppi == NULL) { 56597836SJohn.Forte@Sun.COM return (STMF_ERROR_NOMEM); 56607836SJohn.Forte@Sun.COM } 56617836SJohn.Forte@Sun.COM 56629585STim.Szeto@Sun.COM if (setToken) { 56639585STim.Szeto@Sun.COM ppi->ppi_token_valid = 1; 56649585STim.Szeto@Sun.COM ppi->ppi_token = *setToken; 56659585STim.Szeto@Sun.COM } 56669585STim.Szeto@Sun.COM 56677836SJohn.Forte@Sun.COM allocatedNvBuffer = (char *)&ppi->ppi_data; 56687836SJohn.Forte@Sun.COM if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize, 56697836SJohn.Forte@Sun.COM NV_ENCODE_XDR, 0) != 0) { 56707836SJohn.Forte@Sun.COM return (STMF_STATUS_ERROR); 56717836SJohn.Forte@Sun.COM } 56727836SJohn.Forte@Sun.COM 56737836SJohn.Forte@Sun.COM /* set provider name and provider type */ 56747836SJohn.Forte@Sun.COM (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name)); 56757836SJohn.Forte@Sun.COM switch (providerType) { 56767836SJohn.Forte@Sun.COM case STMF_LU_PROVIDER_TYPE: 56777836SJohn.Forte@Sun.COM ppi->ppi_lu_provider = 1; 56787836SJohn.Forte@Sun.COM break; 56797836SJohn.Forte@Sun.COM case STMF_PORT_PROVIDER_TYPE: 56807836SJohn.Forte@Sun.COM ppi->ppi_port_provider = 1; 56817836SJohn.Forte@Sun.COM break; 56827836SJohn.Forte@Sun.COM default: 56837836SJohn.Forte@Sun.COM return (STMF_ERROR_INVALID_ARG); 56847836SJohn.Forte@Sun.COM } 56857836SJohn.Forte@Sun.COM 56867836SJohn.Forte@Sun.COM /* set the size of the ioctl data to packed data size */ 56877836SJohn.Forte@Sun.COM ppi->ppi_data_size = nvlistEncodedSize; 56887836SJohn.Forte@Sun.COM 56897836SJohn.Forte@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 56907836SJohn.Forte@Sun.COM 56917836SJohn.Forte@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 56927836SJohn.Forte@Sun.COM /* 56937836SJohn.Forte@Sun.COM * Subtracting 8 from the size as that is the size of the last member 56947836SJohn.Forte@Sun.COM * of the structure where the packed data resides 56957836SJohn.Forte@Sun.COM */ 56967836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf_size = nvlistEncodedSize + 56977836SJohn.Forte@Sun.COM sizeof (stmf_ppioctl_data_t) - 8; 56987836SJohn.Forte@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi; 56999585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (uint64_t); 57009585STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken; 57017836SJohn.Forte@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl); 57027836SJohn.Forte@Sun.COM if (ioctlRet != 0) { 57037836SJohn.Forte@Sun.COM switch (errno) { 57047836SJohn.Forte@Sun.COM case EBUSY: 57057836SJohn.Forte@Sun.COM ret = STMF_ERROR_BUSY; 57067836SJohn.Forte@Sun.COM break; 57079585STim.Szeto@Sun.COM case EPERM: 57087836SJohn.Forte@Sun.COM case EACCES: 57097836SJohn.Forte@Sun.COM ret = STMF_ERROR_PERM; 57107836SJohn.Forte@Sun.COM break; 57119585STim.Szeto@Sun.COM case EINVAL: 57129585STim.Szeto@Sun.COM if (stmfIoctl.stmf_error == 57139585STim.Szeto@Sun.COM STMF_IOCERR_PPD_UPDATED) { 57149585STim.Szeto@Sun.COM ret = STMF_ERROR_PROV_DATA_STALE; 57159585STim.Szeto@Sun.COM } else { 57169585STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 57179585STim.Szeto@Sun.COM } 57189585STim.Szeto@Sun.COM break; 57197836SJohn.Forte@Sun.COM default: 57207836SJohn.Forte@Sun.COM syslog(LOG_DEBUG, 57217836SJohn.Forte@Sun.COM "setProviderData:ioctl errno(%d)", errno); 57227836SJohn.Forte@Sun.COM ret = STMF_STATUS_ERROR; 57237836SJohn.Forte@Sun.COM break; 57247836SJohn.Forte@Sun.COM } 57257836SJohn.Forte@Sun.COM if (ret != STMF_STATUS_SUCCESS) 57267836SJohn.Forte@Sun.COM goto done; 57277836SJohn.Forte@Sun.COM } 57287836SJohn.Forte@Sun.COM 57299585STim.Szeto@Sun.COM /* caller has asked for new token */ 57309585STim.Szeto@Sun.COM if (setToken) { 57319585STim.Szeto@Sun.COM *setToken = outToken; 57329585STim.Szeto@Sun.COM } 57337836SJohn.Forte@Sun.COM done: 57347836SJohn.Forte@Sun.COM free(ppi); 57357836SJohn.Forte@Sun.COM return (ret); 57367836SJohn.Forte@Sun.COM } 57379585STim.Szeto@Sun.COM 57389585STim.Szeto@Sun.COM /* 57399585STim.Szeto@Sun.COM * set the persistence method in the library only or library and service 57409585STim.Szeto@Sun.COM */ 57419585STim.Szeto@Sun.COM int 57429585STim.Szeto@Sun.COM stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet) 57439585STim.Szeto@Sun.COM { 57449585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 57459585STim.Szeto@Sun.COM int oldPersist; 57469585STim.Szeto@Sun.COM 57479585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 57489585STim.Szeto@Sun.COM oldPersist = iPersistType; 57499585STim.Szeto@Sun.COM if (persistType == STMF_PERSIST_NONE || 57509585STim.Szeto@Sun.COM persistType == STMF_PERSIST_SMF) { 57519585STim.Szeto@Sun.COM iLibSetPersist = B_TRUE; 57529585STim.Szeto@Sun.COM iPersistType = persistType; 57539585STim.Szeto@Sun.COM } else { 57549585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 57559585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 57569585STim.Szeto@Sun.COM } 57579585STim.Szeto@Sun.COM /* Is this for this library open or in SMF */ 57589585STim.Szeto@Sun.COM if (serviceSet == B_TRUE) { 57599585STim.Szeto@Sun.COM ret = psSetServicePersist(persistType); 57609585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 57619585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 57629585STim.Szeto@Sun.COM /* Set to old value */ 57639585STim.Szeto@Sun.COM iPersistType = oldPersist; 57649585STim.Szeto@Sun.COM } 57659585STim.Szeto@Sun.COM } 57669585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 57679585STim.Szeto@Sun.COM 57689585STim.Szeto@Sun.COM return (ret); 57699585STim.Szeto@Sun.COM } 57709585STim.Szeto@Sun.COM 57719585STim.Szeto@Sun.COM /* 57729585STim.Szeto@Sun.COM * Only returns internal state for persist. If unset, goes to ps. If that 57739585STim.Szeto@Sun.COM * fails, returns default setting 57749585STim.Szeto@Sun.COM */ 57759585STim.Szeto@Sun.COM static uint8_t 57769585STim.Szeto@Sun.COM iGetPersistMethod() 57779585STim.Szeto@Sun.COM { 57789585STim.Szeto@Sun.COM 57799585STim.Szeto@Sun.COM uint8_t persistType = 0; 57809585STim.Szeto@Sun.COM 57819585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 57829585STim.Szeto@Sun.COM if (iLibSetPersist) { 57839585STim.Szeto@Sun.COM persistType = iPersistType; 57849585STim.Szeto@Sun.COM } else { 57859585STim.Szeto@Sun.COM int ret; 57869585STim.Szeto@Sun.COM ret = psGetServicePersist(&persistType); 57879585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 57889585STim.Szeto@Sun.COM /* set to default */ 57899585STim.Szeto@Sun.COM persistType = STMF_DEFAULT_PERSIST; 57909585STim.Szeto@Sun.COM } 57919585STim.Szeto@Sun.COM } 57929585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 57939585STim.Szeto@Sun.COM return (persistType); 57949585STim.Szeto@Sun.COM } 57959585STim.Szeto@Sun.COM 57969585STim.Szeto@Sun.COM /* 57979585STim.Szeto@Sun.COM * Returns either library state or persistent config state depending on 57989585STim.Szeto@Sun.COM * serviceState 57999585STim.Szeto@Sun.COM */ 58009585STim.Szeto@Sun.COM int 58019585STim.Szeto@Sun.COM stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState) 58029585STim.Szeto@Sun.COM { 58039585STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 58049585STim.Szeto@Sun.COM 58059585STim.Szeto@Sun.COM if (persistType == NULL) { 58069585STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 58079585STim.Szeto@Sun.COM } 58089585STim.Szeto@Sun.COM if (serviceState) { 58099585STim.Szeto@Sun.COM ret = psGetServicePersist(persistType); 58109585STim.Szeto@Sun.COM if (ret != STMF_PS_SUCCESS) { 58119585STim.Szeto@Sun.COM ret = STMF_ERROR_PERSIST_TYPE; 58129585STim.Szeto@Sun.COM } 58139585STim.Szeto@Sun.COM } else { 58149585STim.Szeto@Sun.COM (void) pthread_mutex_lock(&persistenceTypeLock); 58159585STim.Szeto@Sun.COM if (iLibSetPersist) { 58169585STim.Szeto@Sun.COM *persistType = iPersistType; 58179585STim.Szeto@Sun.COM } else { 58189585STim.Szeto@Sun.COM *persistType = STMF_DEFAULT_PERSIST; 58199585STim.Szeto@Sun.COM } 58209585STim.Szeto@Sun.COM (void) pthread_mutex_unlock(&persistenceTypeLock); 58219585STim.Szeto@Sun.COM } 58229585STim.Szeto@Sun.COM 58239585STim.Szeto@Sun.COM return (ret); 58249585STim.Szeto@Sun.COM } 5825*10691STim.Szeto@Sun.COM 5826*10691STim.Szeto@Sun.COM /* 5827*10691STim.Szeto@Sun.COM * validateLunNumIoctl 5828*10691STim.Szeto@Sun.COM * 5829*10691STim.Szeto@Sun.COM * Purpose: Issues ioctl to check and get available lun# in view entry 5830*10691STim.Szeto@Sun.COM * 5831*10691STim.Szeto@Sun.COM * viewEntry - view entry to use 5832*10691STim.Szeto@Sun.COM */ 5833*10691STim.Szeto@Sun.COM static int 5834*10691STim.Szeto@Sun.COM validateLunNumIoctl(int fd, stmfViewEntry *viewEntry) 5835*10691STim.Szeto@Sun.COM { 5836*10691STim.Szeto@Sun.COM int ret = STMF_STATUS_SUCCESS; 5837*10691STim.Szeto@Sun.COM int ioctlRet; 5838*10691STim.Szeto@Sun.COM stmf_iocdata_t stmfIoctl; 5839*10691STim.Szeto@Sun.COM stmf_view_op_entry_t ioctlViewEntry; 5840*10691STim.Szeto@Sun.COM 5841*10691STim.Szeto@Sun.COM bzero(&ioctlViewEntry, sizeof (ioctlViewEntry)); 5842*10691STim.Szeto@Sun.COM /* 5843*10691STim.Szeto@Sun.COM * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be 5844*10691STim.Szeto@Sun.COM * false on input 5845*10691STim.Szeto@Sun.COM */ 5846*10691STim.Szeto@Sun.COM ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid; 5847*10691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_hosts = viewEntry->allHosts; 5848*10691STim.Szeto@Sun.COM ioctlViewEntry.ve_all_targets = viewEntry->allTargets; 5849*10691STim.Szeto@Sun.COM 5850*10691STim.Szeto@Sun.COM if (viewEntry->allHosts == B_FALSE) { 5851*10691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name, 5852*10691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 5853*10691STim.Szeto@Sun.COM ioctlViewEntry.ve_host_group.name_size = 5854*10691STim.Szeto@Sun.COM strlen((char *)viewEntry->hostGroup); 5855*10691STim.Szeto@Sun.COM } 5856*10691STim.Szeto@Sun.COM if (viewEntry->allTargets == B_FALSE) { 5857*10691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, 5858*10691STim.Szeto@Sun.COM &ioctlViewEntry.ve_target_group.name, 5859*10691STim.Szeto@Sun.COM sizeof (stmfGroupName)); 5860*10691STim.Szeto@Sun.COM ioctlViewEntry.ve_target_group.name_size = 5861*10691STim.Szeto@Sun.COM strlen((char *)viewEntry->targetGroup); 5862*10691STim.Szeto@Sun.COM } 5863*10691STim.Szeto@Sun.COM /* Validating the lun number */ 5864*10691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 5865*10691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr, 5866*10691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 5867*10691STim.Szeto@Sun.COM } 5868*10691STim.Szeto@Sun.COM 5869*10691STim.Szeto@Sun.COM bzero(&stmfIoctl, sizeof (stmfIoctl)); 5870*10691STim.Szeto@Sun.COM /* 5871*10691STim.Szeto@Sun.COM * Issue ioctl to validate lun# in the view entry 5872*10691STim.Szeto@Sun.COM */ 5873*10691STim.Szeto@Sun.COM stmfIoctl.stmf_version = STMF_VERSION_1; 5874*10691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry); 5875*10691STim.Szeto@Sun.COM stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry; 5876*10691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry); 5877*10691STim.Szeto@Sun.COM stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry; 5878*10691STim.Szeto@Sun.COM ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl); 5879*10691STim.Szeto@Sun.COM 5880*10691STim.Szeto@Sun.COM /* save available lun number */ 5881*10691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 5882*10691STim.Szeto@Sun.COM bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr, 5883*10691STim.Szeto@Sun.COM sizeof (ioctlViewEntry.ve_lu_nbr)); 5884*10691STim.Szeto@Sun.COM } 5885*10691STim.Szeto@Sun.COM if (ioctlRet != 0) { 5886*10691STim.Szeto@Sun.COM switch (errno) { 5887*10691STim.Szeto@Sun.COM case EBUSY: 5888*10691STim.Szeto@Sun.COM ret = STMF_ERROR_BUSY; 5889*10691STim.Szeto@Sun.COM break; 5890*10691STim.Szeto@Sun.COM case EPERM: 5891*10691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 5892*10691STim.Szeto@Sun.COM break; 5893*10691STim.Szeto@Sun.COM case EACCES: 5894*10691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 5895*10691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 5896*10691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 5897*10691STim.Szeto@Sun.COM break; 5898*10691STim.Szeto@Sun.COM default: 5899*10691STim.Szeto@Sun.COM ret = STMF_ERROR_PERM; 5900*10691STim.Szeto@Sun.COM break; 5901*10691STim.Szeto@Sun.COM } 5902*10691STim.Szeto@Sun.COM break; 5903*10691STim.Szeto@Sun.COM default: 5904*10691STim.Szeto@Sun.COM switch (stmfIoctl.stmf_error) { 5905*10691STim.Szeto@Sun.COM case STMF_IOCERR_LU_NUMBER_IN_USE: 5906*10691STim.Szeto@Sun.COM ret = STMF_ERROR_LUN_IN_USE; 5907*10691STim.Szeto@Sun.COM break; 5908*10691STim.Szeto@Sun.COM case STMF_IOCERR_VIEW_ENTRY_CONFLICT: 5909*10691STim.Szeto@Sun.COM ret = STMF_ERROR_VE_CONFLICT; 5910*10691STim.Szeto@Sun.COM break; 5911*10691STim.Szeto@Sun.COM case STMF_IOCERR_UPDATE_NEED_CFG_INIT: 5912*10691STim.Szeto@Sun.COM ret = STMF_ERROR_CONFIG_NONE; 5913*10691STim.Szeto@Sun.COM break; 5914*10691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_HG: 5915*10691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_HG; 5916*10691STim.Szeto@Sun.COM break; 5917*10691STim.Szeto@Sun.COM case STMF_IOCERR_INVALID_TG: 5918*10691STim.Szeto@Sun.COM ret = STMF_ERROR_INVALID_TG; 5919*10691STim.Szeto@Sun.COM break; 5920*10691STim.Szeto@Sun.COM default: 5921*10691STim.Szeto@Sun.COM syslog(LOG_DEBUG, 5922*10691STim.Szeto@Sun.COM "addViewEntryIoctl" 5923*10691STim.Szeto@Sun.COM ":error(%d)", 5924*10691STim.Szeto@Sun.COM stmfIoctl.stmf_error); 5925*10691STim.Szeto@Sun.COM ret = STMF_STATUS_ERROR; 5926*10691STim.Szeto@Sun.COM break; 5927*10691STim.Szeto@Sun.COM } 5928*10691STim.Szeto@Sun.COM break; 5929*10691STim.Szeto@Sun.COM } 5930*10691STim.Szeto@Sun.COM } 5931*10691STim.Szeto@Sun.COM return (ret); 5932*10691STim.Szeto@Sun.COM } 5933*10691STim.Szeto@Sun.COM 5934*10691STim.Szeto@Sun.COM /* 5935*10691STim.Szeto@Sun.COM * stmfValidateView 5936*10691STim.Szeto@Sun.COM * 5937*10691STim.Szeto@Sun.COM * Purpose: Validate or get lun # base on TG, HG of view entry 5938*10691STim.Szeto@Sun.COM * 5939*10691STim.Szeto@Sun.COM * viewEntry - view entry structure to use 5940*10691STim.Szeto@Sun.COM */ 5941*10691STim.Szeto@Sun.COM int 5942*10691STim.Szeto@Sun.COM stmfValidateView(stmfViewEntry *viewEntry) 5943*10691STim.Szeto@Sun.COM { 5944*10691STim.Szeto@Sun.COM int ret; 5945*10691STim.Szeto@Sun.COM int fd; 5946*10691STim.Szeto@Sun.COM stmfViewEntry iViewEntry; 5947*10691STim.Szeto@Sun.COM 5948*10691STim.Szeto@Sun.COM if (viewEntry == NULL) { 5949*10691STim.Szeto@Sun.COM return (STMF_ERROR_INVALID_ARG); 5950*10691STim.Szeto@Sun.COM } 5951*10691STim.Szeto@Sun.COM 5952*10691STim.Szeto@Sun.COM /* initialize and set internal view entry */ 5953*10691STim.Szeto@Sun.COM bzero(&iViewEntry, sizeof (iViewEntry)); 5954*10691STim.Szeto@Sun.COM 5955*10691STim.Szeto@Sun.COM if (!viewEntry->allHosts) { 5956*10691STim.Szeto@Sun.COM bcopy(viewEntry->hostGroup, iViewEntry.hostGroup, 5957*10691STim.Szeto@Sun.COM sizeof (iViewEntry.hostGroup)); 5958*10691STim.Szeto@Sun.COM } else { 5959*10691STim.Szeto@Sun.COM iViewEntry.allHosts = B_TRUE; 5960*10691STim.Szeto@Sun.COM } 5961*10691STim.Szeto@Sun.COM 5962*10691STim.Szeto@Sun.COM if (!viewEntry->allTargets) { 5963*10691STim.Szeto@Sun.COM bcopy(viewEntry->targetGroup, iViewEntry.targetGroup, 5964*10691STim.Szeto@Sun.COM sizeof (iViewEntry.targetGroup)); 5965*10691STim.Szeto@Sun.COM } else { 5966*10691STim.Szeto@Sun.COM iViewEntry.allTargets = B_TRUE; 5967*10691STim.Szeto@Sun.COM } 5968*10691STim.Szeto@Sun.COM 5969*10691STim.Szeto@Sun.COM if (viewEntry->luNbrValid) { 5970*10691STim.Szeto@Sun.COM iViewEntry.luNbrValid = B_TRUE; 5971*10691STim.Szeto@Sun.COM bcopy(viewEntry->luNbr, iViewEntry.luNbr, 5972*10691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 5973*10691STim.Szeto@Sun.COM } 5974*10691STim.Szeto@Sun.COM 5975*10691STim.Szeto@Sun.COM /* 5976*10691STim.Szeto@Sun.COM * set users return view entry index valid flag to false 5977*10691STim.Szeto@Sun.COM * in case of failure 5978*10691STim.Szeto@Sun.COM */ 5979*10691STim.Szeto@Sun.COM viewEntry->veIndexValid = B_FALSE; 5980*10691STim.Szeto@Sun.COM 5981*10691STim.Szeto@Sun.COM /* Check to ensure service exists */ 5982*10691STim.Szeto@Sun.COM if (psCheckService() != STMF_STATUS_SUCCESS) { 5983*10691STim.Szeto@Sun.COM return (STMF_ERROR_SERVICE_NOT_FOUND); 5984*10691STim.Szeto@Sun.COM } 5985*10691STim.Szeto@Sun.COM 5986*10691STim.Szeto@Sun.COM /* call init */ 5987*10691STim.Szeto@Sun.COM ret = initializeConfig(); 5988*10691STim.Szeto@Sun.COM if (ret != STMF_STATUS_SUCCESS) { 5989*10691STim.Szeto@Sun.COM return (ret); 5990*10691STim.Szeto@Sun.COM } 5991*10691STim.Szeto@Sun.COM 5992*10691STim.Szeto@Sun.COM /* 5993*10691STim.Szeto@Sun.COM * Open control node for stmf 5994*10691STim.Szeto@Sun.COM */ 5995*10691STim.Szeto@Sun.COM if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS) 5996*10691STim.Szeto@Sun.COM return (ret); 5997*10691STim.Szeto@Sun.COM 5998*10691STim.Szeto@Sun.COM /* 5999*10691STim.Szeto@Sun.COM * Validate lun# in the view entry from the driver 6000*10691STim.Szeto@Sun.COM */ 6001*10691STim.Szeto@Sun.COM ret = validateLunNumIoctl(fd, &iViewEntry); 6002*10691STim.Szeto@Sun.COM (void) close(fd); 6003*10691STim.Szeto@Sun.COM 6004*10691STim.Szeto@Sun.COM /* save available lun number */ 6005*10691STim.Szeto@Sun.COM if (!viewEntry->luNbrValid) { 6006*10691STim.Szeto@Sun.COM bcopy(iViewEntry.luNbr, viewEntry->luNbr, 6007*10691STim.Szeto@Sun.COM sizeof (iViewEntry.luNbr)); 6008*10691STim.Szeto@Sun.COM } 6009*10691STim.Szeto@Sun.COM 6010*10691STim.Szeto@Sun.COM return (ret); 6011*10691STim.Szeto@Sun.COM } 6012